GetObject(, "Excel~")だけで無く、GetObject(ファイル名)も活用しよう

  • 5
    いいね
  • 1
    コメント

はじめに

GetObject([PathName][, Class])

GetObjectの第1引数指定時の動作を知っておくと、便利な場面もあるという話。

具体例

Excel外部から特定のExcelファイル(例:C:\hoge.xlsx)を操作する場合、以下のような記述をしたとする。

Dim fileName As String
fileName = "C:\hoge.xlsx"

Const XlProgID$ = "Excel.Application"
Dim xlApp As Object 'As Excel.Application

On Error Resume Next
    Set xlApp = VBA.GetObject(, XlProgID)
On Error GoTo 0

If xlApp Is Nothing Then
    Set xlApp = VBA.CreateObject(XlProgID)
End If

Dim myWorkBook As Object 'As Excel.Workbook
Set myWorkBook = xlApp.Workbooks.Open(fileName)

対象のファイルがすでにExcelで開かれているとき、この記述だと以下のような問題が発生する。

  • 2重に開くことになるので存在判定が必要
  • Excelが複数起動している場合、GetObjectで取得したExcelとは別のExcelでファイルが開かれている可能性がある(読み取り専用で開かれる)

GetObject(PathName)を使うと

上の記述はGetObject(PathName)を使用することで以下のようにできる。

Dim fileName As String
fileName = "C:\hoge.xlsx"

Dim myWorkBook As Object 'As Excel.Workbook
Set myWorkBook = VBA.GetObject(fileName)

Dim xlApp As Object 'As Excel.Application
Set xlApp = myWorkBook.Application

GetObject(PathName)の動作(例:Excel)

Excelが起動していない場合

Excelを非表示で起動し、対象のファイルを非表示状態で開く。
開いたファイル(Excel.Workbook)を返す。

Excelが起動しているが、対象のファイルが開かれていない場合

すでに起動しているExcelのインスタンスで、対象のファイルを非表示状態で開く。
開いたファイル(Excel.Workbook)を返す。

Excelが起動していて、対象のファイルが開かれている場合

現在開かれている対象のファイル(Excel.Workbook)を返す。

複数のExcelが起動していても、現在編集中のファイルが捕捉される。

メリット

確実に対象のファイルを捕捉できる。

デメリット

テンプレート(.xltxなど)の場合、新規作成では無くテンプレートそのものを開いてしまう。

インターネット上のファイル(OneDrive上など)にはうまく動作しない。