Excel に 2 変数の 100x100 データ テーブルがあります。
特定のターゲット値を生成する可能性のある変数のすべてのセットを返す関数が必要です。私が見ているのは、ある種の再帰的な 2 次元ルックアップ関数です。誰かが私を正しい方向に向けることができますか?
あなたが望むことをする組み込み関数はありません、私はそれを99%確信しています。
配列を返すVBA関数は、すでに示した手っ取り早いSubの線に沿って作成できます。出力を保持するバリアントを作成します。おそらく、結果の可能な最大数に再減光し、最後に実際の数に再減光します。次に、配列関数として呼び出す必要がある関数の結果としてそれを返します(Control-Shift-Enter)。
欠点の1つは、ターゲット範囲が結果全体を保持するのに十分な大きさであることを確認する必要があることです。Excelはそれを自動的に実行しません。
のように、かなりコンパクトに、VBA なしで実行できます。
100x100 のテーブルが B2:CW101 にあり、1 から 100 までの数字のリストを左下の A2 から A101 まで配置し、1 から 100 までのリストを上部の B1 から CW1 まで配置するとします。
B104 から (たとえば) セルの下に列を作成します。
B104=MAX(($A$2:$A$101*100+$B$1:$CW$1<B103)*($B$2:$CW$101=TargetValue)*($A$2:$A$101*100+$B$1:$CW$1))
これは「配列」式であるため、の代わりにCtrl- Shift-を押すと、中かっこ {} が式の周りに表示されます。EnterEnter
次に、必要な数の行を下にコピーします。また、最初の式の上、つまり B103 には 999999 のように大きな数字を入れる必要があります。
式が行うことは、Rowx100+Column を計算することですが、成功したセルごとにのみであり、MAX 関数は、見つかった以前の結果をすべて除外して最大の結果を見つけます。左上まで。(少し努力すれば、別の方法で検索できるようになります)。
これにより、行 99、列 22 である 9922 のような結果が得られ、数値からこれらの値を簡単に抽出できます。
VBA を使用しないソリューションがありますが、かなり面倒です。これには、Excel でさらに 1 次元のテーブルを作成し、それを参照することが含まれます。100x100 のデータ テーブルの場合、新しいテーブルには 10,000 行が必要です。
これがあなたのニーズに合わない場合はお詫び申し上げます。
以下に概要を示します。詳細が必要な場合はお知らせください。N = データの次元。例では 100 です。
まず、5 つの列と NxN 行の新しいテーブルを作成します。いずれの場合も、列名を適切な Excel 参照に置き換えます
最初の列 (INDEX と呼びます) には、1、2... NxN が単純にリストされています。
2 番目の列 (DATAROW) には、1、2... N、1、2...N... をループする数式が含まれています。これは、=MOD(INDEX-1, N)+1 のようなものを使用して実行できます。
3 番目の列 (DATACOL) には、1、1、1... 2、2、2... (それぞれ N 回) が含まれます。これは =INT((INDEX-1)/N)+1 で実行できます
4 番目の列 (VALUE) には、データ テーブルが $A$1 から始まると仮定して、=OFFSET($A$1, DATAROW, DATACOL) のようなものを使用して、データ テーブルの値が含まれます。
これで、すべてのデータを保持する 1 次元のテーブルができました。
5 番目の列 (LOOKUP) には、式 =MATCH(target, OFFSET(VALUERANGE, [LOOKUP-1], 0),0)+ [LOOKUP-1] が含まれます。
ここで、[LOOKUP-1] はすぐ上のセルを指します (たとえば、セル F4 では、これは F3 を指します)。LOOKUP 列の最初のセルの上に 0 が必要です。
VALUERANGE は、VALUE 列全体への固定の (名前を付けるか、または $ 記号を使用して) 参照にする必要があります。
次に、LOOKUP 列に INDEX 番号が保持されます。これを使用して DATAROW および DATACOL を検索し、データ内で一致する位置を見つけます。
これは、VALUERANGE で一致を検索してから、前の一致の後に始まる調整された範囲で一致を検索することによって機能します。
上記の説明よりもスプレッドシートの方がはるかに簡単ですが、それが今のところ私ができる最善のことです...
VBA を使用せずにこれを何度も試しましたが、VBA なしでは不可能のようです。この問題を解決するには、配列全体をループして最も近い値を見つける必要がありました。これらの値は、呼び出しと範囲プロパティを使用して逆参照され、有効な一致ごとにインクリメントされる範囲で出力が生成されました。
手っ取り早い実装は次のとおりです。
Dim arr As Range
Dim tempval As Range
Dim op As Integer
Set arr = Worksheets("sheet1").Range("b2:ao41")
op = 1
Range("B53:D153").ClearContents
For Each tempval In arr
If Round(tempval.Value, 0) = Round(Range("b50").Value, 0) Then
Range("b52").Offset(op, 0).Value = Range("a" & tempval.Row).Value
Range("b52").Offset(op, 1).Value = Cells(tempval.Column, 1).Value
Range("b52").Offset(op, 2).Value = tempval.Value
op = op + 1
End If
Next
Range("b50").Select
私はまだVBAを使わないアプローチを探しています。