VBAはテーブルやシートを配列に取り込むと高速ですが、配列にアクセスするには数値しか使用できません(私の知る限りでは)
一方で、Excelのテーブルは、テーブル名と列名で列を指定することが出来ます。
なんとかテーブルやRange(範囲)を取り込んだ配列でも列名などの文字で場所を指定できないかと思い、考えました(数字よりも文字の方が他のお方が読んでも分かると思うので)。
レッツ 脱Range、Cells!
Sub テスト()
Dim 辞書 As Variant, ブック As Workbook, ファイルパス As String
'ファイルパスは適せん指定、代入してください
ファイルパス = ~
Set ブック = 開く(ファイルパス)
'Variantで宣言した理由は、arr = 辞書.Items で辞書に登録した値そのものが代入出来るからです
'好きに改変してください
'オブジェクトは 必ず Set (少なくともVBAでは、代わりにletは省略)
Set 辞書 = 辞書に登録する(ブック)
'あとは辞書("テーブル名列名")でテーブルの列のインデックスが指定できます
'以下、解説、テスト用
'bufってなんですか?
Dim 項目 As Variant
For Each 項目 In 辞書.keys
Debug.Print 辞書(項目)
Next 項目
End Sub
Function 開く(ByVal ファイルパス As String) As Workbook
'これはおまけです。Workbook.Open(ReadOnly)が面倒な人向け&ファンクション関数とはなにか?解説用
Set 開く = Workbooks.Open(ファイルパス)
End Function
Function 辞書に登録する(ByVal ブック As Workbook) As Object
'メインテーマ
'辞書を宣言
Dim 辞書 As Object
'辞書を早速代入
Set 辞書 = CreateObject("Scripting.Dictionary")
Dim シート As Worksheet, テーブル As ListObject, テーブルの列 As ListColumn, 辞書の項目 As String
'ブックのすべてのシートをループ
For Each シート In ブック.Sheets
'シートの すべてのテーブルをループ
For Each テーブル In シート.ListObjects
'テーブルのすべての列をループ
For Each テーブルの列 In テーブル.ListColumns
'辞書の項目、エントリー用変数(一般的な解説ではkey)
'テーブル名と列名を使用して重複を回避、一意(ユニーク化)
辞書の項目 = テーブル.Name & テーブルの列.Name
'辞書に登録されていなければ(重複しなければ)
If Not 辞書.Exists(辞書の項目) Then
'辞書に登録、テーブルの列のインデックスを
辞書.Add テーブル.Name & テーブルの列.Name, テーブルの列.Index
End If
Next テーブルの列
Next テーブル
Next シート
'完成した辞書を引き渡す
Set 辞書に登録する = 辞書
End Function
Listobject.Listcolumn("列名").Indexでも指定できますが、
これはテーブルを一つ一つ代入しないといけないので非常に面倒くさいですね。