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

Rechercher des sujets similaires à "oprimiser rapidite programme"