2016-08-23 265 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