Visual Basic を使用して Office ドキュメントを埋め込んで自動化する方法

概要

Office ドキュメント内のデータを使用するアプリケーションを開発する場合、ユーザーが Office アプリケーションに切り替えることなくデータを表示および編集できるように、そのデータを Visual Basic アプリケーション内に直接表示することが有益な場合があります。 これは、OLE コンテナー コントロールを使用して Visual Basic で行うことができます。

この記事では、OLE コンテナー コントロールを使用して Office ドキュメントを動的に作成および自動化する方法について説明します。

詳細情報

Office ドキュメントを Visual Basic に挿入する機能は、Microsoft の Object Linking and Embedding (OLE) テクノロジによって可能になります。 OLE は、エンド ユーザーにとって便利な方法で、あるアプリケーションが別のアプリケーションに属するオブジェクトをホストできるように設計されていますが、関係するアプリケーションが他のアプリケーションの内部の詳細を知る必要はありません。 Visual Basic には、Visual Basic プログラマがフォームに OLE オブジェクトを追加できるようにする OLE コンテナー コントロールが用意されています。

オブジェクトが埋め込まれると、ほとんどの OLE サーバーは Automation をサポートし、ホスト アプリケーションがプログラムによってコードからオブジェクトを変更または操作できるようにします。 Automation オブジェクトへの参照を取得するには、OLE コンテナーの Object プロパティを使用します。 このプロパティは、埋め込まれた特定の項目と密接に一致する Automation オブジェクトを返します。

Excel ブックをホストする Visual Basic アプリケーションを作成する

  1. Visual Basic を起動し、新しい標準プロジェクトを作成します。 Form1 は既定で作成されます。

  2. コントロール ツールボックスから、Form1 に 3 つのコマンド ボタンを追加します。 次に、OLE コンテナー コントロールのインスタンスを追加します。 OLE コンテナー コントロールがフォームに配置されると、挿入するオブジェクトの種類を確認するメッセージが表示されます。 このサンプルでは、オブジェクトを動的に追加する必要があるため、[キャンセル] をクリックして、オブジェクトを追加せずにダイアログを閉じます。

  3. Form1 の [コード] ウィンドウで、次のコードを追加します。

    Option Explicit
    
    Dim oBook As Object
    Dim oSheet As Object
    
    Private Sub Command1_Click()
       On Error GoTo Err_Handler
    
    ' Create a new Excel worksheet...
       OLE1.CreateEmbed vbNullString, "Excel.Sheet"
    
    ' Now, pre-fill it with some data you
     ' can use. The OLE.Object property returns a
     ' workbook object, and you can use Sheets(1)
     ' to get the first sheet.
       Dim arrData(1 To 5, 1 To 5) As Variant
       Dim i As Long, j As Long
    
    Set oBook = OLE1.object
       Set oSheet = oBook.Sheets(1)
    
    ' It is much more efficient to use an array to
     ' pass data to Excel than to push data over
     ' cell-by-cell, so you can use an array.
    
    ' Add some column headers to the array...
       arrData(1, 2) = "April"
       arrData(1, 3) = "May"
       arrData(1, 4) = "June"
       arrData(1, 5) = "July"
    
    ' Add some row headers...
       arrData(2, 1) = "John"
       arrData(3, 1) = "Sally"
       arrData(4, 1) = "Charles"
       arrData(5, 1) = "Toni"
    
    ' Now add some data...
       For i = 2 To 5
          For j = 2 To 5
             arrData(i, j) = 350 + ((i + j) Mod 3)
          Next j
       Next i
    
    ' Assign the data to Excel...
       oSheet.Range("A3:E7").Value = arrData
    
    oSheet.Cells(1, 1).Value = "Test Data"
       oSheet.Range("B9:E9").FormulaR1C1 = "=SUM(R[-5]C:R[-2]C)"
    
    ' Do some auto formatting...
       oSheet.Range("A1:E9").Select
       oBook.Application.Selection.AutoFormat
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "An error occurred: " & Err.Description, vbCritical
    End Sub
    
    Private Sub Command2_Click()
       On Error GoTo Err_Handler
    
    ' Create an embedded object using the data
     ' stored in Test.xls.<?xm-insertion_mark_start author="v-thomr" time="20070327T040420-0600"?> If this code is run in Microsoft Office
     ' Excel 2007, <?xm-insertion_mark_end?><?xm-deletion_mark author="v-thomr" time="20070327T040345-0600" data=".."?><?xm-insertion_mark_start author="v-thomr" time="20070327T040422-0600"?>change the file name to Test.xlsx.<?xm-insertion_mark_end?>
       OLE1.CreateEmbed "C:\Test.xls"
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "The file 'C:\Test.xls' does not exist" & _
              " or cannot be opened.", vbCritical
    End Sub
    
    Private Sub Command3_Click()
       On Error Resume Next
    
    ' Delete the existing test file (if any)...
       Kill "C:\Test.xls"
    
    ' Save the file as a native XLS file...
       oBook.SaveAs "C:\Test.xls"
       Set oBook = Nothing
       Set oSheet = Nothing
    
    ' Close the OLE object and remove it...
       OLE1.Close
       OLE1.Delete
    
    Command1.Enabled = True
       Command2.Enabled = True
       Command3.Enabled = False
    End Sub
    
    Private Sub Form_Load()
       Command1.Caption = "Create"
       Command2.Caption = "Open"
       Command3.Caption = "Save"
       Command3.Enabled = False
    End Sub
    
    
  4. F5 キーを押してプログラムを実行します。 [作成] ボタンをクリックします。 これにより、新しいワークシートが埋め込まれており、Excel を自動化してシートに直接データを追加します。 オブジェクトをダブルクリックするとインプレースがアクティブ化され、ユーザーはデータを直接編集できることに注意してください。 次に、[保存] をクリックしてデータをファイルに保存し、OLE オブジェクトを閉じます。 [開く] ボタンを使用すると、以前に保存したファイルのコピーを開くことができます。

Word 文書をホストする Visual Basic アプリケーションを作成する

  1. Visual Basic を起動し、新しい標準プロジェクトを作成します。 Form1 は既定で作成されます。

  2. コントロール ツールボックスから、Form1 に 3 つのコマンド ボタンを追加します。 次に、OLE コンテナー コントロールのインスタンスを追加します。 OLE コンテナー コントロールがフォームに配置されると、挿入するオブジェクトの種類を確認するメッセージが表示されます。 このサンプルでは、オブジェクトを動的に追加する必要があるため、[キャンセル] をクリックして、オブジェクトを追加せずにダイアログを閉じます。

  3. Form1 の [コード] ウィンドウで、次のコードを追加します。

    Option Explicit
    
    Dim oDocument As Object
    
    Private Sub Command1_Click()
       On Error GoTo Err_Handler
    
    ' Create a new Word Document...
       OLE1.CreateEmbed vbNullString, "Word.Document"
    
    ' Add some text to the document. The OLE.Object
     ' property returns the document object...
       Set oDocument = OLE1.object
    
    oDocument.Content.Select
       With oDocument.Application.Selection
    
    ' Add a heading at the top of the document...
          .Style = oDocument.Styles("Heading 1")
          .Font.Color = &HFF0000
          .TypeText "Blue Sky Airlines"
          .ParagraphFormat.Alignment = 1 '[wdAlignParagraphCenter]
          .TypeParagraph
          .TypeParagraph
    
    ' Now add some text...
          .TypeText "Dear Mr. Smith,"
          .TypeParagraph
          .TypeParagraph
          .TypeText "Thank you for your interest in our current fares " & _
                    "from Oakland to Sacramento. We guarantee to be " & _
                    "the lowest price for local flights, or we'll " & _
                    "offer to make your next flight FREE!"
          .TypeParagraph
          .TypeParagraph
          .TypeText "The current fare for a flight leaving Oakland " & _
                    "on October 4, 1999 and arriving in Sacramento " & _
                    "the same day is $54.00."
          .TypeParagraph
          .TypeParagraph
          .TypeText "We hope you will choose to fly Blue Sky Airlines."
          .TypeParagraph
          .TypeParagraph
          .TypeText "Sincerely,"
          .TypeParagraph
          .TypeParagraph
          .TypeParagraph
          .TypeText "John Taylor"
          .TypeParagraph
          .Font.Italic = True
          .TypeText "Regional Sales Manager"
          .TypeParagraph
    
    End With
    
    ' Zoom to see entire document...
       OLE1.SizeMode = 3
       OLE1.DoVerb -1
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "An error occurred: " & Err.Description, vbCritical
    End Sub
    
    Private Sub Command2_Click()
       On Error GoTo Err_Handler
    
    ' Create an embedded object using the data
     ' stored in Test.doc.<?xm-insertion_mark_start author="v-thomr" time="20070327T040719-0600"?> If this code is run in Microsoft Office
     ' Word 2007, change the file name to Test.docx.<?xm-insertion_mark_end?><?xm-deletion_mark author="v-thomr" time="20070327T040717-0600" data=".."?>
       OLE1.CreateEmbed "C:\Test.doc"
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "The file 'C:\Test.doc' does not exist" & _
              " or cannot be opened.", vbCritical
    End Sub
    
    Private Sub Command3_Click()
       On Error Resume Next
    
    ' Delete the existinf test file (if any)...
       Kill "C:\Test.doc"
    
    ' Save the file as a native Word DOC file...
       oDocument.SaveAs "C:\Test.doc"
       Set oDocument = Nothing
    
    ' Close the OLE object and remove it...
       OLE1.Close
       OLE1.Delete
    
    Command1.Enabled = True
       Command2.Enabled = True
       Command3.Enabled = False
    End Sub
    
    Private Sub Form_Load()
       Command1.Caption = "Create"
       Command2.Caption = "Open"
       Command3.Caption = "Save"
       Command3.Enabled = False
    End Sub
    
    
  4. F5 キーを押してプログラムを実行します。 [作成] ボタンをクリックします。 これにより、新しいドキュメントが埋め込まれており、Word を自動化してドキュメントに直接データを追加します。 オブジェクトをダブルクリックするとインプレースがアクティブ化され、ユーザーはデータを直接編集できることに注意してください。 次に、[保存] をクリックしてデータをファイルに保存し、OLE オブジェクトを閉じます。 [開く] ボタンを使用すると、以前に保存したファイルのコピーを開くことができます。

OLE コンテナーを使用する場合の考慮事項

  • 既存のファイルから埋め込む場合、OLE コンテナー内に表示されるデータは、ファイル上のデータのコピーです。 加えた変更は、自動的に同じファイルに保存されません。 上記のような手法を使用して結果を特定のファイルに保存できますが、すべての OLE サーバーがこの機能をサポートしているわけではありません。 通常の OLE オブジェクトの動作とは見なされません。

  • ファイルに "リンク" している場合、そのオブジェクトをインプレースでアクティブ化することはできません。 代わりに、ユーザーがオブジェクトをダブルクリックすると、サーバー アプリケーションのウィンドウでオブジェクトが開きます。 埋め込みオブジェクトのみをインプレースでアクティブ化できます。

  • OLE コンテナー コントロールは、データ バインドに対応しています。 Access 97 または Access 2000 データベースがある場合は、データベース内の OLE オブジェクト フィールドにコントロールをバインドできます。 フォームが表示されると、データがデータベースからプルされ、ユーザーが編集できるように表示されます。 ユーザーが行った編集変更は、OLE オブジェクトが閉じられると自動的にデータベースに保存されます。

    OLE コンテナー コントロールのデータ バインドを作成するには、Visual Basic Data コントロールを追加し、DatabaseName プロパティをデータベース パスに設定します。 次に、RecordSource をデータベース内の既存のテーブルに設定します。 OLE コントロールの DataSource プロパティを使用してコントロールを Visual Basic Data コントロールにバインドし、OLE オブジェクトを含むレコードセット内の特定のフィールドを指すように DataField プロパティを設定します。 残りは Visual Basic によって行われます。

  • コンテナーがインプレース アクティブになったときに表示されるハッチ付き罫線のサイズと位置は、オブジェクトのサイズと OLE コントロールで選択されているオプションによって決まります。 編集ウィンドウの境界をマークするために、この罫線が表示されます。 多くの場合、編集ウィンドウの境界は OLE コンテナー自体の境界と一致しません。この動作は OLE オブジェクトでは通常どおりです。 Visual Basic から編集ウィンドウをプログラムで変更することはできません。

  • 一部の Automation メソッドは、オブジェクトがインプレース アクティブにされていない限り、正しく動作しない場合があります。 OLE オブジェクトをプログラムでアクティブ化するには、DoVerb メソッドを使用し、動詞として vbOLEShow (-1) を指定します。

  • フォームの NegotiateMenus プロパティを設定することで、リンクオブジェクトまたは埋め込みオブジェクトのメニューがコンテナー フォームに表示されるかどうかを判断できます。 子フォームの NegotiateMenus プロパティが True に設定され、コンテナーにメニュー バーが定義されている場合、オブジェクトがアクティブ化されると、オブジェクトのメニューがコンテナーのメニュー バーに配置されます。 コンテナーにメニュー バーがない場合、または NegotiateMenus プロパティが False に設定されている場合、オブジェクトのメニューはアクティブ化されても表示されません。 NegotiateMenus プロパティは MDI フォームには適用されないため、MDI フォームのメニューをアクティブ化されたオブジェクトのメニューとマージできないことに注意してください。 メニュー ネゴシエーションを説明するには、前のセクションで作成したサンプル アプリケーションを使用して、次の手順を試してください。

    1. アプリケーションを実行し、[作成] ボタンをクリックして OLE コンテナーに新しいドキュメントを埋め込みます。
    2. OLE コンテナーを右クリックし、[編集] を選択して、オブジェクトをインプレース アクティブ化します。 Form1 の NegotiateMenus プロパティが既定で True に設定されているため、オブジェクトのアプリケーションのメニューが表示されることに注意してください。
    3. フォームを閉じて、アプリケーションを終了します。
    4. Form1 が選択された状態で、[ツール] メニューの [メニュー エディター] をクリックします。
    5. キャプションファイルと mnuFile という名前の新しいトップレベル メニューを作成します。 このメニューの NegotiatePosition プロパティを "1-Left" に設定します。[開く] というキャプションと mnuOpen という名前のメニュー項目を作成します。
    6. [OK] をクリックしてメニュー エディターを閉じます。
    7. もう一度、アプリケーションを実行し、[作成] ボタンをクリックして新しいドキュメントを OLE コンテナーに埋め込みます。
    8. OLE コンテナーを右クリックし、[編集] を選択して、オブジェクトをインプレース アクティブ化します。 Form1 のメニューがオブジェクトのアプリケーションのメニューとマージされていることに注意してください。

    Visual Basic では、メニューのマージ プロセスを制御したり、追加されたときにサーバーのメニュー項目を変更したりすることはできません。 ただし、Automation を使用して Office アプリケーションのメニューを変更または変更するには、次のようなコードを使用します。

     ' This code disables the Insert|Object item on the merged menu...
       Dim oMenuBar As Object
       Set oMenuBar = oBook.Application.CommandBars("Worksheet Menu Bar")
       oMenuBar.Controls("&Insert").Controls("&Object...").Enabled = False
    
    

    オブジェクトをインプレース アクティブにする前に、一部の変更を加える必要がある場合があることに注意してください。そうしないと、マージされたメニューに変更が表示されない可能性があります。

    メモ この箇条書きは、Microsoft Office Excel 2007 または Microsoft Office Word 2007 には適用されません。

  • Visual Basic では、現在、ツール バー領域の割り当てはサポートされていません。 したがって、ドッキングされたツール バーは、通常、オブジェクトがアクティブ化されたときには表示されません。 ただし、オートメーションを使用してフローティング ツール ウィンドウを表示できる場合があります。

       OLE1.DoVerb -1 '[vbOLEShow]
       With oBook.Application.CommandBars("Standard")
          .Position = 4 '[msoBarFloating]
          .Visible = True
       End With
    
    

    メモ この箇条書きは、Microsoft Office Excel 2007 または Microsoft Office Word 2007 には適用されません。

  • オブジェクトを常にインプレース アクティブにしておく必要があるプログラムの場合、Microsoft は ActiveX Documents テクノロジを提供しています。 すべての OLE サーバーが ActiveX ドキュメント サーバーであるわけではありません。Microsoft Word、Microsoft Excel、および Microsoft PowerPoint は ActiveX ドキュメント サーバーです。

    Visual Basic では、ActiveX ドキュメントをホストするためのネイティブ コントロールはサポートされていません。 ただし、Internet Explorer (バージョン 3.0 以降) に付属する WebBrowser コントロールでは、この形式のインプレースコンテインメントがサポートされています。 このコントロールを使用して、Office ドキュメントを ActiveX ドキュメントとして開く場合があります。 WebBrowser コントロールの使用の詳細については、次の記事を参照してください。

    243058 WebBrowser コントロールを使用して Office ドキュメントを開く方法

  • OLE コンテナーの SaveToFile メソッドは、OLE コンテナーで開くことができるファイルを作成します。 ただし、OLE コンテナーの SaveToFile メソッドで保存されたファイルは、対応する Office アプリケーションで直接開くことはできません。 埋め込みドキュメントをディスクに保存して、ターゲット アプリケーションでドキュメントを開く場合は、アプリケーションの document SaveAs メソッドを使用します。

    OLE1.object.SaveAs ("C:\MyNewFile.doc")