投稿者 魔界の仮面弁士  (社会人) 投稿日時 2013/5/11 23:38:35
> 結論から申しますと、次のコードで動きました:
良かったですね。

ただ、そのコードを見る限り、お使いの Visual Basic 2010 には
Service Pack が適用されていないように見受けられます。
最新の環境に更新するために、Microsoft Update を実行しておいてください。


> ・.NET より Office をコントロールするのに PIA が必要:
PIA (Primary Interop Assembly) が無くても一応動かせますが、
あった方が良いですね。


> 当初は、どこに記述されているのか?で
> 魔界の仮面弁士さんの意図が不明でしたが
> 今回読み直してわかりました。「4.Excelの操作」ですね。

管理人さん宛:
 長文の記事では、該当記事へのリンクを shokyu/standard44.htm#hoge などと
 紹介できるように、h1 タグのところに id 付きの a タグを入れてあると
 便利かと思います。今後作成される記事にてご一考ください。


> ご指摘の通り wdApp.Visible = True が記述されていないことによるものでした。
Word をプログラムから操作した際には、[Ctrl]+[Shift]+[ESC}等で
「タスクマネージャー」を起動して、『プロセス』タブに winword.exe が
残ってしまっていないかを確認しておいた方が良いでしょう。

これは、プログラムの不具合(表示し忘れ、終了操作漏れ、解放処理の不足など)により、
ワードが画面上に表示されていないまま、裏に残り続けてしまうことがあるためです。


> Dim wdApp As Microsoft.Office.Interop.Word.Application
> wdApp = CreateObject("Word.Application")
> Dim wdDoc = wdApp.Documents.Open("E:\Test.docx")
> wdApp.Visible = True

できることならば、Documents も変数に受けておくことが望ましいです。
具体的にはこんな感じ。
'Imports System.Runtime.InteropServices 
Dim wdApp As New Microsoft.Office.Interop.Word.Application()
wdApp.Visible = True
Dim wdDocs = wdApp.Documents    '◀◀◀ Documents オブジェクトを変数に受ける 
Dim wdDoc = wdDocs.Open("E:\Test.docx")
MsgBox("文書を閉じます。", vbInformation Or vbSystemModal)
wdDoc.Close(False)    '文書を閉じる。 
Marshal.ReleaseComObject(wdDoc)    '◁◁◁ 後始末 
Marshal.ReleaseComObject(wdDocs)   '◁◁◁ 後始末 
wdApp.Quit()    'ワードを終了させる。 
Marshal.ReleaseComObject(wdApp)    '◁◁◁ 後始末 
MsgBox("Wordを終了させました。", vbInformation Or vbSystemModal)


System.Runtime.InteropServices 名前空間の Marshal.ReleaseComObject メソッドは、
COM オブジェクトを使い終わった後の、解放処理(≠開放処理)に使われます。
これをさぼると、winword.exe が非表示で裏に残ってしまうなどの
弊害が出ることがあるので注意してください。

ただ、この COM の解放作業というものは、慣れないうちは分かりにくいですし、
比較的面倒な処理です。自動解放の仕組みもあるので、個人利用のコードなら
明示的解放をさぼってしまうのもアリですが、もしも業務利用の開発だとすれば
即時解放しないと都合が悪い場合も多いので、ReleaseComObject についても
追って習得しておくことをお奨めします。


> 現在上記のように参照設定されていますが、正しいでしょうか?
Word 2010 を参照設定して操作する場合、以下の「いずれか」を使ってください。
両方を同時に参照設定しないようご注意を。

(1).NET タブの "Microsoft.Office.Interop.Word" バージョン 14.0
(2) COM タブの "Microsoft Word 14.0 Object Library"


まず (1) ですが、この本体は、Microsoft.Office.Interop.Word.dll です。
既定のインストール先は、
C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop.Word\14.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Word.dll
ですが、C:\Windows\assembly\ は特殊なフォルダーなので、
エクスプローラーからだと、上記までのパスを表示することはできません。


一方、(2) の本体は、MSWORD.OLB というファイルです。ただしこれは
型情報を持っているだけのライブラリであり、.NET の DLL ではありません。

実際にはレジストリに記載された型情報をもとにして PIA が参照されるため、
結局は Microsoft.Office.Interop.Word.dll に行きつくことになります。
ついでに Microsoft.Office.Core.dll や Microsoft.Vbe.Interop.dll も
参照設定に加わりますので、この点が (1) との違いですね。


なお、PIA がインストールされていない場合、(1)は一覧に載りません。
(2) を選んだ場合は、代わりに IA が自動生成されることになりますが、
この場合、生成されるファイル名は Interop.Excel.DLL となり、
使用する名前空間も変わってきます。


> 参照設定にリストされていないのはOKでしょうか

ソリューションエクスプローラーのツリーに掲載されているものが
COM の参照設定の画面に現れる項目名と一致しないのは、
参照設定画面に表示されているものが、「コンポーネント名」であるためです。

COM タブに表示される「コンポーネント名」は、レジストリに
記録されている文字列となります。今回の場合で言うと、
HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}\8.5
の箇所に相当します。

一方、ツリーに表示されている方は、参照しているファイルの
「アセンブリの短縮名」なので、必ずしも同じ名前とはなりません。
一つのコンポーネントが、複数のファイルへの参照情報を持っていることもありますし。