Visual Basic,VBA数组循环

时间:2017-08-16 22:51:17

标签: arrays excel vba loops

我用http://www.homeandlearn.org/arrays_and_loops.html来帮助我。

我有过滤到一个表的数据连接。不幸的是,当程序将文件导出到Excel时,其中一个源会在错误的列(客户端列)中随意放置不正确的数据(通常是日期)。我想做的是与索引/匹配功能类似的东西。我想检查此主表(A)中的每个预留号码与同一工作簿中的另一个表(B)。如果来自其他表(B)的预订编号与主表(A)中的预订编号匹配,我希望将正确的客户端值输入主表(A)。我对VBA还很陌生,所以对任何帮助表示赞赏。我试图在这里和那里修改我的代码,但无济于事。另外,我最初在没有真实数据的情况下将其作为练习运行,因此我没有弄乱原始文件。我试图添加适当的语法来引用其他工作表和诸如此类的东西,所以我想也可能输错了。这是我提出的最接近的原始代码:

Sub TransferData()
Dim MyArray(1 To 19) As Single

MyArray(1) = 81899
MyArray(2) = 87172
MyArray(3) = 87275
MyArray(4) = 87394
MyArray(5) = 87446
MyArray(6) = 87496
MyArray(7) = 87621
MyArray(8) = 87631
MyArray(9) = 87726
MyArray(10) = 87822
MyArray(11) = 87858
MyArray(12) = 88041
MyArray(13) = 88097
MyArray(14) = 88127
MyArray(15) = 88160
MyArray(16) = 88191
MyArray(17) = 88359
MyArray(18) = 88487
MyArray(19) = 88545

For i = 1 To 19
    If Worksheets("Sheet1").Range("B" & i).Value = MyArray(i) Then
       Worksheets("Sheet2").Range("P" & i).Value = _ 
       Worksheets("Sheet1").Range("E" & i).Value
    End If
Next i

End Sub

我不记得这个错误,因为代码并不完全如上,但接近它。我认为它遇到的问题是,当i变量超过19时,系统无法找到数组> 19.我需要VBA检查19个数组,这些数组的行数目前在3k +。我试图添加另一个变量思考,如果我保持变量分开,我可以让VBA检查所有行的19个数组。这是我为此提出的代码......

Sub TransferData()
Dim MyArray(1 To 19) As Single

MyArray(1) = 81899
MyArray(2) = 87172
MyArray(3) = 87275
MyArray(4) = 87394
MyArray(5) = 87446
MyArray(6) = 87496
MyArray(7) = 87621
MyArray(8) = 87631
MyArray(9) = 87726
MyArray(10) = 87822
MyArray(11) = 87858
MyArray(12) = 88041
MyArray(13) = 88097
MyArray(14) = 88127
MyArray(15) = 88160
MyArray(16) = 88191
MyArray(17) = 88359
MyArray(18) = 88487
MyArray(19) = 88545

For i = 1 To 5000
For j = 1 To 19
If Worksheets("Sheet1").Range("B" & i).Value = MyArray(j) Then
    Worksheets("Sheet2").Range(i, 16).Value = Worksheets("Sheet1"). _ 
    Range(i,5).Value
    Next j
End If
Next i

End Sub

使用此代码我得到编译错误:Next没有For。在线搜索我发现这可能是因为我有2" For" s,if语句," next"在if语句中的声明,然后是另一个" next"循环之外的陈述。我认为必须这样做,以便B列中的每个单元格都可以检查所有数组的可能性。

见下图。我需要将工作表中的列P(实际出具工具名称)的值:TMRtoSPIde输入到工作表上的列D(出具名称):RawData,当工作表中列K中的预留#:TMRtoSPIde与工作表中的预留匹配时:RawData。您将注意到工作表:RawData在“结算名称”列中有一个错误的5位数序列日期。这些是我试图取代的。

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

词典和集合非常适合匹配唯一值。在此示例中,我使用Scripting.Dictionary来存储唯一ID以及对它们所在的EntireRow的引用。

注意:Range().Range()将返回相对于第一个范围对象的引用(例如Range("A10").EntireRow.Range("ZZ1").Address返回$ZZ$10)。

只存储所需的值会更简单,我只是想证明你可以在Dictionary中存储对象引用。请务必注意,您可以将对象存储为字典中的键和/或值。人们常犯的一个错误是尝试存储范围引用,因为键dictionary.Add Cells(1,1), Cells(1,2)会将Cells(1,1)的引用存储为键,Cells(1,2)存储引用值。这个问题是字典不知道如何比较单元格,你将无法根据关键关系查找你的值。 dictionary.Add Cells(1,1).Value, Cells(1,2)是正确的语法。

Sub TransferData()
    Dim r As Range, Source As Range
    Dim d As Object
    Set d = CreateObject("Scripting.Dictionary")
    With Worksheets("TMRtoSPIde")
        For Each r In .Range("B2", .Range("B" & .Rows.Count).End(xlUp))
            If Not d.Exists(r.Value) Then d.Add r.Value, r.EntireRow
        Next
    End With

    With Worksheets("RawData")
        For Each r In .Range("B2", .Range("B" & .Rows.Count).End(xlUp))
            If d.Exists(r.Value) Then
                r.EntireRow.Range("K1").Value = d(r.Value).Range("P1").Value
            End If
        Next
    End With

End Sub

答案 1 :(得分:0)

你的循环应该是这样的:

For i = 1 To 5000
    For j = 1 To 19
        If Worksheets("Sheet1").Cells(i, "B").Value = MyArray(j) Then
            Worksheets("Sheet2").Cells(i, "P").Value = Worksheets("Sheet1").Cells(i, "E").Value
            'Exit from the "For j" loop if we found a match
            Exit For
        End If
    Next j
Next i