Excelでは、2つの配列間で一致するデータを見つける必要があります-1つの水平と1つの垂直


0

Excel 2010(または2007-両方がありますが、実行している一部のレガシーアプリケーションの制限として私のOSはWin7 32ビットのみです)、2つのデータ配列から一致する値を見つけて返す方法を見つける必要があります。

2つのスプレッドシートがあります。1つは、階層的なOLAPキューブディメンションからの巨大なフラットファイルです(SAP BPCから37,000行)。もう1つは、照合する必要がある値のテーブルです。一致する値を2番目のスプレッドシートから最初のシート(フラットファイル)のColumnAに返す必要があります。

課題は、階層構造であるため、Sheet1から一致する単一の列を選択できないことです。各行の列のいずれかで一致する可能性があります。したがって、基本的に、配列としてのSheet 1の単一行と配列としてのSheet 2の列の間で一致するものは何でも取る必要があると考えています(私は思う)。

英語では、Excelに次のことを行います。データがあるSheet1の各行について、行全体を調べます(たとえば、範囲B2:R2-式/一致値の列Aを空白のままにします)。レポートカテゴリリスト(シート2列A、範囲A1:A42)のいずれかに一致するものがある場合、Sheet2値をSheet1!A2(一致用に作成した空白列)に返します。

これは食物のeg話を含むデータのサンプルです。空のColumnAを作成し、各行のデータは分類の階層に進み、ColBが基本レベルであり、必要に応じて端末の親がColFになるように繰り返されることに注意してください。

ここに画像の説明を入力してください

さて、この次の画像は、使用したいレポート形式です。いくつかの階層レベルのデータが必要な場合もあれば、他の階層レベルのデータが必要な場合もあります。

ここに画像の説明を入力してください

最終的に、スプレッドシートには、必要なカスタマイズされたレポートカテゴリが入力されます(その後、集計データのカテゴリをピボットできます)。ここに画像の説明を入力してください

私はモンスターのvlookup式を使用してこれを達成しましたが、vlookupステートメントが8つの深さでネストされた37,000行がExcelをたくさんクラッシュさせるので、別の、より簡単な、または少なくともリソース集約的でない方法があるのだろうかと思っていました。したがって、実際のレポートカテゴリ(sheet2はAll_Budget_Unitsと呼ばれます)を使用して、現在使用しているのは次のとおりです。

= IFERROR(VLOOKUP(IFERROR(VLOOKUP(IFERROR(VLOOKUP(IFERROR(VLOOKUP(IFERROR(VLOOKUP(IFERROR(VLOOKUP(C2、All_Budget_Units!$ A $ 1:$ A $ 39,1、FALSE)、D2)、All_Budget_Units!$ A $ 1 :$ A $ 39,1、FALSE)、E2)、All_Budget_Units!$ A $ 1:$ A $ 39,1、FALSE)、F2)、All_Budget_Units!$ A $ 1:$ A $ 39,1、FALSE)、G2)、All_Budget_Units !$ A $ 1:$ A $ 39,1、FALSE)、H2)、All_Budget_Units!$ A $ 1:$ A $ 39,1、FALSE)、I2)

回答:


0

YMMV、ただし表示->マクロ、マクロを追加します。これを試してください(必要に応じてセル参照を変更します):

Dim data, reference As Range

Set reference = Worksheets("Sheet2").Range("A1", "A42")
Set data = Worksheets("Sheet1").Range("B2", "F6")

For Each dataCell In data
    For Each referenceCell In reference
        If dataCell.Value = referenceCell.Value Then
                Worksheets("Sheet1").Cells(dataCell.Row, 1).Value = dataCell.Value
        End If
    Next
Next

[編集:これが機能する場合、一致するものが見つかったら行の検索を停止することで、少し高速化できます。(行ごとに1つの一致のみを想定)。例えば:

Sub newtest()
    Dim data, reference As Range
    Dim skipsome As Boolean
    skipsome = False

    Set reference = Worksheets("Sheet2").Range("A1", "A7")

    Set data = Worksheets("Sheet1").Range("B2", "F6")
    For Each dataCell In data
        For Each referenceCell In reference
            If dataCell.Value = referenceCell.Value Then
                    Worksheets("Sheet1").Cells(dataCell.Row, 1).Value = dataCell.Value
                    skipsome = True
                    Exit For
            End If

            If skipsome = True Then
                skipsome = False
                Exit For
            End If
        Next
    Next
End Sub

5行のテストデータだけで、セル比較テストが175から132に低下します。] [編集2:コードを機能させる]


はい、階層構造なので、行ごとに可能な一致は1つだけです。それ以外の場合、階層の複数のレベルでレポートすることによりデータを複製します。マクロをありがとう-試してみます!
ppfooie

2

このためのマクロソリューションは必要ありません。配列数式を使用できます。

{=INDEX(All_Budget_Units!$A$1:$A$39, MAX(IFERROR(MATCH(C2:I2, All_Budget_Units!$A$1:$A$39, 0), 0)))}

これは、I2の値がマスターリストにもあると想定しているため、元の式では想定されていません。存在しない場合、または存在しない場合は、代わりにこれを使用します。

{=IFERROR(INDEX(All_Budget_Units!$A$1:$A$39, MAX(IFERROR(MATCH(C2:H2, All_Budget_Units!$A$1:$A$39, 0), -1))), I2)}

以前に配列式を使用したことがない場合は、中括弧{}を自分で入力しないでください。式の残りの部分を入力し、CTRL + SHIFT + ENTERを押して配列式として入力します。正しく行った場合、ブレースが数式ボックスに表示されます。

これがMATCH機能する方法は、関数を使用して一致結果の配列を作成することです。これらの1つを除くすべてが#N/AそうであるIFERRORため、これらを0(または2番目のバージョンでは-1)に変換するためにラップします。実際の一致はすべて正の数になるためMAX、配列を取得すると単一の一致が検出されます。次に、INDEX関数を使用してこれを値に変換します。2番目のバージョンでINDEXは、-1の位置で一致するものがまったくない場合、エラーを生成するためIFERROR、デフォルト値を返すために使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.