Oprimiser rapidité d'un programme
Bonjour,
j'ai créé un programme dans vba Word, qui m'ouvre une instance excel, et copie un range de cellules qui contiennent quelque chose.
Ce "quelque chose" peut être une valeur, mais aussi une mise en forme (bordure ou couleur de cellule)
Or cette macro est trop longue à s’exécuter.
Après avoir fait quelques test, deux points sont particulièrement longs :
- L'ouverture de l'instance excel, mais bon, je ne vois pas trop ce qu'on y peut...
- L'accès depuis vba word aux cellules de l'instance excel. Voici le code utilisé : je m'explique sur mon raisonnement à la suite de ce code, pour plus de compréhension.
Sub Copie_tableau(Chemin As String)
Dim fin As Boolean
Dim FirstLi As Integer
Dim FirstCol As Integer
Dim LastLi As Integer
Dim LastCol As Integer
Dim i As Integer, j As Integer
Set xlApp = CreateObject("Excel.Application")
Set xlWB = xlApp.Workbooks.Open(Chemin)
Set doc = xlWB.Worksheets(1)
fin = False
j = LastLi
i = 0
While fin = False
cellule = doc.Cells(j, LastCol)
If Valeur() <> "" Then
fin = True
Else
If j > FirstLi Then
j = j - 1
Else
LastCol = LastCol - 1
j = LastLi
End If
End If
i = i + 1
Wend
La fonction valeur est définie ainsi :
Function Valeur() As Variant
Dim l As Integer
Dim k As Integer
Valeur = ""
k = 0
With cellule
If .Value <> "" Then
Valeur = 2
GoTo fin
End If
If .Interior.ColorIndex <> xlColorIndexNone Then
Valeur = 2
GoTo fin
End If
For l = 5 To 12
If .Borders(l).LineStyle <> xlLineStyleNone Then
k = k + 1
End If
If k > 1 Then
Valeur = k
GoTo fin
End If
Next l
End With
fin:
End Function
J'ai testé la fonction Valeur dans VBA Excel, elle est très efficace (2-3s pour faire 10000 itérations)
Mais depuis word, ma fonction fait 167 itérations en 10-15s.
Je pense que cela vient des appels d'excel via vba word.
Est-ce possible d'optimiser ce code ?
Pour info, avant de déclarer une cellule en tant que variable dans le While, je faisais doc.cells(1,1) dans ma fonction valeur, avec la même lenteur.
Merci d'avance,
Florian
Bonjour,
tu ne peux pas mettre un .doc et un .xls avec ce qu'il faut pour que ta macro tourne si tu veux qu'on teste ?
eric
Bonjour,
Voici donc 2 fichiers, l'un avec le code complet à copier/coller dans VBE Word
deux fichiers excels à insérer, histoire de comprendre l'objectif de la macro :
Merci d'avance !
Florian
Bonjour,
un peu de mal car je ne pratique pas les macros sous word mais j'ai réussi à faire tourner.
Si ton but est de coller avec liaison une plage du fichier excel ça ne serait pas plus simple de la définir et de coller en une fois sans faire tes boucles ?
Sur les 2 tests faits, ça copie l'intégralité de la feuille utilisée.
Si c'est ce que tu veux c'est :
Range("A1", Cells.SpecialCells(xlCellTypeLastCell).Address).select
eric
Bonjour,
Tout d'abord merci d'y avoir consacré du temps.
Le but est effectivement de générer une liaison vers un tableau dans un fichier excel.
J'avais déjà fait un programme dont le fonctionnement était satisfaisant, qui consistait à faire simplement une insertion d'objet excel dans word. Le problème, c'est que pour certains tableaux, certaines colonnes vides sont ajoutées, ce qui n'est pas souhaitable. Le but de mon programme est de contourner ce problème, en faisant une copie des cellules excel non vides.
Le but est bien de copier l'intégralité de la feuille utilisée, mais je ne sais pas à priori où se trouve le tableau dans ma feuille (Il peut très bien se trouver sur la plage C5:G20 par exemple.
Le problème avec la méthode SpecialCells (que j'utilise un peu dans mon code) c'est qu'elle considère toutes les cellules utilisées. Est définie comme "utilisée" toute cellule qui a subit une modification, même si cette modification a ensuite été effacée.
C'est pour cette raison que j'ai défini toutes ces boucles.
J'ai fait boucler la fonction "Valeur" sur 10000 itérations. C'est très rapide.
Mais dès que l'on passe sous word, cela devient très lent. Je me demande si cela ne vient pas du fait des échanges entre l'appli word, et l'appli excel? Dans ce cas, y a t il une solution pour que tous les calculs soient éxécutés sous vba Excel, avec simplement la fourniture du résultat à VBA word ?
Comme le but est d'intégrer un tableau dans word, je ne peux pas intégrer de macro dans le fichier excel, qui serait lancée par un excel.run dans word, puisque cela impliquerait d'avoir cette macro de définie dans chaque fichier Excel.
A moins que je ne me trompe ?
Merci d'avance, désolé pour ce problème un peu épineux
Si ça peut t'aider 2 syntaxes pour trouver dernière ligne ou dernière colonne utilisées :
derlig = Sheets(nomFeuille).Cells.Find("*", , , , xlByRows, xlPrevious).Row
dercol = Range("B1:IV12400").Find("*", , , , , xlPrevious).Column
derlig : sur toute la feuille, dercol : sur une plage restreinte de la feuille active.
Sinon on peut ajouter du code dans un classeur. Pas trop évident à partir d'excel, je ne sais pas trop ce que ça donne à partir de word.
eric
Bonjour,
Alors, le find ne marche pas, car j'ai besoin de trouver des cellules vides, mais mises en forme
Merci pour l'astuce de modifier le VBE, je n'aurais pas pensé que tout ce qu'ils expliquent était possible.
Il va falloir que je bidouille un moment avant de trouver la bonne solution. ça va être bien chiant d'activer par macro les différentes librairies, créer la macro dans excel, la lancer, récuperer les infos, et supprimer tout ça proprement une fois le job fini.
Je vous tiens au courant si cela aboutit.
Merci encore !
Florian