使用COM Interop从VSTO C#中列出现有Access实例的MS Access表

问题描述 投票:0回答:2

使用VSTO和COM Interop,我正在尝试访问和操作已在Microsoft Access中打开的数据库。我可以掌握Access应用程序对象,当前用户名和其他属性。但是,当我尝试获取表列表以打印表名称时,代码将失败。

我的最终目标是使用'application.Run(“ MyMacroName”)'运行Access VBA宏。谁能告诉我我在想什么或做错了什么?谢谢。

更新解决方案

谢谢Albert(见下文),他一直提供(Visual Basic)信息,直到我能够使用C#代码为止。我所缺少的最大的东西是1)使用引用的DAO(VStudio最初说我并不需要它),以及2)循环的explicit DAO TableDef类型(“ var”不起作用)。

有效的更新代码:

using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Access;
using Microsoft.Office.Interop.Access.Dao;  // *MUST* have DAO as well
using Access = Microsoft.Office.Interop.Access; // Access = a namespace qualifier

[TestMethod()]
  public void MsAccessComInteropTest() {
    // explicitly cast the object to an Access.Application
    // I used 'Access.Application' to qualify from a System.xxxx.Application type
    var app = (Access.Application) Marshal.GetActiveObject("Access.Application");
    Dprint($"{app.Name}"); // prints Microsoft Access
    Dprint($"{app.CurrentUser()}"); // prints Admin

    var db = app.CurrentDb();

    // *MUST* use TableDef type explicitly from DAO in loop - cannot use 'var'
    foreach (TableDef tbl in db.TableDefs) {
      // Attributes == 0 means a user-defined table
      if (tbl.Attributes == 0) {
        Debug.Print($"{tbl.Name}  '{tbl.Attributes.ToString()}'");
      }
    }

    app.Run("MyVbaMacroName");  
}
c# ms-access com vsto
2个回答
0
投票

您需要同时访问Access和DAO。

这两个:

Microsoft.Office.Interop.Access
C:\Program Files (x86)\Microsoft Visual Studio 12.0\
Visual Studio Tools for Office\PIA\Office14\
Microsoft.Office.Interop.Access.dll

您需要这个:

Microsoft.Office.Interop.Access.Dao
C:\Program Files (x86)\Microsoft Visual Studio 12.0\
Visual Studio Tools for Office\PIA\Office14\
Microsoft.Office.interop.access.dao.dll

因此您的代码将如下所示:

{
Access.Application app;

app = Interaction.GetObject(Class: "Access.Application");
Access.Dao.Database db;
db = app.CurrentDb;
Access.Dao.TableDef tblDef;

foreach (var tblDef in db.TableDefs)
    Debug.Print(tblDef.Name);
 }

实际上,您可以使用后期绑定,甚至不引用互操作程序集。

例如此:

{
var app = Interaction.GetObject(Class: "Access.Application");
var db = app.CurrentDB;
var tblDef;
foreach (var tblDef in db.TableDefs)
    Debug.Print(tblDef.Name);
}

但是,如果您进行100%的后期绑定,那么您将不会获得任何智能感知。

而且,这看起来很奇怪:

using Access = Microsoft.Office.Interop.Access;  

为什么上面的“ =”-我认为看起来不正确。

应该是:

using Access Microsoft.Office.Interop.Access;  

因此,如果要使用互操作进行引用-您需要Access + DAO。 (而且它们是不同的汇编,但是使用相同的名称空间-不确定c#中是否存在问题,但在vb.net中存在]


0
投票

如果要获取完整的表列表,通常使用CurrentDb.Tabledefs

var db = app.CurrentDb(); 
foreach (var td in db.TableDefs) {
    Dprint(td.Name);
}
© www.soinside.com 2019 - 2024. All rights reserved.