excel VBA宏在32000行后崩溃

xxe27gdn  于 2023-01-10  发布在  其他
关注(0)|答案(3)|浏览(236)

我有一个VBA宏,它可以根据在3列单元格中找到的值将行从一个工作表复制到另一个工作表。宏可以工作,但在到达第32767行时崩溃。此行中没有公式或特殊格式。此外,我已将该行删除。但是它仍然在那个行号上崩溃。这是Excel中的限制吗?正在处理的工作表中大约有43000个。
因此,我问我的宏出了什么问题,以及如何使它到达工作表的末尾:

Dim LSearchRow As Integer
Dim LCopyToRow As Integer
Dim wks As Worksheet
On Error GoTo Err_Execute
   
 
For Each wks In Worksheets

    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."
mv1qrgav

mv1qrgav1#

VBA“Int”类型是有符号的16位字段,因此它只能保存-32768到+32767之间的值。请将这些变量更改为“Long”,它是有符号的32位字段,可以保存-2147483648到+2147483647之间的值。对于Excel应该足够了。)

kuhbmx9i

kuhbmx9i2#

这听起来像一个整数问题

    • Integer和Long数据类型都可以保存正值或负值。它们之间的区别在于它们的大小:整型变量可以保存-32,768到32,767**之间的值,而长整型变量的范围可以从-2,147,483,648到2,147,483,647。

但是您使用的是哪个版本?因为:
传统上,VBA程序员使用整数来保存较小的数字,因为它们需要的内存较少。但是,在最近的版本中,**VBA将所有整数值转换为Long类型,即使它们声明为Integer类型。**因此,使用Integer变量不再具有性能优势;事实上,长变量可能会稍微快一些,因为VBA不必转换它们。
此信息直接来自MSDN

    • 更新**

也请阅读第一个评论!我是解释MSDN信息的错误方式!
这是MSDN的误导:VBA本身并不将整数转换为长整型。在其背后,CPU将整数转换为长整型,执行算术运算,然后将结果长整型转换回整数。因此VBA整数仍然不能容纳大于32K的数字-Charles Williams

yx2lnoni

yx2lnoni3#

通过使用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

相关问题