WordをExcel VBAから使う,まとめ。
今までこれがうまくできなかったのは,一連の作業に今一理解が及ばないからだったんですが,クラスやコレクションを使うようになって,似たようなものなので,以前よりはしっくりくるようになりました。
本当にWordの文書にExcelのデータを流し込むというのは,便利極まりなかったので,そこは記憶から消えないうちに再度きちんとまとめたいと思います。
まずは,自分のパソコンでしか使わないのであれば,参照設定は最強だと思われるので,参照設定を入れましょう。
データを流し込むという意味では,Excel上のVBAから他のアプリを操作するという設定で考えます。
VisualBasicEditorの ツール→参照 から
Microsoft Powerpoint ●.● Object Library やMicrosoft Word ●.● Object Library
を登録します。インテリセンスが効いてくれるので,便利です。
組み終わった後,汎用性を高めるなら,参照設定なしでも動くように作れるので,まずは組みやすさを優先するといいと思います。
さて,ExcelもWordもPowerpointもかなり巨大なクラスモジュールみたいなものだと考えられます。
なので,使い始めは同じような感じになる。それらを放り込むオブジェクト変数を作り,そこに各アプリケーションを参照渡しで入れます。
そして,アクセスしやすいように,
ExcelならWorkbook,WordならDocument,PowerpointならPresentationを入れるオブジェクト変数を作り,これまた参照渡しで入れてあげます。
ExcelからWord文書を開くテストです。ファイルは同じパスにあると仮定して,Excelのパスをthisworkbook.pathで取得して使っています。
ファイル名は直接書き込むのもいいんですが,書き換えやすいように最初あたりで変数に放り込むようにすると,変更部分を最初あたりにかためることができます。
Word.Applicationで宣言して,Newでメモリ上に確保して上げます。この時点でWordはメモリ上にもういるんですが,隠れているのでVisible=Trueで表に出す。
Applicationからいちいち目的のオブジェクトまでいくのはひどく面倒なので,Documentオブジェクトも変数に入れています。
Sub testWord() Dim FileName As String: FileName = ThisWorkbook.Path & "\test.docx" Dim WordApp As Word.Application: Set WordApp = New Word.Application WordApp.Visible = True Dim WordDoc As Word.Document: Set WordDoc = WordApp.Documents.Open(FileName) Stop End Sub
Powerpointの例だと次の感じですね。
Sub testPowerpoint() Dim FileName As String: FileName = ThisWorkbook.Path & "\test.pptx" Dim PowerpointApp As PowerPoint.Application: Set PowerpointApp = New PowerPoint.Application PowerpointApp.Visible = True Dim PptPresen As PowerPoint.Presentation: Set PptPresen = PowerpointApp.Presentations.Open(FileName) Stop End Sub
無駄に,Excelから同じ作法でExcelブックを開いてみると,次の感じ。
Sub testExcel() Dim FileName As String: FileName = ThisWorkbook.Path & "\test2.xlsx" Dim ExcelApp As Excel.Application: Set ExcelApp = New Excel.Application ExcelApp.Visible = True Dim ExcelBook As Excel.Workbook: Set ExcelBook = ExcelApp.Workbooks.Open(FileName) Stop End Sub
Applicationに対して作業を行いたいときと,ファイルにあたるプレゼンやドキュメントに対して作業を行いたいときの両方があるので,
わたしは,いつもこんな感じで他のオフィスアプリを制御するときは2つのオブジェクト変数を必ず使用しています。
ほぼクラスと同じ書き方ですよね。クラスを扱うようになって,ずいぶんしっくりくるようになりました。
ここからは,今回はWordが主の相手なので,Wordに焦点を置きます。
何回かの記事に書いたように,差し込み印刷的な動きを実現するには, 表,テキストボックス,文字置換 の3つの手段を手に入れることで,ほぼ実現可能です。
実際私はそれで今日仕事が成立しました。もっと扱いたいオブジェクトを増やすには,上記のようにStopで止めてローカルウィンドウを見たり,Wordにも記録マクロがありますので,それを利用すればおそらく解決の方法は見つかると思います。
各オブジェクトへのアクセスは以前にも書きましたが,次のような感じでどうでしょう。
'表を制御 表が複数あるならインデックスの数字を変える。 WordDoc.Tables(1).Cell.Range.Text = " ~ " 'テキストボックスを制御 WordDoc.Shapes("シェイプの名前").TextFrame.TextRange.Text = " ~ " '文字置換 WordDoc.Content.Find.Execute findtext:="置換元", ReplaceWith:="置換先" 'ループの使用例 i = 1 Dim SourceString1 As String, SourceString2 As String Dim SourceSht As Worksheet: Set SourceSht = ThisWorkbook.Worksheets("Sheet1") Do SourceString1 = SourceSht.Cells(i, 1) SourceString2 = SourceSht.Cells(i, 2) WordDoc.Content.Find.Execute findtext:="【フィールド1】", ReplaceWith:=SourceString1 WordDoc.Content.Find.Execute findtext:="【フィールド2】", ReplaceWith:=SourceString2 '印刷する WordDoc.PrintOut '元に戻して次の置換に備える。 WordDoc.Content.Find.Execute findtext:=SourceString1, ReplaceWith:="【フィールド1】" WordDoc.Content.Find.Execute findtext:=SourceString2, ReplaceWith:="【フィールド2】" i = i + 1 Loop Until SourceSht.Cells(i, 1) = ""
本日私はこんな感じのループで仕事をしたのですが,
もちろんうまく戻せるように文字を配慮できた場合の使い方になります。簡便さを求めた単純な書き方ですので。
Wordオブジェクトを作ったり開いたりするところにもさっと時間がかかるので,一度開いたらその文書を開いたままどう編集作業を繰り返すかで勝負をしています。
Excelから二つの数値を読み取って, 【フィールド1】等をその文字に置換して, 印刷したら ,次のループで変えれるように 【フィールド1】等に戻しておく。
これをデータがなくなるまで繰り返す,と書いています。
差し込みって基本こんな感じですから,これで私はできました。
Wordを使い倒したら,ドキュメントを閉じて,メモリを解放します。
WordDoc.Close WordApp.Quit
サヨナラ(゚▽゚*)
今この記事を書くために,実際使ってみてたんですが,インテリセンスもきちんと動きますし,とても制御しやすい感じです。参照設定はすばらしい。
ただ,参照設定をしているパソコンでしか動かない状態なので,組み終わったら,汎用性のために,次のように変えてあげる。
'Dim WordApp As Word.Application: Set WordApp = New Word.Application Dim WordApp As Object: Set WordApp = CreateObject("Word.Application") WordApp.Visible = True 'Dim WordDoc As Word.Document: Set WordDoc = WordApp.Documents.Open(FileName) Dim WordDoc As Object: Set WordDoc = WordApp.Documents.Open(FileName)
こうしてあげておけば,参照設定が無くても動きます。
自分のためのメモでもありますが,いかがでしょうか。他のオフィスアプリを制御できるととってもタノシイデスヨ(゚▽゚*)
VBA仲間探索のため,ブログ村に参加しています。
にほんブログ村