Bonjour, à tous
J'espère que cette demande de support Excel VBA se trouve au bon endroit.
Depuis que je suis passé sous environnement Excel office 365, Windows 10 Entreprise, j'ai une Macro VBA qui fonctionne de façon extrêmement lente.
Je ne peux plus l'utiliser, dans l'état.
Le problème semble venir de l'instruction GetPixel, qui prend maintenant beaucoup plus de temps à s'exécuter.
A l'origine, j'appelle cette instruction dans deux boucles imbriquées, jusqu'à 500 000 fois.
En fait, je fais de la reconnaissance de couleur pixel par pixel, sur la base de ce qui est affiché dans une zone précise de l'écran en cours.
Avant de rentrer dans le détail de la problématique "Code" deux questions aux experts.
1. << Avez-vous connaissance de ce genre de problème sur un environnement Windows 10 ? >>
2. << Pouvez-vous me donner quelques pistes d'investigation afin d'orienter mes recherches pour booster ma macro ? >>
A savoir :
J'ai également changé de PC, la configuration générale de ce nouveau PC est plus puissance et plus rapide que mon PC précédent datant de 5 ans.
Configuration actuelle:
Windows 10 Enterprise
Excel 365
VBA 7.1
Processeur Intel(R) Core(TM) i7-8706G CPU @ 3.10GHz, 3096 MHz, 4 cœur(s), 8 processeur(s) logique(s)
Mémoire physique (RAM) installée 16,0 Go
Mémoire physique totale 15,8 Go
Mémoire physique disponible 9,69 Go
Mémoire virtuelle totale 18,2 Go
Mémoire virtuelle disponible 8,53 Go
Je joins mon fichier Macro simplifié, le test consiste à scanner 500 pixels sur une seule colonne de l’écran actif, ceci prend plus de 8,3 sec sur ma configuration actuelle.
Pour info sur mon ancienne configuration PC datant de 5 ans, pour scanner 267 211 pixels (toute une zone) il me fallait 4 min 53 sec ce qui est dans mon cas acceptable. Si j’extrapole il me faudrait aujourd’hui, 1 Heure 13 Minute 58 Sec ce qui n’est pas possible compte tenu de mon besoin.
Remarque utilisation Exemple feuille et Macro associée,
1. Ouvrir Excel sur écran principal (Si vous avez un écran en extension la zone scanner n'est pas forcément cohérente.
2. J'ai ajouté des zones rouge, jaune, et vert pour avoir un résultat minimum, nb de pixel Rouge jaune et vert.
3. J'ai rajouté un méssage indiquant les resultats trouvés.
4. En mettant Excel en priorité haute à travers le gestionnaire de tache, le temps d'exécution c'est légèrement amélioré 6,6 seconde au lieu de 8,3 seconde. Reste à confirmer si c’est vraiment lié, il me faut faire plus de tests, et c'est de tout façon trop long pour mon besoin.
Merci par avance pour votre retour d’information.
Cordialement JLK
Pièce jointe 517343
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 Option Explicit Private Declare PtrSafe Function GetPixel Lib "gdi32" (ByVal Hdc As Long, ByVal x As Long, ByVal Y As Long) As Long Private Declare PtrSafe Function GetWindowDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr Sub ScanZone() Dim TimerDebLoopNiv00 As Double Dim TimerEndLoopNiv00 As Double Dim ScanX As Single Dim ScanY As Single Dim PixelTotal ' Valeure Calculée Dim PixelVert ' Vert Couleur RGB = 0, 160, 80 Dim PixelJaune ' Jaune Couleur RGB = 255, 255, 0 Dim PixelRouge ' Rouge Couleur RGB = 255, 0, 0 Dim Bluejlk As Integer Dim Greenjlk As Integer Dim Redjlk As Integer Dim lDC As Variant Dim lColour As Long If MsgBox("Do you want to Scan ?", vbExclamation + vbYesNo + vbDefaultButton2, "Message Application test JLK2015") = vbNo Then End 'Application.ScreenUpdating = False 'Deactiver pour le test On Error GoTo errorHandler PixelVert = 0 ' Vert Couleur RGB = 0, 160, 80 PixelJaune = 0 ' Jaune Couleur RGB = 255, 255, 0 PixelRouge = 0 ' Rouge Couleur RGB = 255, 0, 0 PixelTotal = 0 ' Valeure Calculée lDC = GetWindowDC(0) 'DoEvents ' A Confirmer si l'instruction est necessaire '*** Pour tester le temps d'execution on va scanner une ligne verticale sur l'écran coordonnée pixel x = 500 coordonnée y de 100 à 599 soit un total de 500 pixels **** TimerDebLoopNiv00 = Timer ScanX = 500 'Colonne pixel n° 500 de la fenêtre en cours For ScanY = 200 To 599 'Ligne pixel n° 100 à 600 lColour = GetPixel(lDC, ScanX, ScanY) 'DoEvents ' A voir si nécessaire 'Fragmentation du code couleur en code RGB Redjlk = Int(lColour Mod 256) Greenjlk = Int((lColour Mod 65536) / 256) Bluejlk = Int(lColour / 65536) 'Vert Couleur RGB = 0, 160, 80 If Redjlk = 0 And Greenjlk = 160 And Bluejlk = 80 Then PixelVert = PixelVert + 1 End If 'Jaune Couleur RGB = 255, 255, 0 If Redjlk = 255 And Greenjlk = 255 And Bluejlk = 0 Then PixelJaune = PixelJaune + 1 End If 'Rouge Couleur RGB = 255, 0, 0 If Redjlk = 255 And Greenjlk = 0 And Bluejlk = 0 Then PixelRouge = PixelRouge + 1 End If PixelTotal = PixelTotal + 1 Next 'Controle temps execution boucle TimerEndLoopNiv00 = Timer MsgBox "Analysis is finish" & Chr(10) _ & "Execution time was: " & Chr(10) _ & Round((TimerEndLoopNiv00 - TimerDebLoopNiv00), 3) & " Seconds" & Chr(10) _ & "Number of pixel scanned " & PixelTotal & Chr(10) _ & "Vert " & PixelVert & Chr(10) _ & "Jaune " & PixelJaune & Chr(10) _ & "Rouge " & PixelRouge _ , vbInformation, "Message Application test JLK2015" 'Application.ScreenUpdating = True 'Deactiver pour le test Exit Sub errorHandler: MsgBox Err.Number & vbLf & Err.Description End Sub
Partager