Wordの表をExcelにコピー

カテゴリー名: [複数のアプリケーションの連携

2016/10/06

 複数のアプリケーションの連携の例として、
Wordの表をExcelにコピーするケースを取り上げます。

 VBScript(または JScript)で処理する方法と、
ExcelにVBAマクロを組み込む方法を取り上げます。

 関連のファイル一式は vov_multi01.zip に同梱しておきます。


《このページの目次》


    

1. 概要

 Word文書の表をExcelにコピーする方法を取り上げます。

 クリップボードを介して表をコピーしてみます。

 二つのアプリケーションを同時に動かして処理します。

 zip圧縮ファイルに同梱されている test.doc の表をExcelにコピーします。

    

(1) クリップボード経由のコピー&貼り付け

 Word文書から表だけを抽出するのは簡単です。

 変数 Doc にドキュメントオブジェクトが代入されているとき、一つ目の表のオブジェクトを得るには次のようにします。

Set TableObject = Doc.Content.Tables(1)

 そして、この一つの表をクリップボードにコピーするには下のようにします。

TableObject.Range.Copy

 これで、一つの表がまるごとクリップボードにコピーされます。

 あとは Excelの側でPaste(貼り付け)を行うだけです。

    

 貼り付け先のワークシートが SheetObject に代入されている場合、次のようにします。

SheetObject.Activate  ' SheetObjectに焦点を当てる
SheetObject.Range("A1").Select  ' 貼り付け開始位置(A1セル)を選択
SheetObject.Paste  ' クリップボードから貼り付け

 以上がクリップボード経由のコピー&貼り付けの要点です。

 Word文書の各々の表についてこの「コピー&貼り付け」を行います。

目次に戻る


    

(2) VBAで他のアプリケーションを動かすときの「参照設定」

 今回は、Excelの側にVBAマクロを組み込んで、そのマクロの中でWordを起動する形を採ります。

 その場合、Word の Application を扱うための変数 WDapp を次のように宣言します。

Dim WDapp As Word.Application

 しかし、この Word.Application を有効にするには、ある手続きが必要です。

 ExcelのVBAで、Word.Application を使うためには、Excel起動中にVBEを立ち上げて「参照設定」をしなければなりません。

 今回のマクロ(Macro1)が test.xls に組み込まれている場合、test.xlsを開いてから、いきなり Macro1 を実行してもエラーになります。

 test.xls を開いた後で、VBEを立ち上げて、メニューから「参照設定」を選び、Wordにチェックを入れてOKボタンを押すという処理が必要です。

 「参照設定」を行った後で test.xls を保存すれば、次回以降は「参照設定」が必要なくなります。

 といっても、参照設定が有効なのは test.xls についてだけです。他のワークブックで Word.Application を使いたければ、別途「参照設定」が必要になります。

 参照設定したとの情報は、ワークブックに記録されるようです。

    

 VOVシリーズでは極力 手作業を減らして簡単に処理できるようにするのをめざすので、VBEを立ち上げて「参照設定」を手作業でやるのも避けたいところです。

 ということで、test.xls を生成するための GetTableSetMacro.vbs というVBScriptでは、マクロを組み込む他に、参照設定も済ませてしまいます。

 VBScriptの中で参照設定を行う場合、Word用の参照設定ファイル MSWORD.OLB というファイルのフルパスが必要になります。

 Office2010の場合は C:\Program Files\Microsoft Office\Office14\MSWORD.OLB というフルパスです。

 このフルパスの取得を正当派のやりかたでやるのは、自動操作の観点からは厄介です。なので、便法として次の方法を採ることにしました。

    

 DOSプロンプトを開いてから下の2行を実行します。

CD /D "C:\Program Files\Microsoft Office"
dir /b /s MSWORD*.OLB

 そうすると、MSWORD.OLB のフルパスが標準出力に出力されます。

 VBScriptの中で上の処理を実行し、標準出力を捕捉すれば目的達成。

 Office2000までの古いOfficeでは MSWORD9.OLB のようにバージョン番号が入るケースがあるので MSWORD*.OLB というワイルドカードを使っていますが、古いOfficeを使わないのであればワイルドカードにする必要はありません。

 ちなみに、PowerPoint だと MSPPT.OLB、Excelなら EXCEL.EXE です。

 EXCEL.EXE を検索するときに EXCEL*.EXE のようにワイルドカードを使うと、EXCELCNV.EXE などの別のファイルも出てくるので、ワイルドカードを使わない方がいいです。

目次に戻る


    

2. VBScriptによるExcelファイルの作成

 まずは VBScript による処理を掲げます。VBAマクロは用いません。前述の「参照設定」も関係ありません。

 下に掲げる get_table.vbs を実行すると、Word文書(test.doc)の表を Excelファイル(test_doc.xls)に書き出します。

 test_doc.xls を開くと、一つのワークシートに一つの表が書き込まれています。どれもクリップボード経由で貼り付けた表です。

 Excel, Word の二つを動かすのでプログラムが長くなりますが、処理の中核は、クリップボードを介した「コピー&貼り付け」です。

    

△ get_table.vbs

 1' test.docの表をExcelに書き出す
 2Option Explicit
 3Dim FSO, BookName, BookPath, DocName, DocPath
 4Dim EXLapp, WBobj, WSobj
 5Dim WDapp, DOCobj
 6Dim TBLobj, TblCount, i
 7Const xlWorkbookNormal = -4143
 8
 9DocName = "test.doc"
10BookName = Replace(DocName, ".", "_") & ".xls"
11
12Set FSO = CreateObject("Scripting.FileSystemObject")
13BookPath = FSO.GetAbsolutePathName(BookName)
14If (FSO.FileExists(BookPath) = True) Then FSO.DeleteFile(BookPath)
15Set EXLapp = CreateObject("Excel.Application")  ' Excelの起動
16EXLapp.Visible = True  ' Excelを見える状態に
17EXLapp.CutCopyMode = False
18Set WBobj = EXLapp.Workbooks.Add()  ' Workbookの新規作成
19
20DocPath = FSO.GetAbsolutePathName(DocName)
21Set WDapp = CreateObject("Word.Application")  ' Wordの起動
22WDapp.Visible = True  ' Wordを見える状態に
23Set DOCobj = WDapp.Documents.Open(DocPath)  ' Word文書を開く
24
25TblCount = DOCobj.Content.Tables.Count  ' 表の数
26For i = 1 To TblCount
27    Set TBLobj = DOCobj.Content.Tables(i)
28    If WBobj.Worksheets.Count < i Then  ' シート枚数が足りない
29        WBobj.Worksheets.Add ,WBobj.Worksheets(WBobj.Worksheets.Count)
30    End If
31    Set WSobj = WBobj.Worksheets(i)  ' シートの選択
32    WSobj.Activate
33    WSobj.Range("A1").Select  ' シートでの書き出しの始点を選択
34    TBLobj.Range.Copy  ' ワードの表をクリップボードにコピー
35    WSobj.Paste  ' クリップボードから貼り付け
36    EXLapp.CutCopyMode = False
37    WSobj.Range("A1").Select
38Next
39DOCobj.Close
40WDapp.Quit
41If TblCount > 0 Then  ' 表があったのでワークブックを保存
42    WBobj.Worksheets(1).Activate  ' 第1シートに焦点を
43    WBobj.SaveAs BookPath, xlWorkbookNormal
44End If
45WBobj.Close
46EXLapp.Quit

    

 細かな事柄ですが、いくつか捕捉しておきます。

 EXLapp.CutCopyMode = False というのは、切り取り・コピーモードの状態をちゃらにするためのものです。おそらく要らない記述だと思いますが、念のため書きました。

 ユーザーのこれまでの操作によって、クリップボードに何かデータが残っているかもしれません。それが今回のExcelファイルに貼り付けられてしまうと困るので、念のため CutCopyMode を False にしています。

    

 WBobj.Worksheets.Add ,WBobj.Worksheets(WBobj.Worksheets.Count) というのは、ワークシートを1枚追加するための記述です。追加されたシートは、最後のシートになります。

 Word文書に4つ以上の表があるとワークシートが足りなくなります。なので、この記述を入れてあります。

目次に戻る


    

3. VBAマクロとそれを組み込むためのVBScript

 下にVBAマクロを掲げます。

 処理の内容は、前述の get_table.vbs とほぼ同じなのですが、Excelの側に軸足を置いているので印象が違います。

 Word文書(test.doc)は、test.xls と同じフォルダにあるものとして処理しています。

 このVBAマクロは、後述の GetTableSetMacro.vbs によって test.xls に組み込みます。

    

△ GetTableMacro.txt

 1' test.docの全テーブルをExcelブックにコピー
 2Sub Macro1()
 3    Dim DocName As String, DocPath As String
 4    Dim TblCount As Integer, i As Integer
 5    Dim WDapp As Word.Application, DOCobj As Document, TBLobj As Table
 6
 7    DocName = "test.doc"
 8    DocPath = ThisWorkbook.Path & "\" & DocName
 9    Set WDapp = New Word.Application
10    WDapp.Visible = True
11    Set DOCobj = WDapp.Documents.Open(DocPath)  ' Word文書を開く
12    TblCount = DOCobj.Content.Tables.Count  ' 表の数
13    For i = 1 To TblCount
14        Set TBLobj = DOCobj.Content.Tables(i)
15        If Worksheets.Count < i Then  ' シート枚数が足りない
16            Worksheets.Add After:=Worksheets(Worksheets.Count)
17        End If
18        Worksheets(i).Activate
19        ActiveSheet.UsedRange.Clear  ' 念のためシートの全クリア
20        Range("A1").Select  ' シートでの書き出しの始点を選択
21        TBLobj.Range.Copy  ' ワードの表をクリップボードにコピー
22        ActiveSheet.Paste  ' クリップボードから貼り付け
23        Application.CutCopyMode = False
24        Range("A1").Select
25    Next
26    DOCobj.Close
27    WDapp.Quit
28    If TblCount > 0 Then  ' 表があったのでワークブックを保存
29        Worksheets(1).Activate  ' 第1シートに焦点を
30        ActiveWorkbook.Save  ' ワークブックを上書き保存
31    End If
32End Sub

    

 Wordについては最後の方で終了(Quit)していますが、Excelの方はワークブックの保存まで行うものの、終了(Quit)は行っていません。

 繰り返しになりますが、このマクロを実行すると、Wordの表がExcelのワークブックに貼り付けられます。

 次は、このマクロを組み込んで、参照設定も行うVBScriptです。

目次に戻る


    

△ GetTableSetMacro.vbs

 test.xls を生成するためのVBScriptです。

 先の GetTableMacro.txt の内容をマクロとして組み込みます。

 Macro1 には Control + j のショートカットキーを割り当てます。

 なお、このVBScriptを実行するためにはExcelのマクロセキュリティの設定をあらかじめ変更しておく必要があります。設定変更は一度やるだけでOKです。

 ExcelをGUI操作して、マクロのセキュリティに関して次の設定変更を行います。
具体的な操作方法は、Excelのバージョンによって違うのでここでは省略します。

 上記は Excelのセキュリティを緩める処置です。
あまり神経質にならなくてもいいとは思いますが、
気になるようでしたら、VBScriptによるマクロの組込みをやらない時は
セキュリティを強化しておく方がいいかもしれません。

    

 1' Wordを起動するマクロを組み込む
 2Option Explicit
 3Dim FSO, BookName, BookPath
 4Dim EXLapp, WBobj, CPobj
 5Dim DocName, DocPath, RefPath
 6
 7DocName = "test.doc"
 8BookName = "test.xls"
 9RefPath = "C:\Program Files\Microsoft Office\Office14\MSWORD.OLB"
10
11Set FSO = CreateObject("Scripting.FileSystemObject")
12If (FSO.FileExists(RefPath) = False) Then _
13    RefPath = GetRefPath("MSWORD.OLB")
14BookPath = FSO.GetAbsolutePathName(BookName)
15If (FSO.FileExists(BookPath) = True) Then FSO.DeleteFile(BookPath)
16Set EXLapp = CreateObject("Excel.Application")  ' Excelの起動
17EXLapp.Visible = True  ' Excelを見える状態に
18Set WBobj = EXLapp.Workbooks.Add()  ' Workbookの新規作成
19WBobj.VBProject.References.AddFromFile RefPath
20Set CPobj = WBobj.VBProject.VBComponents.Add(1)  ' 標準モジュール追加
21CPobj.CodeModule.AddFromFile(FSO.GetAbsolutePathName("GetTableMacro.txt"))
22EXLapp.MacroOptions "Macro1",,,,True,"j"  ' マクロにShortcutKey割り当て
23WBobj.SaveAs BookPath, -4143
24EXLapp.quit
25
26Function GetRefPath(ByVal WildCard)
27    Dim ShellObj, ExecObj
28    Set ShellObj = CreateObject("WScript.Shell")
29    Set ExecObj = ShellObj.Exec("cmd /c CD /D ""C:\Program Files" & _
30        "\Microsoft Office"" & dir /b /s " & WildCard)
31    Do While ExecObj.Status = 0  ' コマンド実行の終了を待つ
32        WScript.Sleep 100  ' 0.1秒待機
33    Loop
34    GetRefPath = ExecObj.StdOut.ReadLine
35End Function

 WBobj.VBProject.References.AddFromFile RefPath というのが参照設定を行うものです。

 変数 RefPath にはOffice2010用のMSWORD.OLBのフルパスを代入してあります。

 しかし、そのMSWORD.OLBが存在しない場合は、関数 GetRefPath によって適正なフルパスを取得します。

目次に戻る


    

4. JScript

 これまで掲げてきた VBScript と同じ処理を行う JScript を掲載します。

△ get_table.js

 Word文書(test.doc)の表を Excelファイル(test_doc.xls)に書き出します。

 VBAマクロは用いません。

 1// test.docの表をExcelに書き出す
 2var fso, bookName, bookPath, docName, docPath;
 3var ExlApp, wb, ws;
 4var WdApp, docObj;
 5var tblObj, tblCount;
 6var xlWorkbookNormal = -4143;
 7
 8docName = "test.doc";
 9bookName = docName.replace(/\./g, "_") + ".xls";
10
11fso = WScript.CreateObject("Scripting.FileSystemObject");
12bookPath = fso.GetAbsolutePathName(bookName);
13if (fso.FileExists(bookPath))  fso.DeleteFile(bookPath);
14ExlApp = WScript.CreateObject("Excel.Application");  // Excelの起動
15ExlApp.Visible = true;  // Excelを見える状態に
16ExlApp.CutCopyMode = false;
17wb = ExlApp.Workbooks.Add();  // Workbookの新規作成
18
19docPath = fso.GetAbsolutePathName(docName); 
20WdApp = WScript.CreateObject("Word.Application");  // Wordの起動
21WdApp.Visible = true;  // Wordを見える状態に
22docObj = WdApp.Documents.Open(docPath);  // Word文書を開く
23
24tblCount = docObj.Content.Tables.Count;
25for (var i=1; i<=tblCount; i++) {
26    tblObj = docObj.Content.Tables(i);
27    if (wb.Worksheets.Count < i) {  // シート枚数が足りない
28        wb.Worksheets.Add(null, wb.Worksheets(wb.Worksheets.Count));
29    }
30    ws = wb.Worksheets(i);  // シートの選択
31    ws.Activate();
32    ws.Range("A1").Select();  // シートでの書き出しの始点を選択
33    tblObj.Range.Copy();  // ワードの表をクリップボードにコピー
34    ws.Paste();  // クリップボードから貼り付け
35    ExlApp.CutCopyMode = false;
36    ws.Range("A1").Select();
37}
38docObj.Close();
39WdApp.Quit();
40if (tblCount > 0) {  // 表があったのでワークブックを保存
41    wb.Worksheets(1).Activate();  // 第1シートに焦点を
42    wb.SaveAs(bookPath, xlWorkbookNormal);
43}
44wb.Close();
45ExlApp.Quit();

目次に戻る


    

△ GetTableSetMacro.js

 VBAマクロを組み込むためのプログラムです。

 マクロは GetTableMacro.txt に書かれているものとします。

 1// Wordを起動するマクロを組み込む
 2var fso, bookPath, refPath;
 3var ExlApp, wb, CPobj;
 4var refPath = "C:\\Program Files\\Microsoft Office\\Office14\\MSWORD.OLB";
 5
 6fso = WScript.CreateObject("Scripting.FileSystemObject");
 7if (fso.FileExists(refPath) == false)
 8    refPath = getRefPath("MSWORD.OLB");
 9bookPath = fso.GetAbsolutePathName("test.xls");
10if (fso.FileExists(bookPath))  fso.DeleteFile(bookPath);
11ExlApp = WScript.CreateObject("Excel.Application");  // Excelの起動
12ExlApp.Visible = true;  // Excelを見える状態に
13wb = ExlApp.Workbooks.Add();  // Workbookの新規作成
14wb.VBProject.References.AddFromFile(refPath);
15CPobj = wb.VBProject.VBComponents.Add(1);  // 標準モジュール追加
16CPobj.CodeModule.AddFromFile(fso.GetAbsolutePathName("GetTableMacro.txt"));
17ExlApp.MacroOptions("Macro1",null,null,null,true,"j");
18wb.SaveAs(bookPath, -4143);
19ExlApp.Quit();
20
21function getRefPath(wildCard) {
22    var ShellObj, ExecObj;
23    ShellObj = WScript.CreateObject("WScript.Shell");
24    ExecObj = ShellObj.Exec("cmd /c CD /D \"C:\\Program Files" +
25        "\\Microsoft Office\" & dir /b /s " + wildCard);
26    while (ExecObj.Status == 0) {  // コマンド実行の終了を待つ
27        WScript.Sleep(100);  // 0.1秒待機
28    }
29    return ExecObj.StdOut.ReadLine();
30}

目次に戻る


    

5. 参照設定を必要としないVBAマクロ

 参照設定しなくても動くVBAマクロを書くことができます。

 VBScript, JScript でよく用いる CreateObject() を利用します。

 この場合、変数宣言のところでWordに特有の型を用いることはできません。

 前掲の GetTableMacro.txt にある下の記述が使えません。

Dim WDapp As Word.Application, DOCobj As Document, TBLobj As Table

 これを次のように書き換えます。全部 Object型にします。

Dim WDapp As Object, DOCobj As Object, TBLobj As Object

 その上で WDapp の生成を下のようにします。

Set WDapp = CreateObject("Word.Application")

 こうすれば参照設定しなくても動きます。

 他のユーザーにも使ってもらうVBAマクロを書く場合は、このやり方がいいかもしれません。

    

 一方、参照設定した場合は次のような利点があります。

 というようなことがあるので、参照設定するための手間が苦にならないなら、設定した方が便利だといえます。

 念のため、参照設定を必要としないVBAマクロを下に掲げておきます。

    

△ GetTableMacro02.txt

 1' test.docの全テーブルをExcelブックにコピー:参照設定不要
 2Sub Macro1()
 3    Dim DocName As String, DocPath As String
 4    Dim TblCount As Integer, i As Integer
 5    Dim WDapp As Object, DOCobj As Object, TBLobj As Object
 6
 7    DocName = "test.doc"
 8    DocPath = ThisWorkbook.Path & "\" & DocName
 9    Set WDapp = CreateObject("Word.Application")
10    WDapp.Visible = True
11    Set DOCobj = WDapp.Documents.Open(DocPath)  ' Word文書を開く
12    TblCount = DOCobj.Content.Tables.Count  ' 表の数
13    For i = 1 To TblCount
14        Set TBLobj = DOCobj.Content.Tables(i)
15        If Worksheets.Count < i Then  ' シート枚数が足りない
16            Worksheets.Add After:=Worksheets(Worksheets.Count)
17        End If
18        Worksheets(i).Activate
19        ActiveSheet.UsedRange.Clear  ' 念のためシートの全クリア
20        Range("A1").Select  ' シートでの書き出しの始点を選択
21        TBLobj.Range.Copy  ' ワードの表をクリップボードにコピー
22        ActiveSheet.Paste  ' クリップボードから貼り付け
23        Application.CutCopyMode = False
24        Range("A1").Select
25    Next
26    DOCobj.Close
27    WDapp.Quit
28    If TblCount > 0 Then  ' 表があったのでワークブックを保存
29        Worksheets(1).Activate  ' 第1シートに焦点を
30        ActiveWorkbook.Save  ' ワークブックを上書き保存
31    End If
32End Sub

    

〜 以上 〜


VOVシリーズ トップページ