更有效地编写索引/匹配循环

我正在使用索引/匹配循环从另一个工作表(wsNewMV)检索值并填充工作表wsMvFile。 如果该值不在wsNewMV中,则它将从工作表wsMvOld中的不同列中获取值。 由于我的代码逐列,我需要根据值比较20列代码是相当大的。

任何关于如何在下面写代码的想法更有效率:

For i = 2 To y vrw = Application.Match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0) If IsError(vrw) Then vrw = Application.Match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0) If Not IsError(vrw) Then _ wsMvFile.Range("B" & i) = Application.Index(wsMvOld.Columns(2), vrw) Else wsMvFile.Range("B" & i) = Application.Index(wsNewMV.Columns(3), vrw, 1) End If Next i For i = 2 To y vrw = Application.Match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0) If IsError(vrw) Then vrw = Application.Match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0) If Not IsError(vrw) Then _ wsMvFile.Range("C" & i) = Application.Index(wsMvOld.Columns(3), vrw) Else wsMvFile.Range("C" & i) = Application.Index(wsNewMV.Columns(5), vrw, 1) End If Next i For i = 2 To y vrw = Application.Match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0) If IsError(vrw) Then vrw = Application.Match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0) If Not IsError(vrw) Then _ wsMvFile.Range("D" & i) = Application.Index(wsMvOld.Columns(4), vrw) Else wsMvFile.Range("D" & i) = Application.Index(wsNewMV.Columns(6), vrw, 1) End If Next i For i = 2 To y vrw = Application.Match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0) If IsError(vrw) Then vrw = Application.Match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0) If Not IsError(vrw) Then _ wsMvFile.Range("E" & i) = Application.Index(wsMvOld.Columns(5), vrw) Else wsMvFile.Range("E" & i) = Application.Index(wsNewMV.Columns(7), vrw, 1) End If Next i For i = 2 To y vrw = Application.Match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0) If IsError(vrw) Then vrw = Application.Match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0) If Not IsError(vrw) Then _ wsMvFile.Range("F" & i) = Application.Index(wsMvOld.Columns(6), vrw) Else wsMvFile.Range("F" & i) = Application.Index(wsNewMV.Columns(8), vrw, 1) End If Next i 

请注意,wsMvFile.Range范围从A到U,wsMvOld.Columns范围从1列到21列,只有wsNewMV.Columns范围将取决于所拉列。

谢谢你的帮助!

一个好的开始是将所有的通用代码提取到它自己的Sub

 Private Sub AppropriateName(wsMvFile As Worksheet, wsMvOld As Worksheet, wsNewMV As Worksheet, _ rowCount As Long, workCol As String, _ srcCol1 As Integer, srcCol2 As Integer) Dim vrw As Variant, i As Long For i = 2 To rowCount vrw = Application.match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0) If IsError(vrw) Then vrw = Application.match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0) If Not IsError(vrw) Then _ wsMvFile.Range(workCol & i) = Application.Index(wsMvOld.Columns(srcCol1), vrw) Else wsMvFile.Range(workCol & i) = Application.Index(wsNewMV.Columns(srcCol2), vrw, 1) End If Next i End Sub 

然后你可以用适当的参数调用它:

 AppropriateName wsMvFile, wsMvOld, wsNewMV, y, "B", 2, 3 AppropriateName wsMvFile, wsMvOld, wsNewMV, y, "C", 3, 5 AppropriateName wsMvFile, wsMvOld, wsNewMV, y, "D", 4, 6 AppropriateName wsMvFile, wsMvOld, wsNewMV, y, "E", 5, 7 AppropriateName wsMvFile, wsMvOld, wsNewMV, y, "F", 6, 8 

理想情况下,它会进入自己的循环,但是由于最后一个参数跳过了数字4,所以您必须进行一些查找。 那至less应该开始重构。

以下是一个非常短(和快速)的解决scheme

 Sub doit(curMVSht As Worksheet, oldMVSht As Worksheet, newMVSht As Worksheet, curShtCol As String, oldShtCol As Long, newShtCol As Long) curMVSht.Columns("A").SpecialCells(xlCellTypeConstants).Offset(, Columns(curShtCol).Column - 1).FormulaR1C1 = _ "=IFERROR(INDEX(" & newMVSht.name & "!C" & newShtCol & ",MATCH(RC1," & newMVSht.name & "!C2,0))," _ & " IFERROR(INDEX(" & oldMVSht.name & "!C" & oldShtCol & ",MATCH(RC1," & oldMVSht.name & "!C1,0))," _ & " """"))" End Sub 

它实际上是一个单一的陈述,我为了可读性的目的而分成三行,你可以称之为

 doit wsMvFile, wsMvOld, wsNewMV, "B", 2, 3 doit wsMvFile, wsMvOld, wsNewMV, "C", 3, 5 doit wsMvFile, wsMvOld, wsNewMV, "D", 4, 6 doit wsMvFile, wsMvOld, wsNewMV, "E", 5, 7 doit wsMvFile, wsMvOld, wsNewMV, "F", 6, 8