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

概要

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

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

オートメーションおよび ADO.NET

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

ADO.NET は、Access データベースのテーブルやクエリなどのデータオブジェクトを操作する場合に推奨されるテクノロジです。 オートメーションを使用するのは、Microsoft Access アプリケーション固有の機能 (Access レポートを印刷またはプレビューする機能、access フォームを表示する機能、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 オブジェクトからデータベースを更新する方法

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

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

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

Access でデータベースを開く

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

また、Access のインスタンスでデータベースを開くには、InteropServices (データベース>)<メソッドを使用することもできます (データベースのパスを指定します)。 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 を呼び出すと、渡される引数のいずれかによって、レポートが画面に表示されるかどうか、またはプリンターに送信されるかどうかが決まります。

// 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 引数はレポートの recordset を制限できます (WHERE という単語は含めません)。オプションとして指定されているオブジェクトのパラメーターをスキップする場合は、system.guid を使用することに注意してください。

レポートをプレビューしている場合は、Access が画面に表示されるように、Application オブジェクトの Visible プロパティを設定していることを確認してください。 これにより、ユーザーは Access ウィンドウでレポートを表示できるようになります。

データベース内のレポートまたはその他のオブジェクトを印刷する別の方法があります。 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 の両方の方法を使用する場合もあります。 Employees レポートの複数のコピーを印刷するが、特定の従業員に対してのみ印刷するとします。 この例では、最初に OpenReport を使用して、WhereCondition 引数を使用して、特定の従業員にレコードを制限し、プレビューモードで Employees レポートを開きます。 次に、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アプリケーションオブジェクトへの変更をリセットする方法

Access フォームを表示および編集する

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 を自動化するときに、データベースを開くときに、ユーザー名またはパスワードの入力を求められる場合があります。 ユーザーが間違った情報を入力すると、コード内でエラーが発生します。 これらのダイアログボックスを非表示にして、プログラムを使用してユーザー名とパスワードを提供し、自動化のコードが中断せずに実行されるようにすることができます。

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
   );

以下は、データベースが開かれていない Access のインスタンスに対して既に設定されている oAccess の例です。 このコードでは、ダイアログボックスを表示しないようにデータベースにパスワードを設定します。

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

Access のセキュリティログオンダイアログボックスを回避する

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

Access ランタイムを自動化する

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

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

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

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

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

C:\Program C:\Program Office\Office\Samples

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

C:\Program C:\Program Office\Office10\Samples

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

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

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

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

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

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

    メモVisual Studio 2005 でコードを変更する必要があります。 既定では、Visual C# は、Windows フォームプロジェクトを作成するときに、プロジェクトにフォームを1つ追加します。 Form には、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. Form1 に5つのオプションボタンコントロールと1つのボタンコントロールを追加します。

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

  9. Form Load イベントのイベントハンドラーと、ボタンコントロールの Click イベントに対するイベントハンドラーを追加します。

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

      フォームの 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. [レポートのプレビュー] をクリックし、[移動] をクリックします。 Preview_Report の手順では、Northwind データベースからレポートをプレビューします。 続行する準備ができたら、Access のインスタンスを閉じます。

  15. [フォームの表示] をクリックし、[移動] をクリックします。 Show_Form の手順では、ノースウィンドデータベースの [得意先宛名ラベル] ダイアログボックスフォームを表示します。 また、フォームのオプショングループを "特定の国" に設定し、一覧から [USA] を選択します。 続行する準備ができたら、Access のインスタンスを閉じます。

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

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

References

詳細については、次の MSDN Web サイトを参照してください。 https://msdn.microsoft.com/en-us/library/aa188489(office.10).aspxMicrosoft Office Development With Visual Studio 詳細については、以下の記事番号をクリックして、マイクロソフトサポート技術情報の記事を参照してください。

317109 Office アプリケーションは、Visual Studio .net クライアントからオートメーションを実行した後に終了しない

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