2016-12-13 5 views
0

驚いたことに、Googleの回答であるをこのサイトと同様に検索すると、この問題に対する明らかな答えが得られなかったので、Excelで2dの範囲を1dの範囲に変換して機能に使用する

2次元セル範囲(A1:C3など)を1次元範囲(A1:A10のような列または行)に変換するマクロ(おそらくUDF)を作成しようとしています。これは、2次元アレイが必要とされるときにMATCH()のような関数で使用するためである。 A1:C3の特定の値を検索します。しかし、この機能を汎用性のあるものにしたいので、2D配列を丸めて1Dにすることができます。 =INDEX(ARRAYDIMENSION(A1:C1),4)または=MATCH("hello",ARRAYDIMENSION(A1:C1),0)

のように私はすでに厄介なアプローチを作ってみました。私は新しいシートに互いに下(A1:A3A1:C3B1:B3C1:C3ため)私のアレイの各列を平手打ち(SO A2は、新しいシートのA2にコピーされ、C3はA9、A4等のB1にコピーされる)

私は新しい配列(Sheet2!A1:A9)の参照を返すので、代わりにMATCH()またはINDEX()と表示されます。

これは機能しますが、明らかな欠陥があります。新しいシートを追加することはマクロには時間がかかり、醜いので、個々の列を積み重ねることは最も効果的な方法ではありません。しかし、特に、マクロはシートを編集するので、UDFにはなり得ません(私は思っていません)。それは、それが必要な式に入れるだけでなく、自己完結型のWorksheet_Calculate Subとして使用する必要があります。


私はそれが比較的明確だと思う、助けてください/最善のアプローチに助言、私はので、私はまだスーパースリックないんだけど、数週間VBAingされています。

+0

あなたは何をしたいですか?配列式はオプションですか? –

答えて

2

これは、あなたが始めるだろう:

Function ArrayDim(rn As Range, dir As Integer) 
Dim test() As Variant 
Dim rng() As Variant 
Dim cell As Range 
Dim i As Long 
rng = rn.Value 
ReDim test(1 To UBound(rng, 1) * UBound(rng, 2)) 
i = 1 

If dir = 0 Then 
    For r = 1 To UBound(rng, 1) 
     For c = 1 To UBound(rng, 2) 
      test(i) = rng(r, c) 
      i = i + 1 
     Next c 
    Next r 
Else 
    For c = 1 To UBound(rng, 2) 
     For r = 1 To UBound(rng, 1) 
      test(i) = rng(r, c) 
      i = i + 1 
     Next r 
    Next c 
End If 

ArrayDim = test 
End Function 

第二の基準は、それがソートされる方法です。

0 =列

![enter image description here

によって行 1 =列で行
+0

興味深いのは、Excelが行と列で自動的に移動するということです(少なくとも同じ数の両方がある場合)。私はOPがその逆を望むかもしれないと思いますか? – SJR

+0

@SJRはOPがどちらの方法でも決定できるように調整されています。 –

+0

@ Scott Craner - 義務の呼び出しを超えて! – SJR

0

これはおそらく何か?

Function OneDimArray(rng As Excel.Range) As Variant() 

Dim v() As Variant 
Dim b As Boolean 
Dim a() As Variant 
Dim irow As Integer 
Dim icol As Integer 
Dim r As Range 

Set r = Range("a1:c2") 
v = r.Value 

ReDim a(0) 

For icol = 1 To r.Columns.Count 
    For irow = 1 To UBound(v) 
     a(UBound(a)) = v(irow, icol) 
     ReDim Preserve a(UBound(a) + 1) 
    Next irow 
Next icol 

OneDimArray = a 

End Function 
+0

ループのたびにサイズを変更するのではなく、配列を一度サイズ変更することができます。高価になる可能性のある大きな範囲の場合... –

+0

私はあなたが関数に渡される範囲をどこで使うのかわかりません。また、 'Redim A(1からR.rows.count * r.columns.count) 'によって、Memroy heavyであるRedim preserveを使わずに行うことができます。 –

+0

はい、scottですが、私が信じているのは、ユーザーがコーディングしている次に、配列の基底を設定することに関して、それ自身を行うか、それをどうやって行ったかに関して、仕事の一部を自分で行うことができます。それが支払われるとき、私はより多くをする:) –

関連する問題