2016-08-23 267 views
0

我有以下的冗余代码:VBA - 如何循环列和插入数组公式

Sheets("Data").Range("D8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(D3&$C8, client_range & date_range, 0),MATCH(D2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("E8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(E3&$C8, client_range & date_range, 0),MATCH(E2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("F8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(F3&$C8, client_range & date_range, 0),MATCH(F2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("G8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(G3&$C8, client_range & date_range, 0),MATCH(G2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("H8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(H3&$C8, client_range & date_range, 0),MATCH(H2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("I8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(I3&$C8, client_range & date_range, 0),MATCH(I2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("J8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(J3&$C8, client_range & date_range, 0),MATCH(J2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("K8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(K3&$C8, client_range & date_range, 0),MATCH(K2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("L8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(L3&$C8, client_range & date_range, 0),MATCH(L2, name_range, 0)), ""Error"")" 

Sheets("Data").Range("M8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(M3&$C8, client_range & date_range, 0),MATCH(M2, name_range, 0)), ""Error"")" 

有没有一种方法,我可以通过遍历列这段代码更紧凑和维护?

谢谢!

+0

如果你有工作代码,仅仅需要改进,那么你可能在这篇文章的错误位置。 [代码评论](http://codereview.stackexchange.com/)是他们处理现有/工作代码的地方,并且在速度,安全性,可持续性和包括最佳实践在内的使用寿命等方面尽最大努力改进。试一试。他们很棒! – Ralph

回答

1

您需要使用细胞代替范围为FormulaArray的父母和地址动态地计算公式:

Dim C As Long: For C = 4 To 13 ' Column 'D' = Column 4 
    Sheets("Data").Cells(8,C).FormulaArray = "=IFERROR(INDEX(data_range, MATCH(" & Sheets("Data").Columns(3,C).Address(False, False) & "&$C8, client_range & date_range, 0),MATCH(" & Sheets("Data").Columns(2,C).Address(False, False) & ", name_range, 0)), ""Error"")" 
Next C 

修订代码:

Dim C As Long: For C = 4 To 13 ' Column 'D' = Column 4 
    ActiveSheet.Cells(C, 8).FormulaArray = "=IFERROR(INDEX(data_range, MATCH(" & ActiveSheet.Cells(C, 3).Address(False, False) & "&$C8, client_range & date_range, 0),MATCH(" & ActiveSheet.Cells(C, 2).Address(False, False) & ", name_range, 0)), ""Error"")" 
Next C 

中当然,您可能希望使用表格(“数据”)而不是ActiveSheet,具体取决于您的工作环境。

+0

谢谢,@ z32a7ul。当我运行此代码时,我看到“下标超出范围”... – equanimity

+0

对不起,代码中有两个错误:(1)下标超出范围 - 这是因为表格(“数据”)不存在一个新的工作簿,(2)一旦我用ActiveSheet取代它,我得到了'应用程序定义或对象定义错误' - 这是因为我应该写出单元格而不是列。所以,我用修改后的代码更新了我的答复。 – z32a7ul

+0

(3)我交换了行和列。 – z32a7ul

0

我会使用范围属性偏移量在这里看到https://msdn.microsoft.com/en-us/library/office/ff840060.aspx。偏移量,它基于所述回路 编辑的增量:

for i = 0 to range.("d8").end(xlRight) 
Sheets("Data").range("d8").offset(0, i).FormulaArray = "=IFERROR(INDEX(data_range, match(Sheets("Data").range("d8").offset(-5,i) & Sheets("Data").range("c8"), client_range & date_range, 0), Match(Sheets("Data").range("d8").offset(-6,i), name_range, 0)), ""Error"")" next i 

的功能开始于细胞D8,并不断通过在列1抵消它;所以它会在第一次迭代中将公式放入d8中,第二次中的公式为e8,第三次中则为f8,依此类推。

看来,在这些迭代中的每一个迭代中,您都需要查找位于该列第三行(第一次迭代的IE D3)和第二行(第二次迭代的IE D2)的数据。基本上我提出的解决方案替换

表(“数据”)。范围(“D8”),每个单元格引用。偏移(X,I),其中根据您正在寻求获取信息哪一行X变化

从;如果你写了第8行(X = 0),第3行(x = -5)或第2行(x = -6)

1

这里有一种方法可以解决它。任何问题,只是问:

Sub DoSomething() 
    Dim sRange1 As String, sRange2 As String, sRange3 As String 
    Dim i As Integer 

    For i = 4 To 13 
     sRange1 = Cells(8, i).Address 
     sRange2 = Cells(3, i).Address 
     sRange3 = Cells(2, i).Address 
     Sheets("Data").Range(sRange1).FormulaArray = "=IFERROR(INDEX(data_range, MATCH(" & sRange2 & "&$C8, client_range & date_range, 0),MATCH(" & sRange3 & ", name_range, 0)), ""Error"")" 
    Next i 
End Sub 
-1

我不认为你需要循环。 .Formula调整没有,相对行和列$

Sheets("Data").Range("D8:M8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(D3&$C8, client_range & date_range, 0),MATCH(D2, name_range, 0)), ""Error"")" 

更新

For Each c in Split("D E F G H I J K L M") 
    Sheets("Data").Range(c & "8").FormulaArray = "=IFERROR(INDEX(data_range, MATCH(" & c & _ 
     "3&$C8, client_range & date_range, 0),MATCH(" & c & "2, name_range, 0)), ""Error"")" 
Next 

For Each cell in Sheets("Data").Range("D8:M8") 
    c = Chr(64 + cell.column) ' Asc("A") is 65 ' or c = Left(cell.Address(0,0)) 
    cell.FormulaArray = "=IFERROR(INDEX(data_range, MATCH(" & c & _ 
     "3&$C8, client_range & date_range, 0),MATCH(" & c & "2, name_range, 0)), ""Error"")" 
Next 
+0

在这种情况下,整个D8:M8范围将被视为包含一个公式,该公式可以立即计算出来,并可以显示10×1值的结果数组。您不能从个别单元中删除公式。问题中的代码会相互创建10个不同的公式,这些公式将分别计算,并且每个公式都会返回一个1 x 1值的数组。您可以逐个删除这些单元格。但是,它与改变公式属性仍然不一样,因为某些工作表函数是以不同的方式计算的(例如= SUM(ROW(1:2))返回1作为公式,3作为公式数组)。 – z32a7ul