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

概要

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

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

詳細

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

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

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 データコントロールを追加し、その DatabaseName プロパティをデータベースパスに設定します。 その後、RecordSource をデータベースの既存のテーブルに設定します。 OLE コントロールの DataSource プロパティを使用して、コントロールを Visual Basic データコントロールに連結し、DataField プロパティを、OLE オブジェクトを含む recordset の特定のフィールドを指すように設定します。 Visual Basic では、rest を行います。

  • コンテナーをアクティブにしたときに表示される斜線の枠線のサイズと位置は、オブジェクトのサイズと OLE コントロールで選択したオプションによって決まります。 この罫線は、編集ウィンドウの境界を示すために表示されます。 通常、編集ウィンドウの境界は、OLE コンテナー自体の境界と一致しません。この動作は、OLE オブジェクトに対しては正常です。 編集ウィンドウは、Visual Basic からプログラムで変更することはできません。

  • オートメーションメソッドによっては、オブジェクトが埋め込み先編集が有効になっていないと、正しく動作しないことがあります。 プログラムを使用して 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-左" に設定します。 キャプションを開いたメニュー項目と名前 mnuOpen を作成します。
    6. [OK] をクリックしてメニューエディターを閉じます。
    7. もう一度、アプリケーションを実行し、[作成] ボタンをクリックして、新しい文書を OLE コンテナーに埋め込みます。
    8. OLE コンテナーを右クリックし、[編集] を選択して、その場でオブジェクトをアクティブにします。 Form1 のメニューが、オブジェクトのアプリケーションのメニューに統合されていることに注意してください。

    Visual Basic では、メニュー項目が追加されたときに、メニュー項目の結合や変更を行うことはできません。 ただし、次のようなコードを使用してオートメーションで 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 ドキュメントテクノロジを提供しています。 すべての 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")