1

VBA コードの一部を .Net から Microsoft Access データベースに挿入しています。

これは、マクロを実行する 1 行のコードです。マクロが行うことは、モジュール内で VBA コードのブロックを実行することだけです。

私が抱えている問題は、これがすべて、ユーザーが現在開いているセッションではなく、見ることさえできない新しい MSAccess セッションで発生することです。

代わりに、これをユーザーの現在の MSAccess セッションと対話させることは可能ですか? これの要点は、.Net イベントが発生するたびに MSAccess セッション内で特定のフォームを開くことです。私のC#コードは以下の通りです:

using Microsoft.Office.Interop.Access;

var msAccess = new Application();

msAccess.OpenCurrentDatabase(@"x:\foo\bar.accdb", false);
msAccess.DoCmd.RunMacro("macCTI");
msAccess.CloseCurrentDatabase();

ありがとう

4

2 に答える 2

2

Accessの単一インスタンスを実行している場合は、次を使用できますMarshal.GetActiveObject

using Microsoft.Office.Interop.Access;
using System.Runtime.InteropServices
...
try
{
    var msAccess = (Application)Marshal.GetActiveObject("Access.Application");
    msAccess.DoCmd.RunMacro("macCTI");
}
catch (COMException ex)
{
    // handle error
}

または、複数のインスタンスが実行されていて、2つのインスタンスで同じデータベースが開いていない場合は、次を使用できますMarshal.BindToMoniker

var msAccess = (Application) Marshal.BindToMoniker(@"x:\foo\bar.accdb"); 

注:このマイクロソフトサポート技術情報には、次のように書かれています。

COMサーバーがシングルユース(マルチインスタンス)であるかマルチユース(シングルインスタンス)であるかは、GetActiveObjectを使用してそのサーバーへの参照を取得する決定に影響を与える可能性があります。Word、Excel、またはMicrosoft Accessの複数のインスタンスが実行されている可能性があるため、特定のサーバー上のGetActiveObjectは、予期しないインスタンスを返す場合があります。ROTに最初に登録されるインスタンスは、通常、GetActiveObjectによって返されるインスタンスです。Word、Excel、またはMicrosoft Accessの特定の実行中のインスタンスへの自動化参照を取得する場合は、そのインスタンスで開かれているファイルの名前でBindToMonikerを使用します。PowerPointのようなマルチユース(シングルインスタンス)サーバーの場合、自動化参照が同じ実行中のインスタンスを指しているため、問題ではありません。

于 2012-05-01T12:58:26.033 に答える
0

新しい Access インスタンスを取得しないようにするには、インスタンスが既に存在するかどうかを確認する必要があります。Marshal.GetActiveObjectMatt が提案したように使用します。

Application GetAccessApplication() {
  var application = (Application) Marshal.GetActiveObject("Access.Application");
  return application ?? new Application();
}

ProgID を使用して Access の既存のインスタンスを取得する必要がありますが、相互運用アセンブリを使用して新しいインスタンスを作成する必要があるため、ここではわずかな切断があることに注意してください。

次に、Access アプリケーションを表示できるようにします。

var msAccess = GetAccessApplication();
msAccess.Visible = true;
于 2012-05-01T13:09:26.863 に答える