ブックの他の場所にある動的な名前付き範囲の一部に対応する列見出しを持つExcelのテーブルがあります。たとえば、「10」、「20」などの列見出しと、「NameRange10」、「ExampleRange2」などの動的な名前付き範囲があります。連結して、ExampleRange10を参照するVLookup式を入力します文字列「ExampleRange」と列見出し「10」。これにより、各列の数式に「ExampleRange10」、「ExampleRange20」などを手動で入力する代わりに、テーブルのすべての列に数式を単純に拡張できます。
私はINDIRECT関数を認識しており、過去に名前付き範囲で正常に使用したことがありますが、この場合はdynamic名前付き範囲では機能していないようです。 。これは、動的な名前付き範囲がExcelでどのように定義されるかに関係していると思います(数式バーの左側にある名前付き範囲のドロップダウンには表示されず、VBAにいくつかの興味深いプロパティがあります、 例えば)。動的な名前付き範囲と組み合わせてINDIRECT数式を使用する方法はありますか、それともこの問題を解決する別の方法がありますか?
編集:使用されている正確な式は次のとおりです。
これは主な式です:=VLOOKUP(B2,INDIRECT("ExampleRange"&C1),2,FALSE)
ここで、C1には「10」が含まれ、「ExampleRange10」と呼ばれる動的な名前付き範囲の式は=OFFSET(Sheet1!$F$2,0,0,COUNTA(Sheet1!$F$2:$F$25),2)
です。メインの数式は「#REF!」を返しますが、動的な名前付き範囲の数式を削除し、「ExampleRange10」を静的な範囲として定義すると正しく機能します。
さらに調査を行った後でわかるように、ExcelのINDIRECT
関数はダイナミックレンジでは機能しません。 INDIRECT
を使用してVBA以外のExcelの世界にこだわる賢い方法があるかもしれませんが、私はそのような方法を知りません。代わりに、記述されたものと非常によく似たユーザー定義関数を作成しました here 。メインの数式を=VLOOKUP(B2,DINDIRECT("ExampleRange"&C1),2,FALSE)
に変更しました。ここで、DINDIRECT
は作成したVBA関数の名前です。
この代替方法の唯一の欠点(見方によっては欠点になる場合とそうでない場合があります)は、ブックをマクロ対応のブックとして保存する必要があり、カスタム関数の使用があまり自己文書化されていないことです。他のユーザーへの少しの説明が必要です。とはいえ、すべてが考慮されましたが、これは私にとって許容できる解決策でした。
Link-averseのコードは次のとおりです。
Public Function DINDIRECT(sName As String) As Range
Dim nName As Name
On Error Resume Next
Set nName = ActiveWorkbook.Names(sName)
Set nName = ActiveSheet.Names(sName)
On Error GoTo 0
If Not nName Is Nothing Then
Set DINDIRECT = nName.RefersToRange
Else
DINDIRECT = CVErr(xlErrName)
End Function
注:この解決策は機能しましたが、他の人がより良い解決策を投稿するのを思いとどまらせたくないので、私の答えを受け入れるつもりはありません。また、私はこのサイトを初めて使用するので、自分の質問に答えてエチケットコードを壊してしまった場合は、申し訳ありません...他の人が役立つと思った場合に使用した正確な解決策を共有したいと思いました.
私は最近この正確なレンガの壁にぶつかりました。すでに推測したとおり、答えは動的な名前付き範囲をINDIRECTで参照できないことです。
ただし、ダイナミックレンジの式itselfをINDIRECTの引数として使用できますが、これはやりたいことには役に立ちません。非常に役立つ種類の機能であるため、PITAとは多少異なります。
データに10、20などのヘッダーがある場合は、Indirectを使用する必要はありません。インデックス/マッチを使用して必要なデータを選択しないのはなぜですか?
たとえば、テーブル全体にExampleRangesという名前を付け、次の式を使用します。
Index(ExampleRanges, match(B2, index(ExampleRanges, , 1), 0), match(C1, index(ExampleRanges, 1,), 0))
テストされていませんが、これでうまくいくと思います。
動的に名前が付けられた範囲のアドレスを返すユーザー定義関数:
Function Named_Range_Address(Range_Name As Range, _
Optional SheetName As Boolean) As String
Dim strName As String
Application.Volatile
If SheetName = True Then
strName = "'" & Range_Name.Parent.Name & "'!" & Range_Name.Address
Else
strName = Range_Name.Address
End If
Named_Range_Address = strName
End Function
次に、vlookup式を使用できるようになります。
=VLOOKUP(B2,INDIRECT(named_range_address("ExampleRange"&C1,TRUE)),2,FALSE)
私はこれが本当に古いスレッドであることを知っていますが、私は同じ問題を抱えていたので、おそらく私の解決策は将来人々を助けることができます。
基本的に、保存時に範囲を削除して再定義し、名前を付けるマクロを作成しました。したがって、範囲が動的ではなかったため、INDIRECT関数は機能します。名前付き範囲に値を追加した後、ワークブックを保存するだけです。
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim a, b, c, d, e, f As Integer
Dim data As Worksheet
Set data = ThisWorkbook.Worksheets("Data")
a = data.Range("A" & Rows.count).End(xlUp).row
b = data.Range("B" & Rows.count).End(xlUp).row
c = data.Range("C" & Rows.count).End(xlUp).row
d = data.Range("D" & Rows.count).End(xlUp).row
e = data.Range("E" & Rows.count).End(xlUp).row
f = data.Range("F" & Rows.count).End(xlUp).row
ActiveWorkbook.Names("KP").Delete
ActiveWorkbook.Names("KPT").Delete
ActiveWorkbook.Names("AP").Delete
ActiveWorkbook.Names("APT").Delete
ActiveWorkbook.Names("DISC").Delete
ActiveWorkbook.Names("SEATS").Delete
ActiveWorkbook.Names.Add Name:="KP", RefersTo:="=Data!$A$2:$A$" & a
ActiveWorkbook.Names.Add Name:="KPT", RefersTo:="=Data!$B$2:$B$" & b
ActiveWorkbook.Names.Add Name:="AP", RefersTo:="=Data!$C$2:$C$" & c
ActiveWorkbook.Names.Add Name:="APT", RefersTo:="=Data!$D$2:$D$" & d
ActiveWorkbook.Names.Add Name:="DISC", RefersTo:="=Data!$E$2:$E$" & e
ActiveWorkbook.Names.Add Name:="SEATS", RefersTo:="=Data!$F$2:$F$" & f
End Sub
私はこれがかなり古いことを知っていますが、私はこれに出くわしたばかりで、これに遭遇した他の人を助ける場合に備えて、VBAコーディングを回避するソリューションを追加すると思いました:
=VLOOKUP(B2,CHOOSE(C1/10,example10,example20,example30,example40),2,0)
これは、命名規則が10、20、30などであることを前提としており、数百の範囲には理想的ではありません。
新しいひねりを加えると、アドレス関数と間接関数で名前付き範囲を使用することができます。一連のテーブルに名前付き範囲を設定していて、以下を使用している場合があります。
Named Range: WWDH-FF-PI which points to Linear!$A$19 (first cell in table)
アドレスを取得するには:$ T $ 56:= ADDRESS(MATCH(S56、Linear!A:A、0)、1,1,1、 "Linear")
次に、複数回コピーされたオフセット関数を使用して、ピボットテーブルを作成します。
=OFFSET(INDIRECT($T$56),C5,$T$57-1)
したがって、アドレス関数を間接関数に埋め込んで(またはラップして)、動的セルアドレスを作成できます。
今日、私はExcelの名前付き範囲をいじっていましたが、INDIRECT()
呼び出し自体では範囲の名前を計算できないことは事実ですが、純粋な「Excel-」で取得できることを発見しました。中間ステップを追加することで「方法」:名前付き範囲を計算する非表示のセルを作成するだけです。
たとえば、_A1
_に範囲名の「動的部分」が含まれているとし、_A2
_で式_= "ExampleRange" & A1
_を使用すると、使用できる完全な範囲名が得られます。 = INDIRECT(A2)
として。