17

3列のセルの値の検索に基づいて、あるワークシートから別のワークシートに行をコピーするVBAマクロがあります。マクロは機能しますが、行32767に達するとクラッシュします。この行には数式や特別な書式設定はありません。さらに、その行を取り出しましたが、それでもその行番号でクラッシュします。これはExcelの制限ですか?処理中のワークシートには約43000があります

したがって、マクロの何が問題になっているのか、そしてどのようにしてマクロをワークシートの最後に到達させることができるのかを尋ねます。

Dim LSearchRow As Integer
Dim LCopyToRow As Integer
Dim wks As Worksheet
On Error GoTo Err_Execute

ワークシートの各週について

LSearchRow = 4
LCopyToRow = 4

ThisWorkbook.Worksheets.Add After:=Worksheets(Worksheets.Count)
Set wksCopyTo = ActiveSheet
wks.Rows(3).EntireRow.Copy wksCopyTo.Rows(3)

While Len(wks.Range("A" & CStr(LSearchRow)).Value) > 0

    If wks.Range("AB" & CStr(LSearchRow)).Value = "Yes" And wks.Range("AK" & CStr(LSearchRow)).Value = "Yes" And wks.Range("BB" & CStr(LSearchRow)).Value = "Y" Then

        Rows(CStr(LSearchRow) & ":" & CStr(LSearchRow)).Select
        Selection.Copy


        wksCopyTo.Select
        wksCopyTo.Rows(CStr(LCopyToRow) & ":" & CStr(LCopyToRow)).Select
        wksCopyTo.Paste

        'Move counter to next row
        LCopyToRow = LCopyToRow + 1
        'Go back to Sheet1 to continue searching
        wks.Select
    End If
    LSearchRow = LSearchRow + 1
Wend

Application.CutCopyMode = False
Range("A3").Select
MsgBox "All matching data has been copied."
Next wks
    Exit Sub
Err_Execute:
    MsgBox "An error occurred."

助けてください!

4

3 に答える 3

36

VBAの「Int」タイプは符号付き16ビットフィールドであるため、-32768〜+32767の値のみを保持できます。これらの変数を「Long」に変更します。これは、符号付き32ビットフィールドであり、-2147483648から+2147483647までの値を保持できます。Excelには十分なはずです。;)

于 2012-05-11T21:07:58.057 に答える
6

これは整数の問題のように聞こえます

Integerデータ型とLongデータ型は、どちらも正または負の値を保持できます。それらの違いはサイズです。整数変数は-32,768〜32,767の値を保持できますがロング変数は-2,147,483,648〜2,147,483,647の範囲になります。

しかし、どのバージョンを使用していますか?なぜなら:

従来、VBAプログラマーは、必要なメモリが少ないため、整数を使用して小さな数値を保持していました。ただし、最近のバージョンでは、整数型として宣言されている場合でも、VBAはすべての整数値をLong型に変換します。したがって、整数変数を使用することによるパフォーマンス上の利点はなくなりました。実際、Long変数は、VBAが変換する必要がないため、わずかに高速になる可能性があります。

この情報はMSDNから直接提供されています

アップデート

最初のコメントも読んでください!私はMSDN情報を間違った方法で解釈していました!

それはMSDNが誤解を招くものです:VBA自体は整数を長整数に変換しません。カバーの下で、CPUは整数をlongに変換し、算術演算を実行してから、結果のlongを整数に変換し直します。したがって、VBA整数は32Kを超える数値を保持できません– Charles Williams

于 2012-05-11T21:28:22.330 に答える
2

行をインクリメントするのではなく、For Eachを使用することで、整数と長の問題を回避できます。For Eachは、範囲の選択を回避するのと同様に、一般的に高速です。次に例を示します。

Sub CopySheets()

    Dim shSource As Worksheet
    Dim shDest As Worksheet
    Dim rCell As Range
    Dim aSheets() As Worksheet
    Dim lShtCnt As Long
    Dim i As Long

    Const sDESTPREFIX As String = "dest_"

    On Error GoTo Err_Execute

    For Each shSource In ThisWorkbook.Worksheets
        lShtCnt = lShtCnt + 1
        ReDim Preserve aSheets(1 To lShtCnt)
        Set aSheets(lShtCnt) = shSource
    Next shSource

    For i = LBound(aSheets) To UBound(aSheets)
        Set shSource = aSheets(i)

        'Add a new sheet
        With ThisWorkbook
            Set shDest = .Worksheets.Add(, .Worksheets(.Worksheets.Count))
            shDest.Name = sDESTPREFIX & shSource.Name
        End With

        'copy header row
        shSource.Rows(3).Copy shDest.Rows(3)

        'loop through the cells in column a
        For Each rCell In shSource.Range("A4", shSource.Cells(shSource.Rows.Count, 1).End(xlUp)).Cells
            If Not IsEmpty(rCell.Value) And _
                rCell.Offset(0, 27).Value = "Yes" And _
                rCell.Offset(0, 36).Value = "Yes" And _
                rCell.Offset(0, 53).Value = "Yes" Then

                'copy the row
                rCell.EntireRow.Copy shDest.Range(rCell.Address).EntireRow
            End If
        Next rCell
    Next i

    MsgBox "All matching data has been copied."

Err_Exit:
    'do this stuff even if an error occurs
    On Error Resume Next
    Application.CutCopyMode = False
    Exit Sub

Err_Execute:
    MsgBox "An error occurred."
    Resume Err_Exit

End Sub
于 2012-05-12T16:06:05.903 に答える