Visual C を使用して Microsoft Access を自動化する方法#

概要

この記事では、Microsoft Visual C# 2005 または Microsoft Visual C# .NET を使用して Microsoft Access を自動化する方法を示します。 トピックとサンプル コードでは、次の操作を行う方法について説明します。

  • Access でデータベースを開きます。
  • Access レポートを印刷またはプレビューします。
  • Access フォームを表示および編集します。
  • パスワードで保護されたデータベースを開くとき、またはユーザー レベルのセキュリティがオンになっている場合は、ダイアログ ボックスを使用しないでください。
  • アクセス ランタイムを自動化します。

オートメーションと ADO.NET

開発者は、Automation と Microsoft ADO.NET という 2 つの別個のテクノロジを使用して、Visual C# 2005 または Visual C# .NET から Microsoft Access データベースを操作できます。

ADO.NET は、Access データベース内のテーブルやクエリなどのデータ オブジェクトを操作する場合に推奨されるテクノロジです。 Automation は、Access レポートを印刷したりプレビューしたり、Access フォームを表示したり、Access マクロを呼び出したりする機能など、Microsoft Access アプリケーション固有の機能が必要な場合にのみ使用します。

この記事では、Access を自動化する方法について説明します。 この記事では、ADO.NET については説明しません。 ADO.NET に関する情報については、以下の記事番号をクリックして、Microsoft サポート技術情報の記事を表示してください。

  • 306636 ADO 2005 および Visual C# 2005 を使用するか、ADO.NET と Visual C# .NET を使用してデータベースに接続し、コマンドを実行する方法

  • 314145 Visual C# .NET を使用してデータベースから DataSet オブジェクトを設定する方法

  • 307587 Visual C# 2005 または Visual C# .NET を使用して DataSet オブジェクトからデータベースを更新する方法

Automation はコンポーネント オブジェクト モデル (COM) テクノロジです。 Automation を使用すると、Visual C# .NET などの言語で記述されたアプリケーションは、他のアプリケーションをプログラムで制御できます。 Microsoft Office アプリケーションを自動化すると、実際にはそのアプリケーションのインスタンスをメモリ内で実行し、アプリケーションのオブジェクト モデルを呼び出して、そのアプリケーションでさまざまなタスクを実行します。 Access やその他の Microsoft Office アプリケーションでは、ユーザー インターフェイスを使用して手動で実行できるほぼすべてのアクションを、Automation を使用してプログラムで実行することもできます。

Access では、オブジェクト モデルを使用してこのプログラム機能が公開されます。 オブジェクト モデルは、Access の論理コンポーネントに対応するクラスとメソッドのコレクションです。 Visual C# .NET からオブジェクト モデルにアクセスするには、プロジェクト参照をタイプ ライブラリに設定できます。

オートメーションでの一般的な作業

Access でデータベースを開く

Microsoft Access を自動化する場合は、レポートの印刷などの便利なタスクを実行する前にデータベースを開く必要があります。 自動化している Access のインスタンスでデータベースを開くには、Application オブジェクトの OpenCurrentDatabase または OpenAccessProject メソッドを使用します。 Access で一度に開くことができるデータベースは 1 つだけです。 別のデータベースを操作するには、別のデータベースを開く前に CloseCurrentDatabase メソッドを使用します。

System.Runtime.InteropServices.Marshal.BindToMoniker(<path to database>) メソッドを使用して、Access のインスタンスでデータベースを開くこともできます。 Access のインスタンスでデータベースが既に開かれている場合、BindToMoniker は、そのインスタンスの Application オブジェクトを返します。 それ以外の場合、BindToMoniker は Access の新しいインスタンスを開始し、指定したデータベースを開きます。

OpenCurrentDatabase は、自動化する Access のインスタンスを指定するため、データベースを開く方法として推奨されます。 次のように、データベースの開き方を制御する引数を指定することもできます。

Access.Application oAccess = null;

// Start a new instance of Access for Automation:
oAccess = new Access.ApplicationClass();

// Open a database in exclusive mode:
oAccess.OpenCurrentDatabase(
   "c:\\mydb.mdb", //filepath
   true //Exclusive
   );

Access レポートをプレビューまたは印刷するには、DoCmd オブジェクトの OpenReport メソッドを呼び出します。 OpenReport を呼び出すときに渡す引数の 1 つは、レポートが画面でプレビューされるかどうか、またはプリンターに送信されるかどうかを決定します。

// Preview a report named Sales:
oAccess.DoCmd.OpenReport(
   "Sales", //ReportName
   Access.AcView.acViewPreview, //View
   System.Reflection.Missing.Value, //FilterName
   System.Reflection.Missing.Value //WhereCondition
   );

// Print a report named Sales:
oAccess.DoCmd.OpenReport(
   "Sales", //ReportName
   Access.AcView.acViewNormal, //View
   System.Reflection.Missing.Value, //FilterName
   System.Reflection.Missing.Value //WhereCondition
   );

View 引数によって、レポートが Access に表示されるかどうか、またはプリンターに送信されるかどうかが決まります。 有効な SQL WHERE 句を使用する場合は、WhereCondition 引数でレポートのレコードセットを制限できます (WHERE という単語は使用しません)。System.Reflection.Missing.Value を使用して、省略可能なオブジェクト パラメーターをスキップできることに注意してください。

レポートをプレビューする場合は、画面に Access が表示されるように、アプリケーション オブジェクトの Visible プロパティを設定してください。 この方法で、ユーザーは [アクセス] ウィンドウでレポートを表示できます。

データベース内のレポートまたはその他のオブジェクトを印刷する別の方法があります。 DoCmd オブジェクトの PrintOut メソッドを使用します。 この例では、データベース ウィンドウで Employees という名前のレポートを選択し、PrintOut を呼び出して選択したオブジェクトを印刷します。 PrintOut メソッドを使用すると、Access の [印刷] ダイアログ ボックスに対応する引数を指定できます。

// Select the Employees report in the database window:
oAccess.DoCmd.SelectObject(
   Access.AcObjectType.acReport, //ObjectType
   "Employees", //ObjectName
   true //InDatabaseWindow
   );

// Print 2 copies of the selected object:
oAccess.DoCmd.PrintOut(
   Access.AcPrintRange.acPrintAll, //PrintRange
   System.Reflection.Missing.Value, //PageFrom
   System.Reflection.Missing.Value, //PageTo
   Access.AcPrintQuality.acHigh, //PrintQuality
   2, //Copies
   false //CollateCopies
   );

または、場合によっては、OpenReport メソッドと PrintOut メソッドの両方を使用してレポートを印刷することもできます。 従業員レポートの複数のコピーを印刷し、特定の従業員に対してのみ印刷するとします。 この例では、まず OpenReport を使用してプレビュー モードで Employees レポートを開き、WhereCondition 引数を使用してレコードを特定の従業員に制限します。 次に、PrintOut を使用して、アクティブなオブジェクトの複数のコピーを印刷します。

// Open the report in preview mode using a WhereCondition:
oAccess.DoCmd.OpenReport(
   "Employees", //ReportName
   Access.AcView.acViewPreview, //View
   System.Reflection.Missing.Value, //FilterName
   "[EmployeeID]=1" //WhereCondition
   );

// Print 2 copies of the active object: 
oAccess.DoCmd.PrintOut(
   Access.AcPrintRange.acPrintAll, //PrintRange
   System.Reflection.Missing.Value, //PageFrom
   System.Reflection.Missing.Value, //PageTo
   Access.AcPrintQuality.acHigh, //PrintQuality
   2, //Copies
   false //CollateCopies
   );

// Close the report preview window: 
oAccess.DoCmd.Close(
   Access.AcObjectType.acReport, //ObjectType
   "Employees", //ObjectName
   Access.AcCloseSave.acSaveNo //Save
   );

Access 2002 では、Printer オブジェクトが導入されました。 このオブジェクトを使用すると、以前のバージョンの Access よりも簡単に Access プリンター設定をカスタマイズできます。 Access で Printer オブジェクトを使用してレポートを印刷する例については、以下の記事番号をクリックして、Microsoft サポート技術情報の記事を表示します。

284286 Application.Printer オブジェクトの変更をリセットする方法

アクセス フォームを表示および編集する

Visual C# .NET には、非常に強力なフォーム機能があります。 ただし、以前に Access で開発されたフォームをユーザーに表示させる場合があります。 または、Access データベースにクエリまたはレポートの条件を提供するフォームがあり、レポートをプレビューまたは印刷する前にそのフォームを開く必要があります。 Access フォームを開いて表示するには、DoCmd オブジェクトの OpenForm メソッドを呼び出します。

// Show a form named Employees:
oAccess.DoCmd.OpenForm(
   "Employees", //FormName
   Access.AcFormView.acNormal, //View
   System.Reflection.Missing.Value, //FilterName
   System.Reflection.Missing.Value, //WhereCondition
   Access.AcFormOpenDataMode.acFormPropertySettings, //DataMode
   Access.AcWindowMode.acWindowNormal, //WindowMode
   System.Reflection.Missing.Value //OpenArgs
   );

これで、フォームのコントロールを編集できるようになりました。

[アクセス セキュリティ] ダイアログ ボックス

Access を自動化すると、データベースを開こうとすると、ユーザー名またはパスワードまたはその両方を入力するように求められる場合があります。 ユーザーが間違った情報を入力すると、コードにエラーが発生します。 これらのダイアログ ボックスを回避し、代わりにプログラムによってユーザー名とパスワードを指定して、Automation コードが中断なく実行されるようにしたい場合があります。

Microsoft Access には、パスワードで保護されたデータベースとワークグループ ファイル (System.mdw) によるユーザー レベルのセキュリティという 2 種類のセキュリティがあります。 パスワードで保護されたデータベースを開こうとすると、データベースパスワードの入力を求めるダイアログ ボックスが表示されます。 ユーザー レベルのセキュリティは、パスワードで保護されたデータベースとは異なります。 ユーザー レベルのセキュリティがアクティブ化されると、ユーザーが Access で任意のデータベースを開く前に、ユーザー名とパスワードの両方を入力するように求めるログオン ダイアログ ボックスが表示されます。

[データベース パスワードの回避] ダイアログ ボックス

パスワードで保護されているデータベースを開く場合は、OpenCurrentDatabase メソッドにパスワードを指定することで、ダイアログ ボックスを回避できます。

// Open a password-protected database in shared mode:
// Note: The bstrPassword argument is case-sensitive
oAccess.OpenCurrentDatabase(
   "c:\\mydb.mdb", //filepath
   false, //Exclusive
   "MyPassword" //bstrPassword
   );

oAccess が以前にデータベースを開かない Access のインスタンスに設定されている例を次に示します。 このコードは、ダイアログ ボックスを回避するためにデータベースにパスワードを提供します。

string sDBPassword = "MyPassword"; //database password
DAO._DBEngine oDBEngine = oAccess.DBEngine;
DAO.Database oDB = oDBEngine.OpenDatabase("c:\\mydb.mdb",
   false, false, ";PWD=" + sDBPassword);
oAccess.OpenCurrentDatabase("c:\\mydb.mdb", false);
oDB.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDB);
oDB = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDBEngine);
oDBEngine = null;

oDB.Close は実際には Access のデータベースを閉じません。 DBEngine オブジェクトを介して作成されたデータベースへの DAO 接続のみが閉じられます。 OpenCurrentDatabase メソッドを使用した後は、DAO 接続は不要になります。 oDB オブジェクトと oDBEngine オブジェクトを解放するコードに注目してください。 コードの完了後に Access が正しく終了するように、これらのオブジェクトを使用する必要があります。

[アクセス セキュリティ ログオンの回避] ダイアログ ボックス

Access でユーザー レベルのセキュリティが有効になっている場合、ログオン ダイアログ ボックスが表示され、ユーザー名とパスワードの両方を入力するように求められます。 Access オブジェクト モデルを使用して、ユーザー名とパスワードを指定することはできません。 そのため、Access を自動化するときにログオン ダイアログ ボックスを回避する場合は、最初にMsaccess.exe ファイルを起動し、/user および /pwd コマンド ライン スイッチを指定してユーザー名とパスワードを指定する必要があります。 その後、GetActiveObject または BindToMoniker を使用して、実行中の Access インスタンスの Application オブジェクトを取得して、Automation を続行できます。

アクセス ランタイムの自動化

Microsoft Office Developer Edition には、Microsoft Office Developer Tools (MOD) が含まれています。 MOD を使用すると、Access 開発者は Access アプリケーションを作成し、製品版の Access を持たないユーザーに配布できます。 ユーザーが製品版の Access を持たないコンピューターに Access アプリケーションをインストールすると、ランタイム バージョンの Access がインストールされます。 Access ランタイムがインストールされ、製品版と同様に登録されます。 実行可能ファイルはMsaccess.exeとも呼ばれます。 Access ランタイムを使用すると、Access アプリケーションをクライアント コンピューターで実行できますが、Access ランタイムでは、ユーザーが新しいアプリケーションを開発したり、既存のアプリケーションの設計を変更したりすることはできません。

Access ランタイムは、データベースで開始する必要があります。 この要件のため、Access ランタイムを自動化する場合は、Msaccess.exeを開始し、開くデータベースを指定する必要があります。 GetActiveObject または BindToMoniker を使用して Application オブジェクトを取得した後、Access ランタイムを自動化できます。 Access ランタイムを自動化しようとしたときにこの方法を使用しない場合、インスタンスをインスタンス化しようとすると、次のようなエラー メッセージが表示されます。

System.Runtime.InteropServices.COMException (0x80080005) サーバーの実行に失敗しました。

完全なサンプル Visual C# 2005 または Visual C# .NET プロジェクトを作成する

次のステップ バイ ステップ サンプルを使用するには、Northwind サンプル データベースがインストールされていることを確認します。 既定では、Microsoft Access 2000 では、次のパスにサンプル データベースがインストールされます。

C:\Program Files\Microsoft Office\Office\Samples

Microsoft Access 2002 では、次のパスが使用されます。

C:\Program Files\Microsoft Office\Office10\Samples

Microsoft Office Access 2003 では、次のパスが使用されます。

C:\Program Files\Microsoft\Office\Office11\Samples

Northwind サンプル データベースが Access 2002 または Access 2003 にインストールされていることを確認するには、[ヘルプ] メニューの [サンプル データベース] をクリックし、[Northwind サンプル データベース] をクリックします。

  1. 現在実行中の Access のすべてのインスタンスを閉じます。

  2. Microsoft Visual Studio .NET を起動します。

  3. [ファイル] メニューの [新規] をクリックし、[プロジェクト] をクリックします。 Visual C# プロジェクトの種類から Windows アプリケーションを選択します。 既定では、Form1 が作成されます。

    メモ Visual Studio 2005 でコードを変更する必要があります。 既定では、Visual C# は、Windows フォーム プロジェクトを作成するときに、1 つのフォームをプロジェクトに追加します。 フォームは Form1 という名前です。 フォームを表す 2 つのファイルは、Form1.cs と Form1.designer.cs という名前です。 Form1.cs でコードを記述します。 Form1.designer.cs ファイルは、Windows フォーム デザイナーがツールボックスからコントロールをドラッグ アンド ドロップすることによって実行したすべてのアクションを実装するコードを記述する場所です。

    Visual C# 2005 のWindows フォーム デザイナーの詳細については、次の Microsoft Developer Network (MSDN) Web サイトを参照してください。https://msdn.microsoft.com/en-us/library/ms173077.aspx

  4. Microsoft Access オブジェクト ライブラリへの参照を追加します。 これを行うには、次の手順を実行します。

    1. [ プロジェクト] メニューの [ 参照の追加] をクリックします。
    2. [COM] タブで、Microsoft Access オブジェクト ライブラリを探し、[選択] をクリックします。

    メモ Visual Studio 2005 で。 [選択] をクリックする必要はありません。

    メモ Microsoft Office 2003 には、プライマリ相互運用機能アセンブリ (PIA) が含まれています。 Microsoft Office XP には PIA は含まれていませんが、ダウンロードできます。

  5. [参照の追加] ダイアログ ボックスで、[OK] をクリックして選択内容を受け入れます。

    メモ Access 10.0 オブジェクト ライブラリを参照していて、参照を追加しようとしたときにエラーが発生した場合。

  6. [表示] メニューの [ツールボックス] をクリックしてツールボックスを表示します。

  7. 5 つのラジオ ボタン コントロールと 1 つのボタン コントロールを Form1 に追加します。

  8. すべてのラジオ ボタン コントロールを選択し、Size プロパティを 150,24 に設定します。

  9. Form Load イベントと Button コントロールの Click イベントのイベント ハンドラーを追加します。

    1. Form1.cs のデザイン ビューで、Form1 をダブルクリックします。

      Form の Load イベントのハンドラーが作成され、Form1.cs に表示されます。

    2. [表示] メニューの [デザイナー] をクリックしてデザイン ビューに切り替えます。

    3. Button1 をダブルクリックします。

      ボタンの Click イベントのハンドラーが作成され、Form1.cs に表示されます。

  10. Form1.cs で、次のコードを置き換えます

    private void Form1_Load(object sender, System.EventArgs e)
    {
    
    }
    
    private void button1_Click(object sender, System.EventArgs e)
    {
    
    } 
    

    置換後:

          private string msAction = null;
          // Commonly-used variable for optional arguments:
          private object moMissing = System.Reflection.Missing.Value;
    
    private void Form1_Load(object sender, System.EventArgs e)
          {
             radioButton1.Text = "Print report";
             radioButton2.Text = "Preview report";
             radioButton3.Text = "Show form";
             radioButton4.Text = "Print report (Security)";
             radioButton5.Text = "Preview report (Runtime)";
             button1.Text = "Go!";
             radioButton1.Click += new EventHandler(RadioButtons_Click);
             radioButton2.Click += new EventHandler(RadioButtons_Click);
             radioButton3.Click += new EventHandler(RadioButtons_Click);
             radioButton4.Click += new EventHandler(RadioButtons_Click);
             radioButton5.Click += new EventHandler(RadioButtons_Click);
          }
    
    private void RadioButtons_Click(object sender, System.EventArgs e)
          {
             RadioButton radioBtn = (RadioButton) sender;
             msAction = radioBtn.Text;
          }
    
    private void button1_Click(object sender, System.EventArgs e)
          {
             // Calls the associated procedure to automate Access, based
             // on the selected radio button on the form.
             switch(msAction)
             {
                case "Print report": Print_Report();
                   break;
                case "Preview report": Preview_Report();
                   break;
                case "Show form": Show_Form();
                   break;
                case "Print report (Security)": Print_Report_Security();
                   break;
                case "Preview report (Runtime)": Preview_Report_Runtime();
                   break;
             }
          }
    
    private void NAR(object o)
          {
             // Releases the Automation object.
             try // use try..catch in case o is not set
             {
                Marshal.ReleaseComObject(o);
             }
             catch{}
          }
    
    private Access.Application ShellGetDB(string sDBPath, string sCmdLine,
             ProcessWindowStyle enuWindowStyle, int iSleepTime)
          {
             //Launches a new instance of Access with a database (sDBPath)
             //using System.Diagnostics.Process.Start. Then, returns the
             //Application object via calling: BindToMoniker(sDBPath). Returns
             //the Application object of the new instance of Access, assuming that
             //sDBPath is not already opened in another instance of Access. To
             //ensure the Application object of the new instance is returned, make
             //sure sDBPath is not already opened in another instance of Access
             //before calling this function.
             // 
             //Example:
             //Access.Application oAccess = null;
             //oAccess = ShellGetDB("c:\\mydb.mdb", null,
             //  ProcessWindowStyle.Minimized, 1000);
    
    Access.Application oAccess = null;
             string sAccPath = null; //path to msaccess.exe
             Process p = null;
    
    // Enable exception handler:
             try
             {
                // Obtain the path to msaccess.exe:
                sAccPath = GetOfficeAppPath("Access.Application", "msaccess.exe");
                if (sAccPath == null)
    
    {
                   MessageBox.Show("Can't determine path to msaccess.exe");
                   return null;
                }
    
    // Make sure specified database (sDBPath) exists:
                if(!System.IO.File.Exists(sDBPath))
                {
                   MessageBox.Show("Can't find the file '" + sDBPath + "'");
                   return null;
                }
    
    // Start a new instance of Access passing sDBPath and sCmdLine:
                if(sCmdLine == null)
                   sCmdLine = @"""" + sDBPath + @"""";
                else
                   sCmdLine = @"""" + sDBPath + @"""" + " " + sCmdLine;
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = sAccPath;
                startInfo.Arguments = sCmdLine;
                startInfo.WindowStyle = enuWindowStyle;
                p = Process.Start(startInfo);
                p.WaitForInputIdle(60000); //max 1 minute wait for idle input state
    
    // Move focus back to this form. This ensures that Access
                // registers itself in the ROT:
                this.Activate();
    
    // Pause before trying to get Application object:
                System.Threading.Thread.Sleep(iSleepTime);
    
    // Obtain Application object of the instance of Access
                // that has the database open:
                oAccess = (Access.Application) Marshal.BindToMoniker(sDBPath);
                return oAccess;
             }
             catch(Exception e)
             {
                MessageBox.Show(e.Message);
                // Try to quit Access due to an unexpected error:
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
                return null;
             }
          }
    
    private Access.Application ShellGetApp(string sCmdLine,
             ProcessWindowStyle enuWindowStyle)
          {
             //Launches a new instance of Access using System.Diagnostics.
             //Process.Start then returns the Application object via calling:
             //GetActiveObject("Access.Application"). If an instance of
             //Access is already running before calling this function,
             //the function may return the Application object of a
             //previously running instance of Access. If this is not
             //desired, then make sure Access is not running before
             //calling this function, or use the ShellGetDB()
             //function instead. Approach based on Q316125.
             // 
             //Examples:
             //Access.Application oAccess = null;
             //oAccess = ShellGetApp("/nostartup",
             //  ProcessWindowStyle.Minimized);
             // 
             //-or-
             // 
             //Access.Application oAccess = null;
             //string sUser = "Admin";
             //string sPwd = "mypassword";
             //oAccess = ShellGetApp("/nostartup /user " + sUser + "/pwd " + sPwd,
             //  ProcessWindowStyle.Minimized);
    
    Access.Application oAccess = null;
             string sAccPath = null; //path to msaccess.exe
             Process p = null;
             int iMaxTries = 20; //max GetActiveObject attempts before failing
             int iTries = 0; //GetActiveObject attempts made
    
    // Enable exception handler:
             try
             {
                // Obtain the path to msaccess.exe:
                sAccPath = GetOfficeAppPath("Access.Application", "msaccess.exe");
                if(sAccPath == null)
                {
                   MessageBox.Show("Can't determine path to msaccess.exe");
                   return null;
                }
    
    // Start a new instance of Access passing sCmdLine:
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = sAccPath;
                startInfo.Arguments = sCmdLine;
                startInfo.WindowStyle = enuWindowStyle;
                p = Process.Start(startInfo);
                p.WaitForInputIdle(60000); //max 1 minute wait for idle input state
    
    // Move focus back to this form. This ensures that Access
                // registers itself in the ROT:
                this.Activate();
    
    tryGetActiveObject:
                // Enable exception handler:
                try
                {   
                   // Attempt to use GetActiveObject to reference a running
                   // instance of Access:
                   oAccess = (Access.Application)
                      Marshal.GetActiveObject("Access.Application");
                }
                catch
                {
                   //GetActiveObject may have failed because enough time has not
                   //elapsed to find the running Office application. Wait 1/2
                   //second and retry the GetActiveObject. If you try iMaxTries
                   //times and GetActiveObject still fails, assume some other
                   //reason for GetActiveObject failing and exit the procedure.
                   iTries++;
                   if(iTries < iMaxTries)
                   {
                      System.Threading.Thread.Sleep(500); //wait 1/2 second
                      this.Activate();
                      goto tryGetActiveObject;
                   }
                   MessageBox.Show("Unable to GetActiveObject after " +
                      iTries + " tries.");
                   return null;
                }
    
    // Return the Access Application object:
                return oAccess;
             }
             catch(Exception e)
             {
                MessageBox.Show(e.Message);
                // Try to quit Access due to an unexpected error:
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
                return null;
             }
          }
    
    private string GetOfficeAppPath(string sProgId, string sEXE)
          {
             //Returns path of the Office application. e.g.
             //GetOfficeAppPath("Access.Application", "msaccess.exe") returns
             //full path to Microsoft Access. Approach based on Q240794.
             //Returns null if path not found in registry.
    
    // Enable exception handler:
             try
             {
                Microsoft.Win32.RegistryKey oReg = 
                   Microsoft.Win32.Registry.LocalMachine;
                Microsoft.Win32.RegistryKey oKey = null;
                string sCLSID = null;
                string sPath = null;
                int iPos = 0;
    
    // First, get the clsid from the progid from the registry key
                // HKEY_LOCAL_MACHINE\Software\Classes\<PROGID>\CLSID:
                oKey = oReg.OpenSubKey(@"Software\Classes\" + sProgId + @"\CLSID");
                sCLSID = oKey.GetValue("").ToString();
                oKey.Close();
    
    // Now that we have the CLSID, locate the server path at
                // HKEY_LOCAL_MACHINE\Software\Classes\CLSID\ 
                // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx}\LocalServer32:
                oKey = oReg.OpenSubKey(@"Software\Classes\CLSID\" + sCLSID +
                   @"\LocalServer32");
                sPath = oKey.GetValue("").ToString();
                oKey.Close();
    
    // Remove any characters beyond the exe name:
                iPos = sPath.ToUpper().IndexOf(sEXE.ToUpper()); // 0-based position
                sPath = sPath.Substring(0, iPos + sEXE.Length);
                return sPath.Trim();
             }
             catch
             {
                return null;
             }
          }
    
    private void Print_Report()
          {
             // Prints the "Summary of Sales by Year" report in Northwind.mdb.
    
    Access.Application oAccess = null;
             string sDBPath = null; //path to Northwind.mdb
             string sReport = null; //name of report to print
    
    // Enable exception handler:
             try
             {
                sReport = "Summary of Sales by Year";
    
    // Start a new instance of Access for Automation:
                oAccess = new Access.ApplicationClass();
    
    // Determine the path to Northwind.mdb:
                sDBPath = oAccess.SysCmd(Access.AcSysCmdAction.acSysCmdAccessDir,
                   moMissing, moMissing).ToString();
                sDBPath = sDBPath + @"Samples\Northwind.mdb";
    
    // Open Northwind.mdb in shared mode:
                oAccess.OpenCurrentDatabase(sDBPath, false, "");
                // If using Access 10.0 object library, use this instead:
                //oAccess.OpenCurrentDatabase(sDBPath, false, null);
    
    // Select the report name in the database window and give focus
                // to the database window:
                oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);
    
    // Print the report:
                oAccess.DoCmd.OpenReport(sReport,
                   Access.AcView.acViewNormal, moMissing, moMissing, 
                   Access.AcWindowMode.acWindowNormal, moMissing);
                // If using Access 10.0 object library, use this instead:
                //oAccess.DoCmd.OpenReport(sReport,
                //  Access.AcView.acViewNormal, moMissing, moMissing,
                //  Access.AcWindowMode.acWindowNormal, moMissing);
             }
             catch(Exception e)
             {
                MessageBox.Show(e.Message);
             }
             finally
             {
                // Release any Access objects and quit Access:
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
             }
          }
    
    private void Preview_Report()
          {
             // Previews the "Summary of Sales by Year" report in Northwind.mdb.
    
    Access.Application oAccess = null;
             Access.Form oForm = null;
             string sDBPath = null; //path to Northwind.mdb
             string sReport = null; //name of report to preview
    
    // Enable exception handler:
             try
             {
                sReport = "Summary of Sales by Year";
    
    // Start a new instance of Access for Automation:
                oAccess = new Access.ApplicationClass();
    
    // Make sure Access is visible:
                if(!oAccess.Visible) oAccess.Visible = true;
    
    // Determine the path to Northwind.mdb:
                sDBPath = oAccess.SysCmd(Access.AcSysCmdAction.acSysCmdAccessDir,
                   moMissing, moMissing).ToString();
                sDBPath = sDBPath + @"Samples\Northwind.mdb";
    
    // Open Northwind.mdb in shared mode:
                oAccess.OpenCurrentDatabase(sDBPath, false, "");
                // If using Access 10.0 object library, use this instead:
                //oAccess.OpenCurrentDatabase(sDBPath, false, null);
    
    // Close any forms that Northwind may have opened:
                while(oAccess.Forms.Count > 0)
                {   
                   oForm = oAccess.Forms[0];
                   oAccess.DoCmd.Close(Access.AcObjectType.acForm,
                      oForm.Name, Access.AcCloseSave.acSaveNo);
                   NAR(oForm);
                   oForm = null;
                }
    
    // Select the report name in the database window and give focus
                // to the database window:
                oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);
    
    // Maximize the Access window:
                oAccess.RunCommand(Access.AcCommand.acCmdAppMaximize);
    
    // Preview the report:
                oAccess.DoCmd.OpenReport(sReport,
                   Access.AcView.acViewPreview, moMissing, moMissing, 
                   Access.AcWindowMode.acWindowNormal, moMissing);
                // If using Access 10.0 object library, use this instead:
                //oAccess.DoCmd.OpenReport(sReport,
                //  Access.AcView.acViewPreview, moMissing, moMissing,
                //  Access.AcWindowMode.acWindowNormal, moMissing);
    
    // Maximize the report window:
                oAccess.DoCmd.Maximize();
    
    // Hide Access menu bar:
                oAccess.CommandBars["Menu Bar"].Enabled = false;
                // Also hide NorthWindCustomMenuBar if it is available:
                try
                {
                   oAccess.CommandBars["NorthwindCustomMenuBar"].Enabled = false;
                }
                catch{}
    
    // Hide Report's Print Preview menu bar:
                oAccess.CommandBars["Print Preview"].Enabled = false;
    
    // Hide Report's right-click popup menu:
                oAccess.CommandBars["Print Preview Popup"].Enabled = false;
    
    // Release Application object and allow Access to be closed by user:
                if(!oAccess.UserControl) oAccess.UserControl = true;
                NAR(oAccess);
                oAccess = null;
             }
             catch(Exception e)
             {
                MessageBox.Show(e.Message);
                // Release any Access objects and quit Access due to error:
                NAR(oForm);
                oForm = null;
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
             }
          }
    
    private void Show_Form()
          {
             // Shows the "Customer Labels Dialog" form in Northwind.mdb
             // and manipulates controls on the form.
    
    Access.Application oAccess = null;
             Access.Form oForm = null;
             Access.Controls oCtls = null;
             Access.Control oCtl = null;
             string sDBPath = null; //path to Northwind.mdb
             string sForm = null; //name of form to show
    
    // Enable exception handler:
             try
             {
                sForm = "Customer Labels Dialog";
    
    // Start a new instance of Access for Automation:
                oAccess = new Access.ApplicationClass();
    
    // Make sure Access is visible:
                if(!oAccess.Visible) oAccess.Visible = true;
    
    // Determine the path to Northwind.mdb:
                sDBPath = oAccess.SysCmd(Access.AcSysCmdAction.acSysCmdAccessDir,
                   moMissing, moMissing).ToString();
                sDBPath = sDBPath + @"Samples\Northwind.mdb";
    
    // Open Northwind.mdb in shared mode:
                oAccess.OpenCurrentDatabase(sDBPath, false, "");
                // If using Access 10.0 object library, use this instead:
                //oAccess.OpenCurrentDatabase(sDBPath, false, null);
    
    // Close any forms that Northwind may have opened:
                while(oAccess.Forms.Count > 0)
                {   
                   oForm = oAccess.Forms[0];
                   oAccess.DoCmd.Close(Access.AcObjectType.acForm,
                      oForm.Name, Access.AcCloseSave.acSaveNo);
                   NAR(oForm);
                   oForm = null;
                }
    
    // Select the form name in the database window and give focus
                // to the database window:
                oAccess.DoCmd.SelectObject(Access.AcObjectType.acForm, sForm, true);
    
    // Show the form:
                oAccess.DoCmd.OpenForm(sForm, Access.AcFormView.acNormal, moMissing,
                   moMissing, Access.AcFormOpenDataMode.acFormPropertySettings,
                   Access.AcWindowMode.acWindowNormal, moMissing);
    
    // Use Controls collection to edit the form:
    
    oForm = oAccess.Forms[sForm];
                oCtls = oForm.Controls;
    
    // Set PrintLabelsFor option group to Specific Country:
    
    oCtl = (Access.Control)oCtls["PrintLabelsFor"];
                object[] Parameters = new Object[1];
                Parameters[0] = 2; //second option in option group
                oCtl.GetType().InvokeMember("Value", BindingFlags.SetProperty,
                   null, oCtl, Parameters);
                NAR(oCtl);
                oCtl = null;
    
    // Put USA in the SelectCountry combo box:
                oCtl = (Access.Control)oCtls["SelectCountry"];
                Parameters[0] = true;
                oCtl.GetType().InvokeMember("Enabled", BindingFlags.SetProperty,
                   null, oCtl, Parameters);
                oCtl.GetType().InvokeMember("SetFocus", BindingFlags.InvokeMethod,
                   null, oCtl, null);
                Parameters[0] = "USA";
                oCtl.GetType().InvokeMember("Value", BindingFlags.SetProperty,
                   null, oCtl, Parameters);
                NAR(oCtl);
                oCtl = null;
    
    // Hide the Database Window:
                oAccess.DoCmd.SelectObject(Access.AcObjectType.acForm, sForm, true);
                oAccess.RunCommand(Access.AcCommand.acCmdWindowHide);
    
    // Set focus back to the form:
                oForm.SetFocus();
    
    // Release Controls and Form objects:       
                NAR(oCtls);
                oCtls = null;
                NAR(oForm);
                oForm = null;
    
    // Release Application object and allow Access to be closed by user:
                if(!oAccess.UserControl) oAccess.UserControl = true;
                NAR(oAccess);
                oAccess = null;
             }
             catch(Exception e)
             {
                MessageBox.Show(e.Message);
                // Release any Access objects and quit Access due to error:
                NAR(oCtl);
                oCtl = null;
                NAR(oCtls);
                oCtls = null;
                NAR(oForm);
                oForm = null;
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
             }
          }
    
    private void Print_Report_Security()
          {
             //Shows how to automate Access when user-level
             //security is enabled and you wish to avoid the logon
             //dialog asking for user name and password. In this
             //example we're assuming default security so we simply
             //pass the Admin user with a blank password to print the
             //"Summary of Sales by Year" report in Northwind.mdb.
    
    Access.Application oAccess = null;
             string sDBPath = null; //path to Northwind.mdb
             string sUser = null; //user name for Access security
             string sPwd = null; //user password for Access security
             string sReport = null; //name of report to print
    
    // Enable exception handler:
             try
             {
                sReport = "Summary of Sales by Year";
    
    // Determine the path to Northwind.mdb:
                sDBPath = GetOfficeAppPath("Access.Application", "msaccess.exe");
                if(sDBPath == null)
                {
                   MessageBox.Show("Can't determine path to msaccess.exe");
                   return;
                }
                sDBPath = sDBPath.Substring(0, sDBPath.Length - "msaccess.exe".Length)
                   + @"Samples\Northwind.mdb";
                if(!System.IO.File.Exists(sDBPath))
                {
                   MessageBox.Show("Can't find the file '" + sDBPath + "'");
                   return;
                }
    
    // Specify the user name and password for the Access workgroup
                // information file, which is used to implement Access security.
                // Note: If you are not using the system.mdw in the default
                // location, you may include the /wrkgrp command-line switch to
                // point to a different workgroup information file.
                sUser = "Admin";
                sPwd = "";
    
    // Start a new instance of Access with user name and password:
                oAccess = ShellGetDB(sDBPath, "/user " + sUser + " /pwd " + sPwd,
                   ProcessWindowStyle.Minimized, 1000);
                //or
                //oAccess = ShellGetApp(@"""" + sDBPath + @"""" + 
                //  " /user " + sUser + " /pwd " + sPwd,
                //  ProcessWindowStyle.Minimized);
    
    // Select the report name in the database window and give focus
                // to the database window:
                oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);
    
    // Print the report:
                oAccess.DoCmd.OpenReport(sReport,
                   Access.AcView.acViewNormal, moMissing, moMissing,
                   Access.AcWindowMode.acWindowNormal, moMissing );
                // If using Access 10.0 object library, use this instead:                       
                //oAccess.DoCmd.OpenReport(sReport,
                //  Access.AcView.acViewNormal, moMissing, moMissing,
                //  Access.AcWindowMode.acWindowNormal, moMissing);
             }
             catch(Exception e)
             {   
                MessageBox.Show(e.Message);
             }
             finally
             {
                // Release any Access objects and quit Access:
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
             }
          }
    
    private void Preview_Report_Runtime()
          {
             //Shows how to automate the Access Runtime to preview
             //the "Summary of Sales by Year" report in Northwind.mdb.
    
    Access.Application oAccess = null;
             Access.Form oForm = null;
             string sDBPath = null; //path to Northwind.mdb
             string sReport = null; //name of report to preview
    
    // Enable exception handler:
             try
             {
                sReport = "Summary of Sales by Year";
    
    // Determine the path to Northwind.mdb:
                sDBPath = GetOfficeAppPath("Access.Application", "msaccess.exe");
                if(sDBPath == null)
                {
                   MessageBox.Show("Can't determine path to msaccess.exe");
                   return;
                }
    
    sDBPath = sDBPath.Substring(0, sDBPath.Length - "msaccess.exe".Length)
                   + @"Samples\Northwind.mdb";
                if(!System.IO.File.Exists(sDBPath))
                {
                   MessageBox.Show("Can't find the file '" + sDBPath + "'");
                   return;
                }
    
    // Start a new instance of Access with a database. If the
                // retail version of Access is not installed, and only the
                // Access Runtime is installed, launches a new instance
                // of the Access Runtime (/runtime switch is optional):
                oAccess = ShellGetDB(sDBPath, "/runtime",
                   ProcessWindowStyle.Minimized, 1000);
                //or
                //oAccess = ShellGetApp(@"""" + sDBPath + @"""" + " /runtime",
                //  ProcessWindowStyle.Minimized);
    
    // Make sure Access is visible:
                if(!oAccess.Visible) oAccess.Visible = true;
    
    // Close any forms that Northwind may have opened:
                while(oAccess.Forms.Count > 0)
                {   
                   oForm = oAccess.Forms[0];
                   oAccess.DoCmd.Close(Access.AcObjectType.acForm,
                      oForm.Name, Access.AcCloseSave.acSaveNo);
                   NAR(oForm);
                   oForm = null;
                }
    
    // Select the report name in the database window and give focus
                // to the database window:
                oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);
    
    // Maximize the Access window:
                oAccess.RunCommand(Access.AcCommand.acCmdAppMaximize);
    
    // Preview the report:
                oAccess.DoCmd.OpenReport(sReport,
                   Access.AcView.acViewPreview, moMissing, moMissing,
                   Access.AcWindowMode.acWindowNormal, moMissing );
                // If using Access 10.0 object library, use this instead:
                //oAccess.DoCmd.OpenReport(sReport,
                //  Access.AcView.acViewPreview, moMissing, moMissing,
                //  Access.AcWindowMode.acWindowNormal, moMissing);
    
    // Maximize the report window:
                oAccess.DoCmd.Maximize();
    
    // Hide Access menu bar:
                oAccess.CommandBars["Menu Bar"].Enabled = false;
                // Also hide NorthWindCustomMenuBar if it is available:
                try
                {
                   oAccess.CommandBars["NorthwindCustomMenuBar"].Enabled = false;
                }
                catch{}
    
    // Release Application object and allow Access to be closed by user:
                if(!oAccess.UserControl) oAccess.UserControl = true;
                NAR(oAccess);
                oAccess =  null;
             }
             catch(Exception e)
             {
                MessageBox.Show(e.Message);
                // Release any Access objects and quit Access due to error:
                NAR(oForm);
                oForm = null;
                try // use try..catch in case oAccess is not set
                {
                   oAccess.Quit(Access.AcQuitOption.acQuitSaveNone);
                }
                catch{}
                NAR(oAccess);
                oAccess = null;
             }
          }
    
    
  11. Form1.cs の Using ディレクティブに次のコードを追加します。

    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Reflection; 
    
  12. F5 キーを押してビルドし、プログラムを実行します。 Form1 が表示されます。

  13. [レポートの印刷] をクリックし、[移動] をクリックします。 Print_Report プロシージャは、Northwind データベースからレポートを出力します。

  14. [レポートのプレビュー] をクリックし、[Go!] をクリックします。 Preview_Reportプロシージャは、Northwind データベースからレポートをプレビューします。 続行する準備ができたら、Access インスタンスを閉じます。

  15. [フォームの表示] をクリックし、[移動] をクリックします。 Show_Formプロシージャには、Northwind データベースの [顧客ラベル] ダイアログ ボックス フォームが表示されます。 また、フォームのオプション グループを "特定の国" に設定し、一覧から [USA] を選択します。 続行する準備ができたら、Access インスタンスを閉じます。

  16. [レポートの印刷 (セキュリティ)] をクリックし、[Go!] をクリックします。 Print_Report_Security手順では、Access を自動化する方法と、ユーザー レベルのセキュリティがオンになっている場合にログオン ダイアログ ボックスを回避する方法を示します。 この例では、空のパスワードでユーザー 管理を渡して既定のログオンを想定します。 その後、コードは Northwind データベースにレポートを出力します。

  17. [プレビュー レポート (ランタイム)] をクリックし、[Go!] をクリックします。 Preview_Report_Runtime手順では、Access ランタイムを自動化して、Northwind データベースでレポートをプレビューする方法を示します。 製品版の Access がインストールされている場合でも、手順は正しく動作します。 続行する準備ができたら、Access のインスタンスを閉じます。

関連情報

詳細については、次の MSDN Web サイト「Visual Studio https://msdn.microsoft.com/en-us/library/aa188489(office.10).aspxを使用した Microsoft Office Development」を参照してください。詳細については、次の記事番号をクリックして、Microsoft サポート技術情報の記事を表示してください。

Visual Studio .NET クライアントからの自動化後に Office アプリケーションが終了しない317109

316126 Visual C# を使用して Office プログラムの実行中のインスタンスを自動化する方法