2013/06/26

VBアプリケーションからExcelやWordのOfficeファイルを開く方法

Visual BasicアプリケーションからExcelやWordなどOfficeファイルを開く方法をメモ。
本内容はVS2012 & .Net Framework 3.5を用いています。
2013.06.26 コメントでいただいた内容を反映してみました。

方法1 Shell関数を利用する

VBAでおなじみのShell関数を利用してExcelやWordなどOfficeファイルを開きます。
開いたファイルは別プロセスとなります。
Shell 関数 - msdn visual basic

Dim procId As Integer
Dim execPath as String = "c:\xxxxxx\xxx.xlsx"

procId = Shell(execPath, AppWinStyle.NormalFocus)

MSDNのヘルプを見るとVisual Basic 2005/2008となっていますが、Visual Basic 2012でも利用できました。しかし、2012などで利用してもいいかはよく分かりません・・・
2013-06-26_132206

方法2 Processクラスを利用する

Process クラスは.Net Framework 1.1~4.5と幅広く利用できるので、環境が変わっても実行ファイルが動作すると思っています。
開いたファイルは別プロセスとなります。
Process クラス - msdn

Dim officeFileProc As New Process
Dim execPath as String = "c:\xxxxxx\xxx.xlsx"

With officeFileProc
     .StartInfo.FileName = execPath
     .Start()
End With

ProcessクラスにはExistedイベントがあるので外部アプリケーションの終了を待つ事もできます。利用した限りですが、Shell関数よりもProcessクラスを利用した方が使い勝手がいいと感じています。

方法3 COMオブジェクトを利用する

方法1,2を知る前に試したのがCOMオブジェクトを利用した方法です。
利用する前にMicrosoft Excel xxx Object Libraryなどを参照する設定を行います。
2013-06-26_142835

<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
End Function

Dim retWindowFore As Boolean
Dim xlApplication As Excel.Application = New Excel.Application
Dim xlBooks  As Excel.Workbooks

xlBooks = xlApplication.Workbooks
xlBooks.Open(ExcelFile)

xlApplication.Visible = True

'Excel ウィンドウをフォアグラウンド
retWindowFore = SetForegroundWindow(xlApplication.Hwnd)

'終了と解放-2013.06.26 追記分
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
前述の2方法に比べてですが、ExcelやWordをただ起動するだけならば「方法1,2」をおススメします。
理由は
  1. COMオブジェクトを利用し単純にExcelやWordを起動するとExcelやWordはバックグラウンドで起動してしまう
    ※user32.dllをインポートしSetForegroundWindow関数でフォアグランドにする方法で対処しました。(正しい作法かは分かりません・・・)
  2. [VBアプリケーションからExcelやWordを起動→ExcelやWordを終了する]とプロセスが残り、メモリがひっ迫する可能性がある
    2013-06-26_103054
  3. [VBアプリケーションからExcelやWordを起動→VBアプリケーションを終了→ExcelやWordを終了]するとタスクマネージャからプロセスを終了させるしかない
などのデメリットがあり、結局COMオブジェクトよる操作を諦めProcessクラスを利用しました。
当初、上記2,3の動作が全く分かりませんでしたが、わんくま同盟のメンバーさんが運営されている「C#とVB.NETの入門サイト」の
COM オブジェクトの参照カウントを解放する
に明記されている
COM オブジェクトを扱う場合は、参照カウントの解放を意識しなければなりません。使用した COM オブジェクトの参照カウントが、正しくデクリメントされていないと意図したタイミングでプロセスが解放されません。
を再度読み返したところ、動作が理解できました。
COMオブジェクトを使う場合は、意図的に[終了と解放]を使う事が大事なんですね!
インフラもそうですが、アプリケーション開発ももっと深い知識が必要。
日々精進、精進・・・
スポンサーリンク

スポンサーリンク