2017-08-16 14 views
0

私はhttp://www.homeandlearn.org/arrays_and_loops.htmlを使ってこれを手伝ってくれました。Visual Basic、VBA配列ループ

1つのテーブルにフィルタリングするデータ接続があります。残念ながら、ソースの1つは、プログラムがExcelにファイルをエクスポートするときに間違ったデータ(通常は日付)を間違った列(Client列)にランダムに配置します。私がしたいのは、インデックス/マッチ機能に似たものです。私はこのマスターテーブル(A)の各予約番号を同じブック内の別のテーブル(B)と照合したいと思います。他のシート(B)からの予約番号がマスターテーブル(A)の予約番号と一致する場合は、マスターテーブル(A)に正しいクライアント値を入力したいと思います。私はまだかなりVBAに新しいので、どんな助けもありがとうございます。私はここで、私のコードを変更しようとしたが役に立たない。また、私はもともと本物のデータなしでこれを練習として実行していたので、元のファイルを台無しにしませんでした。他のシートやその他のものを参照するための適切な構文を追加しようとしたため、間違って入力することもできます。私が思いついた最も近い元のコードは次のとおりです。

Sub TransferData() 
Dim MyArray(1 To 19) As Single 

MyArray(1) = 81899 
MyArray(2) = 87172 
MyArray(3) = 87275 
MyArray(4) = 87394 
MyArray(5) = 87446 
MyArray(6) = 87496 
MyArray(7) = 87621 
MyArray(8) = 87631 
MyArray(9) = 87726 
MyArray(10) = 87822 
MyArray(11) = 87858 
MyArray(12) = 88041 
MyArray(13) = 88097 
MyArray(14) = 88127 
MyArray(15) = 88160 
MyArray(16) = 88191 
MyArray(17) = 88359 
MyArray(18) = 88487 
MyArray(19) = 88545 

For i = 1 To 19 
    If Worksheets("Sheet1").Range("B" & i).Value = MyArray(i) Then 
     Worksheets("Sheet2").Range("P" & i).Value = _ 
     Worksheets("Sheet1").Range("E" & i).Value 
    End If 
Next i 

End Sub 

コードは正確に上記と同じではなく、それに近いので、私はエラーを思い出しません。私はそれが実行されていた問題は、変数が19より上になったとき、システムは配列> 19を見つけることができなかったと信じています。現在、3k +になっている行の数が変わっても19個の配列をチェックする必要があります。変数を別にしておくと、別の変数を追加しようとしましたが、VBAですべての行に対して19個の配列をチェックできるようになりました。ここで私はコンパイルエラーを取得、このコードでは、私はそれのために思い付いたコード....

Sub TransferData() 
Dim MyArray(1 To 19) As Single 

MyArray(1) = 81899 
MyArray(2) = 87172 
MyArray(3) = 87275 
MyArray(4) = 87394 
MyArray(5) = 87446 
MyArray(6) = 87496 
MyArray(7) = 87621 
MyArray(8) = 87631 
MyArray(9) = 87726 
MyArray(10) = 87822 
MyArray(11) = 87858 
MyArray(12) = 88041 
MyArray(13) = 88097 
MyArray(14) = 88127 
MyArray(15) = 88160 
MyArray(16) = 88191 
MyArray(17) = 88359 
MyArray(18) = 88487 
MyArray(19) = 88545 

For i = 1 To 5000 
For j = 1 To 19 
If Worksheets("Sheet1").Range("B" & i).Value = MyArray(j) Then 
    Worksheets("Sheet2").Range(i, 16).Value = Worksheets("Sheet1"). _ 
    Range(i,5).Value 
    Next j 
End If 
Next i 

End Sub 

です:次の場合なし。オンラインで検索すると、2つの「For」、if文、if文内の「next」文、ループの外側の別の「next」文があるために見つかった可能性があります。私は、B列の各セルがすべての配列の可能性に対してチェックされるように、このようにしなければならないと考えていました。

下記の画像を参照してください。シートからの列K(TMRtoSPIde)の値がシート:RawDataの列D(請求金額)に入力される必要があります。シートには、RawDataに5桁のシリアル日付がBilling Name列に誤って表示されています。これらは私が取り組もうとしているものです。

enter image description here

enter image description here

+0

。レンジ( "B2")。[値]次に 'のワークシート( "シート2")。レンジ( "P2")。値= ワークシート( "Sheet1")。Range( "E2")。Value'。 'Worksheets(" Sheet1 ")の予約番号として' Worksheets( "Sheet2")の同じ行を更新しているのは不思議です。 '私はあなたが' Worksheets( " Sheet2 ")'も同様です。 –

+0

あなたは間違いなしです。私は少しここで描画ボードに戻るつもりです。これをキャッチするためにありがとう。 – Craig

+0

'MyArray()'の目的は何ですか?これらのコードは、コードを使用するために制限したいアカウント番号のサブセットですか?あなたが使用したくない他の口座番号はありますか? –

答えて

1

辞書とコレクションは、一意の値を一致させるための理想的です。この例では、Scripting.Dictionaryを使用して、一意のIDとそれらが見つかったEntireRowへの参照を格納します。

注:Range().Range()は、最初の範囲オブジェクトを基準にした参照を返します(Range("A10").EntireRow.Range("ZZ1").Address$ZZ$10など)。

これは、必要な値だけを格納する方が簡単です。オブジェクト参照を辞書に格納できることを実証したかったのです。ディクショナリ内のキーおよび/または値の両方としてオブジェクトを保存できることに注意することが重要です。一般的な間違いは、範囲参照をキーとして保存しようとすることです。dictionary.Add Cells(1,1), Cells(1,2)は、Cells(1,1)をキーとして、Cells(1,2)という参照を値として保存します。この問題は、ディクショナリがセルの比較方法を知らず、キーの関係に基づいて値をルックアップすることができなくなるという問題があります。dictionary.Add Cells(1,1).Value, Cells(1,2)は正しい構文です。予約番号が 'ワークシート( "シート1")上で発見された場合

Sub TransferData() 
    Dim r As Range, Source As Range 
    Dim d As Object 
    Set d = CreateObject("Scripting.Dictionary") 
    With Worksheets("TMRtoSPIde") 
     For Each r In .Range("B2", .Range("B" & .Rows.Count).End(xlUp)) 
      If Not d.Exists(r.Value) Then d.Add r.Value, r.EntireRow 
     Next 
    End With 

    With Worksheets("RawData") 
     For Each r In .Range("B2", .Range("B" & .Rows.Count).End(xlUp)) 
      If d.Exists(r.Value) Then 
       r.EntireRow.Range("K1").Value = d(r.Value).Range("P1").Value 
      End If 
     Next 
    End With 

End Sub 
+0

あなたが言及した行全体のためにあなたの応答を読んだ後、コードでそれを見て少し変わった。私はこれのために必要ではない左のテーブルを転送することを心配していた。だから、私は右のテーブルを緑のヘッダーで取り、それを自分のシートに置き、それに合わせてコーディングを変更して、うんざり!助けてくれてありがとう。私はVBAのコレクションや辞書を聞いたことがないので、それらを調べます。私はVBAにまだまだ新しく、すぐにクラスに参加していますので、少し前から、少し時間をずらして、そして解決策をとってくれてありがとう! – Craig

0

あなたのループは、おそらくこのようにする必要があります:

For i = 1 To 5000 
    For j = 1 To 19 
     If Worksheets("Sheet1").Cells(i, "B").Value = MyArray(j) Then 
      Worksheets("Sheet2").Cells(i, "P").Value = Worksheets("Sheet1").Cells(i, "E").Value 
      'Exit from the "For j" loop if we found a match 
      Exit For 
     End If 
    Next j 
Next i 
+0

これを調べていただきありがとうございます。私はトマスの提案を受け取り、それをあなたのものに結びつけて、私の所見を提供します。 – Craig