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

を調整しますおそらくこの投稿では間違った場所にあるでしょう。 [Code Review](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の代わりにSheets( "Data")を使用することもできます。

+0

ありがとう、@ z32a7ul。 – equanimity

+0

申し訳ありません、コードに2つのエラーがあります:(1)下付き文字が範囲外です - これはSheets( "Data")が存在しないためです(2)ActiveSheetに置き換えると、「Application defined or object defined error」が表示されます。これは、Columnsの代わりにCellsを記述する必要があるためです。だから、改訂されたコードで私の返信を更新しました。 – 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に、2番目の場合はe8に、3番目の場合はf8のように、数式を入れます。

これらの繰り返しのそれぞれで、その列の3番目の行(最初の繰り返しでIE D3)と2番目の行(2番目の繰り返しでは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の範囲全体には、一度に計算される1つの数式が含まれているとみなされ、10×1の値の結果配列を表示できます。個々のセルから数式を削除することはできません。問題のコードは、互いに別々に計算され、それぞれが1×1の値の配列を返す10の異なる式を隣り合わせに作成します。これらのセルを1つずつ削除することができます。ただし、いくつかのワークシート関数が異なる方法で計算されるため、Formulaプロパティの変更と同じではありません(たとえば、= SUM(ROW(1:2))はFormulaとして1を返し、FormulaArrayとして3を返します)。 – z32a7ul

関連する問題