2016-12-29 62 views
2

發送要建立一個報告的Excel的說明,我計算了一些數據和訪問,然後使用VBA宏導出多個表,那麼這個宏啓動Excel並在Excel中運行另一個宏編譯一切。VBA - 加快由Access

一切是相當快了,但有必要有一個Excel工作表使用VBA代碼,它除了我訪問VBA困擾我。最近,我最近在數據庫中增加了許多新功能,可以選擇生成多個報表,並在Access窗體上提供大量自定義功能。

我在這兩個文件之間導航有些複雜,所以我試圖將我的Excel代碼放在Access中,所以我的同事(最終用戶)只需要保持1個文件的最新狀態他們的電腦,它也會讓事情更容易調試。

報告建成符合市場預期,但這個過程是比較慢的5倍。我試着測量每個步驟所花費的時間,並且比例保持不變(除了PowerPoint演示文稿最終生成時的部分)。

所以我決定嘗試這種無用的代碼:

Sub test() 

Dim t As Double 'Starting time 
t = Round(Timer) 

Dim b As Workbook 
Dim s As Worksheet 
Dim i As Integer, j As Integer 'Loop variables 


'Create workbook 
Set b = Workbooks.Add 
'Get worksheet 
Set s = b.Sheets(1) 

'Double Loop 
For i = 1 To 100 
    For j = 1 To 100 
     s.Cells(i, j) = "Hi!" 'Write some useless comment 
    Next 
Next 

b.Close False 'Close without saving 

'Message 
MsgBox (Round(Timer) - t) \ 60 & "'" & Format((Round(Timer) - t) Mod 60, "00") & "''" 

End Sub 

我沒有把任何ScreenUpdating =假enableEvents方法=假,等故意的。

當從Excel運行的代碼,它需要2至3秒。

當從Access運行的代碼,它從7到10秒!

據我瞭解,訪問具有發送指令到另一個應用程序,它可以減緩過程。所以我試着要求Excel在另一個Excel實例中運行我的腳本(所以我創建了一個對象「Excel.Application」,我在其中放置了我的工作簿,Access在後臺執行的操作),並且獲得了與我一樣的性能從Access運行代碼。

有什麼辦法可以加快速度嗎? 改變VB腳本與其創建的應用程序對象通信方式的指令可能是什麼?

非常感謝大家的支持。

編輯:根據ASH的要求,這裏是我在Access中運行的完整代碼(我不會把我的報告代碼,因爲它是很大的潛艇,功能,自定義類等)。評論是在法國,但這裏是一個總結:

  • 第一個腳本是創建或打開一個Excel 工作簿的功能,只有少數的優化(Excel中無形的,沒有屏幕 更新,不計算等。)

  • 第二個腳本是封閉Excel工作簿,與保存/保存作爲 選項,並且從所述第一 功能丟棄的優化子

  • 第三腳本是analte我之前提出的測試代碼的版本。

現在的代碼本身:

Option Explicit 

Function Ouvrir_Classeur_Excel(Optional Fichier As String, Optional Optimiser As Boolean = False) As Workbook 

'*********************************** Descriptif 
'Ouvre (ou crée) un classeur Excel en appliquant une optimisation si demandé par l'utilisateur. 
'L'optimisation cache et désactive le rafraîchissement visuel d'Excel, les messages d'alerte, les événements et les calculs automatiques. 

'------------------ Paramètres 
'Fichier : Le chemin du classeur à ouvrir. S'il est vide, un classeur est créé 
'Optimiser : Indique si les scripts d'optimisation doivent être exécutés. Par défaut, cette option est désactivée 



'*********************************** Exécution 
With Excel.Application 


    If Optimiser Then 
     'Excel invisible 
     .Visible = False 
     'Désactivation du rafraîchissement 
     .ScreenUpdating = False 
     'Désactivation des messages d'alerte 
     .DisplayAlerts = False 
     'Désactivation des événements 
     .EnableEvents = False 
    End If 

    'Ouverture/Création du classeur 
    If Fichier <> "" Then Set Ouvrir_Classeur_Excel = Workbooks.Open(Fichier) 'Si on a spécifié un fichier, il est ouvert 
    If Fichier = "" Then Set Ouvrir_Classeur_Excel = Workbooks.Add 'Si on n'a pas spécifié de fichier, on en crée un 

    'Désactivation des calculs automatiques 
    If Optimiser Then .Calculation = xlCalculationManual 

End With 

End Function 




Sub Fermer_Classeur_Excel(Classeur As Workbook, Optional Enregistrer As Boolean = False, _ 
    Optional Emplacement As String, Optional Fin_Optimisation As Boolean = False) 

'*********************************** Descriptif 
'Ferme le classeur Excel spécifié. 
'Si l'utilisateur le demande, le classeur peut être enregistré, ou enregistré sous. 
'Si l'utilisateur le demande, les optimisations appliquées par la fonction Ouvrir_Classeur_Excel peuvent être annulées. 

'------------------ Paramètres 
'Classeur : Le classeur à fermer 
'Enregistrer : Indique si le classeur doit être enregistré. Par défaut, cette option est désactivée 
'Emplacement : Indique l'emplacement où enregistrer le classeur. Si vide, l'enregistrement sera simple. 
'Fin_Optimisation : Indique si les optimisations doivent être annulées. Par défaut, cette option est désactivée 



'*********************************** Exécution 
With Excel.Application 

    'Enregistrement du classeur 
    If Enregistrer Then 
     If Emplacement = "" Then Classeur.Save 
     If Emplacement <> "" Then Classeur.SaveAs Emplacement 
    End If 

    'Réactivation des calculs automatiques 
    If Fin_Optimisation Then .Calculation = xlCalculationAutomatic 

    'Fermeture du classeur 
    Classeur.Close False 


    If Fin_Optimisation Then 
     'Réactivation du rafraîchissement 
     .ScreenUpdating = True 
     'Réactivation des messages d'alerte 
     .DisplayAlerts = True 
     'Réactivation des événements 
     .EnableEvents = False 
    End If 

End With 

End Sub 




Sub testA() 

'------------Relève de l'heure de début 
Dim tGlo As Double 'Heure de début d'exécution du script 
Dim infoFin As String 
tGlo = Round(Timer) 

Dim x As Excel.Application 
Dim c As Workbook 
Dim f As Worksheet 
Dim i As Integer, j As Integer 

Set c = Ouvrir_Classeur_Excel(, True) 

Set f = c.Sheets(1) 
i = 1 
Do Until i = 100 
    j = 1 
    Do Until j = 100 
     f.Cells(i, j) = "Coucou" 
     j = j + 1 
    Loop 
    i = i + 1 
Loop 

Fermer_Classeur_Excel c, , , True 


'------------Message de fin 
infoFin = infoFin & Chr(10) & Chr(10) & "DUREE DE TRAITEMENT : " & (Round(Timer) - tGlo) \ 60 & "'" & Format((Round(Timer) - tGlo) Mod 60, "00") & "''" 
MsgBox infoFin, , title:="** FIN DU TRAITEMENT **" 


End Sub 

像這樣,它需要2至7秒(用Excel已經運行),相比小於1在Excel具有相同的優化這是巨大。

問題是這裏看起來並不重要,但另一個通常需要40秒的過程在Excel中遷移到Access時花費了3分多鐘。我有另一個(尚未優化),需要更多的3:30在Excel中,我甚至不敢嘗試在Access中運行它。

+0

很多事情可以加速操作。你需要嘗試一下。即使excel應用程序不可見,禁用事件等,這些額外的延遲可能是由於在開始時的一些設置時間等。我建議你發佈一些代碼,你從Access運行,看看它可以如何調整。 –

+3

您也可以通過[Code Review](http://codereview.stackexchange.com/)尋求幫助。該網站強調減少代碼並提高已有代碼的性能。 – PartyHatPanda

+0

我沒有在我的消息中使用任何Application.visible等,以使代碼儘可能短。 這裏是我的優化上訪問: - Excel是不可見的(該指令是不是強制性的,但我把它反正) - ScreenUpdating禁用 - 警報禁用 - 活動禁用 - 計算禁用 在Excel中,我做的一樣。該比例仍然很高(慢3到6倍)。 啓動Excel時,安裝時間只會延遲執行代碼幾秒鐘,但如果在Excel中花費40秒的進程需要超過3分鐘的Access時間,則無法證明安裝時間。 –

回答

0

我知道你提到你在Access中有很多自定義程序來生成各種報告,但是有什麼理由不能將該代碼移動到Excel?我有幾個解決方案,我在Excel中創建了運行代碼,但使用Access作爲數據源,而且它們速度非常快 - 您在Access中構建的用戶表單必須在Excel中重新生成,但可以解決Excel之間的性能問題/訪問...

希望這有助於 TheSilkCode