Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA Excel For循环,变量数组使Excel崩溃_Vba_Excel_For Loop_Variant - Fatal编程技术网

VBA Excel For循环,变量数组使Excel崩溃

VBA Excel For循环,变量数组使Excel崩溃,vba,excel,for-loop,variant,Vba,Excel,For Loop,Variant,下午好。我正在使用For/Next循环和ReDim-Preserve向变量数组中添加未确定数量的值(客户)。我的代码如下: lRow = sht1.Cells(sht1.Rows.Count, 1).End(xlUp).Row cCount = 0 uCount = 0 var_Events = sht1.Range("A2:BC" & lRow).Value2 For i = LBound(var_Events) To UBound(var_Events) ReDim P

下午好。我正在使用For/Next循环和ReDim-Preserve向变量数组中添加未确定数量的值(客户)。我的代码如下:

lRow = sht1.Cells(sht1.Rows.Count, 1).End(xlUp).Row
cCount = 0
uCount = 0

var_Events = sht1.Range("A2:BC" & lRow).Value2

For i = LBound(var_Events) To UBound(var_Events)

    ReDim Preserve var_Customers(0 To cCount)

    If Not CustInArray(str(var_Events(i, 2)), var_Customers) Then

        var_Customers(cCount) = str(var_Events(i, 2))
        cCount = cCount + 1

    End If

    If i Mod 100 = 0 Then

        MsgBox "Line: " & i

    End If

Next i
以下是CustInArray功能:`

Function CustInArray(str As String, arr As Variant) As Boolean

    CustInArray = (UBound(Filter(arr, str)) > -1)

End Function`
在第一次崩溃后,我添加了Mod/MsgBox,以查看它在何处/何时崩溃,并且没有错误。在excel崩溃之前,它会到达大约6000行(我没有看到“line:6000”MsgBox)

我已经检查了var_事件的UBound,它是6290,与我的WS上的行数一致。我也试过(UBound(var_Events)-1),但仍然没有成功

我不是百分之百地解释为什么它会崩溃,因为没有错误,所以这就是我现在所能提供的。提前谢谢


编辑:我在评论中提到了这一点,但我认为在这里添加会很好。我最初想使用字典,但这只是一个较长过程的第一部分。每个客户都将有一个未知数量的项目分配给他们,这些项目的类别数量未知。

从数组足够大以容纳每一行的值开始,然后在最后使用
ReDim Preserve
将其缩小到正确的大小:

lRow = sht1.Cells(sht1.Rows.Count, 1).End(xlUp).Row
ReDim var_customers(0 to lRow - 1)
cCount = 0
uCount = 0

var_Events = sht1.Range("A2:BC" & lRow).Value2

For i = LBound(var_Events) To UBound(var_Events)
    If Not CustInArray(str(var_Events(i, 2)), var_Customers) Then
        var_Customers(cCount) = str(var_Events(i, 2))
        cCount = cCount + 1
    End If

    If i Mod 100 = 0 Then
        MsgBox "Line: " & i
    End If
Next i

ReDim Preserve var_customers(0 to cCount)
但是,有更好的方法可以做到这一点,可以使用Dictionary对象(如注释中所指出的)、内置的“删除重复项”命令,或者像这样使用ADO:

' Set up connection
Dim cn As Object
Set cn = CreateObject("ADODB.Connection")

' Connection string for Excel 2007 onwards .xlsm files
With cn
   .Provider = "Microsoft.ACE.OLEDB.12.0"
   .ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
        "Extended Properties=""Excel 12.0 Macro;IMEX=1"";"
    .Open
End With

' Connection string for Excel 97-2003 .xls files
' It should also work with Excel 2007 onwards worksheets
' as long as they have less than 65536 rows
'With cn
'    .Provider = "Microsoft.Jet.OLEDB.4.0"
'    .ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
'        "Extended Properties=""Excel 8.0;IMEX=1"";"
'    .Open
'End With

' Create and run the query
Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")

' Get all unique customers - assumes worksheet is named "Sheet1"
' and column name in cell B1 is "Customer"
rs.Open "SELECT DISTINCT [Customer] FROM [Sheet1$];", cn

' Output the field names and the results
Dim fld As Object
Dim i As Integer

' Change the worksheet to whichever one you want to output to
With Worksheets("Sheet3")
    .UsedRange.ClearContents

    For Each fld In rs.Fields
        i = i + 1
        .Cells(1, i).Value = fld.Name
    Next fld

    .Cells(2, 1).CopyFromRecordset rs

    ' You could now read the range values back into a variant array if you wanted to
End With

' Tidy up
rs.Close
cn.Close

Redim Preserve
一个数组数千次都非常消耗资源,可能会耗尽内存。我劝你开始使用a。在你提到它之后,我检查了一下,内存还没有用完。永远不要使用超过约500MB(26GB的可用容量)。我最初想使用字典,但这只是一个较长过程的第一部分。每个客户都将有未知数量的项目分配给他们,这些项目的类别也未知。当你说
崩溃时
它到底做了什么?excel是否关闭并消失?有错误吗?或者它会结冰变白?你可能对阅读感兴趣。“对于VBA(数组、代码等),32位版本的Excel似乎有大约500MB的内存限制。”。不要认为VBA会有效地利用系统上的所有可用内存。它具有固有的局限性。此外,我不知道为什么字典不能满足你提到的那些要求。说真的,一个接一个地重新定义阵列是一个非常糟糕的设计选择。至少,一次分配最大可能大小,然后在最后截断数组。但还是很糟糕。字典是一种可能的选择,但不是唯一的选择。