2012-04-15 32 views
2

好吧,我試圖從C#中自動化Microsoft Access。顯然你不能在VBA本身異步執行VBA代碼,但我的想法是使用委託從C#強制執行此操作。這個VBA代碼是否會異步執行

我們有一個傳統的報告系統,它運行數百個設計不當的查詢來獲取信息,並且這些查詢在宏內同步運行。每個查詢都是使用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

計數是一個靜態變量嗎? – Paparazzi 2012-04-15 12:55:46

+0

是的,這是一個問題嗎? – JMK 2012-04-15 12:57:47

+0

不,它是使用C#異步運行VBA代碼,導出只是我想運行的VBA代碼類型的一個示例。 – JMK 2012-04-15 14:34:07

回答

2

實際上,啓動Word,Excel,Power Point或任何辦公套件不會異步運行任何事情。事實上,如果你創建了SQL服務器的實例,你會發現同樣的事情。 (將SQL命令發送到SQL SEPARATE進程與創建進程內實例相比,差別很大)

我會考慮將此數據寫入文本文件甚至臨時表,然後將shell()一個正在啓動的應用程序實例運行一系列quires,甚至可以在這裏創建一個windows腳本來執行這些命令,這樣你就可以獲得一個單獨的實例和線程,因此你的應用程序不需要等待,

1

Microsoft Access中的任何內容都不能與其他任何內容同時運行。我非常確定,當您成功打開Access數據庫時,您將獲得對所有系統表的獨佔鎖定。我看不出其他方式如何工作。

更好的方法是從Access數據庫中提取SQL。你說每個查詢都是使用查詢設計器設計的(我認爲你的意思是設計視圖),但它仍然有你可以得到的SQL。從設計視圖切換到SQL視圖,並且你有它

+0

嗯,我試圖避免這一點。這裏的問題是,SQL不是MySQL,所以每個查詢都必須進行轉換,那麼鏈接表的名稱在Access中都已更改,例如,MySql中的tblOne可能已更改爲Access中的tblAccessOne,這意味着每個查詢中的每個tblAccessOne實例都需要更改爲tblOne來直接運行MySql查詢。這就是我最初做的事情,它很快就變得非常混亂! – JMK 2012-04-15 13:34:37

+0

您可以創建MySQL視圖來模擬MS Access選擇查詢。 SQL不會有那麼不同。 – 2012-04-15 13:56:56

7

剛剛從Access作爲前端的許多經驗來看,最好的方法是將所有查詢都更改爲傳遞查詢,並將其重寫爲mySQL語法。

因爲目前的方法需要這麼久的原因可能是通過網絡傳遞的數據集遠大於它所需要的。訪問傳遞mySQL DB可以解釋的內容,然後在到達時應用其餘的sql語法。對於大數據集來說效率非常低。

+0

我很早以前就問過這個問題,但是感謝您花時間回答,自從詢問並確實重寫了很多MySQL中的查詢以來,我已經學會了這一難題 – JMK 2012-10-10 20:41:38