ExcelのINDIRECT関数は、同じブック内にある複数のシートの値を抽出する場合には有効ですが、他のブックの値を抽出する場合は用途が限定されます。
具体的には、他のブックを参照している場合 (これを外部参照と言うようです)、そのブックを事前に開いておく必要があります。参照先のブックを開いていないと、エラー値 #REF! が返される仕様。
複数のブックのセルから数個ずつ、セルの値を抽出したいような場合はPowerQueryも設定が手間となるので、Excelの数式として利用できるユーザー定義関数で対応できないかを検討した備忘録。
なお、使用のExcelは、Microsoft® Excel® for Microsoft 365 MSOです。
結果、処理速度が非常に遅いユーザー定義関数しかできなかったので、Excelの数式としてではなく、VBAで処理するのがよさそう。
処理が遅い要因は、ユーザー定義関数では、数式の一つずつで「ファイルを開く、読み取り、閉じる」を繰り返すような方法しか不明だった。ユーザー定義関数でなければ高速化の余地はある。また、良い方法が探せなかっただけで、他に良い方法があるかも知れません。
内容:
実現したいこと
Excelの数式にユーザー定義関数を追加し、①ファイル名(フルパス)、②シート名、③セル番地 を指定すれば、当該のセルの値を抽出できるようにしたい。
要は、ファイルを開いていなくても外部参照できるINDIRECT関数のような関数。
参考にした情報
以下のサイトを参考にさせていただきました。
調べた内容
Workbooks.Openを使った方法
実現はできるが、一つの値取得に数秒かかるので、用途に適さなかった。
Function 他のブックの値取得WorkbooksOpen(フルパス As String, シート名 As String, セル番地 As String) As Variant Dim result As Variant Dim xlApp As Object Dim xlBook As Object Dim xlSheet As Object Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.Workbooks.Open(フルパス) Set xlSheet = xlBook.Sheets(シート名) result = xlSheet.Range(セル番地).Value xlBook.Close xlApp.Quit Set xlSheet = Nothing Set xlBook = Nothing Set xlApp = Nothing 他のブックの値取得 = result End Function
ExecuteExcel4Macroを使った方法
実現はできるが、Workbooks.Openを使った方法と同様に、一つの値取得に数秒かかるので、用途に適さなかった。
また、詳細未確認だが、Excelの数式として利用できるユーザー定義関数とするには、CreateObject("Excel.Application")が必要で、Excel起動の時間を要する。
(Subからの呼び出しならCreateObject("Excel.Application")が不要だった)
Function 他のブックの値取得Excel4Macro(フルパス As String, シート名 As String, セル番地 As String) As Variant Dim xlApp As Object Set xlApp = CreateObject("Excel.Application") Dim result As Variant Dim 参照文字列 As String Dim ファイル位置 As Long Dim RCセル番地 As String ファイル位置 = InStrRev(フルパス, "\") ファイル名 = Mid(フルパス, ファイル位置 + 1) RCセル番地 = "R" & Range(セル番地).Row & "C" & Range(セル番地).Column 参照文字列 = "'" & Left(フルパス, ファイル位置) & "[" & ファイル名 & "]" & シート名 & "'!" & RCセル番地 result = xlApp.ExecuteExcel4Macro(参照文字列) xlApp.Quit Set xlApp = Nothing 他のブックの値取得Excel4Macro = result End Function
なお、ExecuteExcel4Macroの詳細は以下です。
Formulaを使った方法
セルに、外部参照(リンク)を入力する方法での取得を試みたが、ユーザー定義関数ではできなさそう(エラーとなる)。勝手なイメージでしかないが、セルの編集中にExcelの他の操作ができないような挙動で、途中で処理が止まっている。
Evaluateを使った方法
Formulaでエラーになったので、Evaluateを試す。Evaluateは、セルに入れる数式を文字列としてVBAで実行できるので試してみたが、こちらはINDIRECT関数と同様に、他のブックを事前に起動しておく必要があり、用途に適さない。
ということで、処理速度が非常に遅いユーザー定義関数しかできなかった(探せなかった)という備忘録でした。
参考
INDIRECT関数で、複数シートのデータ抽出をする方法は次のとおりです。