好的,我试图从C#自动化Microsoft Access。显然你不能在VBA本身中异步执行VBA代码,但我的想法是使用委托从C#中强制执行此操作。
我们有一个遗留报告系统,它运行数百个设计糟糕的查询来获取信息,这些查询在宏中同步运行。每个查询都是使用MS Access查询设计器设计的,并通过ODBC查询MySql数据库。它们需要2-3分钟才能运行,而宏可能包含< = 20个查询,这意味着宏将花费一小时的最佳时间来运行。如果我运行这些异步,我可以在几分钟内运行整个宏。
我的完整C#代码如下:
using System;
using Microsoft.Office.Interop.Access;
namespace AsyncVBA
{
class Program
{
private static Application ap;
private delegate void ExportThread(string queryName, string exportLocation);
private static int count;
static void Main(string[] args)
{
var dbName = @"C:\Users\JMK\Desktop\MyDatabase.accdb";
count = 0;
ExportThread queryThread = new ExportThread(ExportQuery);
ap = new Application();
ap.OpenCurrentDatabase(dbName);
queryThread.BeginInvoke("qryOne", @"C:\Users\JMK\Desktop\x\one.xlsx", null, null);
queryThread.BeginInvoke("qryTwo", @"C:\Users\JMK\Desktop\x\two.xlsx", null, null);
queryThread.BeginInvoke("qryThree", @"C:\Users\JMK\Desktop\x\three.xlsx", null, null);
queryThread.BeginInvoke("qryFour", @"C:\Users\JMK\Desktop\x\four.xlsx", null, null);
queryThread.BeginInvoke("qryFive", @"C:\Users\JMK\Desktop\x\five.xlsx", null, null);
queryThread.BeginInvoke("qrySix", @"C:\Users\JMK\Desktop\x\six.xlsx", null, null);
queryThread.BeginInvoke("qrySeven", @"C:\Users\JMK\Desktop\x\seven.xlsx", null, null);
queryThread.BeginInvoke("qryEight", @"C:\Users\JMK\Desktop\x\eight.xlsx", null, null);
queryThread.BeginInvoke("qryNine", @"C:\Users\JMK\Desktop\x\nine.xlsx", null, null);
queryThread.BeginInvoke("qryTen", @"C:\Users\JMK\Desktop\x\ten.xlsx", null, null);
while (count < 10)
{
Console.ReadLine();
}
ap.CloseCurrentDatabase();
}
private static void ExportQuery(string queryName, string exportLocation)
{
ap.DoCmd.TransferSpreadsheet(AcDataTransferType.acExport, AcSpreadSheetType.acSpreadsheetTypeExcel9, queryName, exportLocation);
count++;
}
}
}
我目前有两个问题,第一个是我的代码似乎仍在同步执行,这可能与MS Access中的限制有关。我猜测MS Access在收到请求时将请求排队。第二个不那么重要的问题是,我的计数似乎没有增加。
我哪里错了?
由于
答案 0 :(得分:7)
从大量使用Access作为前端的经验来看,最好是将所有查询更改为传递查询并使用mySQL语法重写它们。
当前方法花费这么长时间的原因可能是通过网络传递的数据集远远大于它需要的数据集。 Access通过mySQL DB可以解释的内容,然后在到达时应用其余的sql语法。对于大型数据集来说效率非常低。
答案 1 :(得分:3)
实际上,启动word,Excel,power point或任何办公套件都不会异步运行任何内容。实际上,如果你创建了一个SQL服务器实例,你会发现同样的事情。 (将SQL命令发送到SQL SEPARATE进程与创建进程内实例之间的巨大差异。
我会考虑将这些数据写入文本文件,甚至是临时表,然后shell()在启动时运行一系列quires的应用程序实例。你甚至可以在这里创建一个执行这些命令的Windows脚本。这样,您就可以获得单独的实例和线程,因此您的应用程序将不必等待。
答案 2 :(得分:1)
Microsoft Access中的任何内容都不能与其他任何内容同时运行。我很确定当您成功打开Access数据库时,您将获得所有系统表的独占锁定。我无法看到它如何以其他方式工作。
更好的方法是从Access数据库中提取SQL。您说每个查询都是使用查询设计器设计的(我认为您的意思是设计视图),但它仍然具有您可以获得的SQL。只需从设计视图切换到SQL视图,就可以了,