我正在使用索引/匹配循环从另一个工作表(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范围会有所不同,具体取决于拉出的列。
感谢您的帮助!
答案 0 :(得分:1)
一个良好的开端是将所有常用代码提取到其自己的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,你必须进行某种查找。这至少应该是重构的开始。
答案 1 :(得分:1)
以下是一个非常简短(快速)的解决方案
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