2012-05-11 12 views
16

3つの列にあるセルの値を検索して、あるワークシートの行を別のワークシートにコピーするVBAマクロがあります。マクロは機能しますが、行32767に達したときにクラッシュします。この行には数式や特殊な書式はありません。さらに、私はその行を取り出しましたが、それでもその行番号でクラッシュします。これはExcelの制限ですか?プロセス32000行後にVBAマクロがクラッシュする

されているワークシートの一部の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." 

助けてください!

+2

IIRC VBAの整数型は16ビット幅です。 「ロング」はありますか?私は忘れる。 – cHao

+0

ルックアップヘルプで整数を変更してからロングに変更してください –

+0

ありがとうございました - データ型をlongに変更するだけでした。 – Andy5

答えて

31

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

+0

Integer変数(32767を超える行)の行数を使用する1つのマクロが、32676の後に崩れない、別のマクロが壊れているときの状況を、どのように説明しますか? – parsecer

4

これは整数問題

整数との両方が正または負 値を保持することができる長いデータ型のように聞こえます。それらの違いはサイズです。整数変数 は、-32,768と32,767の間の値を保持できますが、ロング変数は の範囲は-2,147,483,648〜2,147,483,647です。

どちらのバージョンをお使いですか?ので:彼らはより少ないメモリを必要と ので

伝統的に、VBA プログラマは、小さな数値を保持するために、整数を使用しています。ただし、最近のバージョンでは、VBAは 整数として宣言されていても、すべて 整数値をLong型に変換します。したがって、Integer変数を使用した場合、もはやパフォーマンス上の利点はありません( )。実際には、VBAはそれらを変換する必要がないため、Long変数はわずかに になる可能性があります。

この情報はMSDN

UPDATE

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

Thats MSDNは誤解を招く:VBA自体が整数を に変換しません。カバーの下でCPUは​​整数をlongに変換し、 の算術演算を行い、その結果のlongを整数に変換します。あなたはそれぞれのために使用するのではなく、行をインクリメントすることにより、整数対ロング問題を回避することができますCharles Williams

+7

それは誤解を招くMSDN:VBA自体はIntegerをLongに変換しません。カバーの下で、CPUはintegerをlongに変換し、算術演算を行い、その結果得られたlongを整数に変換します。だから、VBAの整数はまだ32Kより大きい数値を保持することができません –

+0

この情報をありがとう!それは知らなかった。私のポストを更新します! – Neysor

2

- だから、 VBAの整数はまだ32Kよりも数値が大きく保持することはできません。なぜなら、選択範囲を避けるのと同様に、それぞれが一般的にはより速いからです。次に例を示します:

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 
+0

「For Each」の実行中にコレクションを操作しています - *いたずら* ... –

+0

かなり正しいです。一定。ありがとうマーカス。 –