Vitesse d'exécution

Résolu
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 - 30 janv. 2008 à 18:32
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 - 31 janv. 2008 à 11:49
bonsoir

en VBA je mets dans AutoCAD des données dans un tableau ( une douzaine de colonnes et de 2 à 30000 lignes suivant la densité du dessin d'où j'extraie ces données)
en suite je copie ce tableau dans une feuille Excel pour pouvoir faire des corrections avant de réimporter dans le dessin.
mon probleme est que si je fais tout l'oprération d'export vers excel depuis la macro Autocad je vais mettre pour 3000 lignes environ 5minutes pour remplir la feuille Excel
par contre si dans mon VBA je copie ce tableau dans un fichier texte puis je lance une macro excel qui va lire ce fichier et remplis la feuille le temps pour ces memes 3000lignes tombe à 12 secondes

voici le code VBA de ma macro AutoCAD (la partie concernant l'envoi des données dans la feuille excel)

    Set ExcelApp = GetObject(, "Excel.Application")
    If Err.Number <> 0 Then
        Err.Clear
        Set ExcelApp = CreateObject("Excel.Application")
    End If
    Set feuille = ExcelApp.Sheets("EXTRACT")
    feuille.Activate
    With feuille
        .Cells.Delete Shift:=xlUp
        .Rows(1).Font.Bold = True
        .Rows(1).Interior.ColorIndex = 35
        .Columns(1).Interior.ColorIndex = 37
        .Cells.NumberFormat = "@"
        .Columns("A:Z").AutoFit
    End With
    ' ExcelApp.Run "PERSO.XLS!extract2"
   For I = 0 To UBound(extrtab, 2)
        For J = 0 To UBound(extrtab, 1)
            feuille.Cells(I + 1, J + 1) = extrtab(J, I)
        Next J
    Next I
    Set ExcelApp = Nothing
    Exit Sub
 
la macro telle que copiée ici exécute tout depuis autocad
pour la solution rapide je mets tout ce qui est bleu en commentaire et rend la ligne actuellement en commentaire active

quelqu'un a-t-il une explication à cette différence de vitesse ? (et éventuellement une solution autre que mes deux macros )

merci d'avance

10 réponses

cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 23
31 janv. 2008 à 11:01
Sous VB6 ou VBA, dans un des menus de l'IDE, tu as "Références" qui ouvre une boîte et présente tous les programmes auxquels tu peux créer une référence. C'est du "early binding". Lorsque tu utilises CreateObject, c'est du "late binding". Je me disais donc que tu pourrais éventuellement créer une référence et faire un essai de cette manière et voir si ça n'accélère pas le processus...(?)

Le hic avec les références, c'est justement qu'elles sont créées dans l'IDE, donc fixes, en quelque sorte. Si tu essaies d'exploiter ton programme sur un PC possédant une autre version d'Office, ça va planter...

Autre chose qui peut ralentir, je pense, c'est la version d'Office que tu utilises. D'après mon expérience, Office 2000 et précédents étaient plus rapides que 2003, et 2003 plus rapide que 2007 (selon les dires...)

Dernière idée, pour l'instant...
avant ta boucle qui semble celle qui cause le ralentissement, mets
    ExcelApp.ScreenUpdating = False
    ExcelApp.Calculation = xlCalculationManual
Après la boucle, tu remets les valeurs normales
    ExcelApp.ScreenUpdating = True
    ExcelApp.Calculation = xlCalculationAutomatic

PS: n'oublie pas de regarder le DataObject qui te permettrait de remplir ta feuille d'un seul coup, plutôt que de double-boucler les valeurs de ton tableau...

MPi²
Pour ceux qui programment sous Office, n'oubliez pas qu'il existe un forum dédié à ces applications VBA....... ICI
3
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 6
31 janv. 2008 à 11:49
    ExcelApp.ScreenUpdating = False
    ExcelApp.Calculation = xlCalculationManual
    ma doubleboucle
    ExcelApp.ScreenUpdating = True
    ExcelApp.Calculation = xlCalculationAutomatic
grace à   ces quatres lignes j'ai divisé le temps de remplissage de la feuille excel par deux
pour un meme dessin je suis passé de 65 secondes à 35
ce qui est encore loin des 10 secondes que j'ai en passant par un fichier texte puis la macro excel
mais c'est déja plus que significatif comme amélioration
je vais plancher sur le dataobject  pour voir comment l'exploiter et peut être améliorer encore la vitesse d'éxécution

merci Mpi pour ta patience et tes précieux conseils !!!!!
3
bigfish_le vrai Messages postés 1835 Date d'inscription vendredi 13 mai 2005 Statut Membre Dernière intervention 20 novembre 2013 15
30 janv. 2008 à 19:21
Salut,

en faite tu opposes une solution qui s'apparente un copier coller suvit d'une ouverture de fichier(ta solution la plus rapide) a une solution qui traite les données une par une grace a tes 2 boucles
for next. Pour cette deuxieme solution, cela represente pour 12 colonnes et 3000 lignes 36000 boucles.

en VBA Excel Un tableau est un objet au meme titre qu'une celule donc tu peux faire une egalité entre 2 tableaux de meme taille:

Worsheets("feuille2").Range("A1:N300").Value = Worsheets("feuille1").Range("A1:N300").Value

Cela fait la meme chose qu'un copier coller mais en plus rapide. Cela peu peut etre marcher entre un tableau Autocad et un tableau Excel. Essayes car c'est a mon avis la solution la plus rapide

A+
0
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 6
30 janv. 2008 à 19:53
le tableau où je stock mes données autocad est un tableau visual basic déclaré commesuit:
dim extrtab() as string
redim extrab(15,0)
j'augmente la taille de mon tableau par un classic redim preserve au fur et à mesure des besoins

c'est ce tableau que je transmet à la macro Excel par le biais d'un fichier texte pour qu'elle remplisse la Feuille Excell à partir de la lecture de ce fichier. de plus dans excel la macro qui rempli la feuille utilise rigoureusement les meme boucles que la macro Autocad quand c'est elle qui le fait
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 23
31 janv. 2008 à 00:26
Plutôt que ceci
.Cells.Delete Shift:=xlUp
fais plutôt
.Cells.Clear

Selon les versions ça pourrait accélérer cette partie, mais bon... ce n'est probablement pas vraiment ça qui ralentit le processus, si je comprends bien..

Tu pourrais aussi regarder du côté du DataObject d'Excel
Tu pourrais ouvrir ton fichier d'un seul coup avec LOF et utliser le DataObject pour copier encore là, d'un seul coup tes données.

MPi²
Pour ceux qui programment sous Office, n'oubliez pas qu'il existe un forum dédié à ces applications VBA....... ICI
0
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 6
31 janv. 2008 à 01:45
En fait je crois que je me suis mal expliqué.

For I = 0 To UBound(extrtab, 2)
        For J = 0 To UBound(extrtab, 1)
            feuille.Cells(I + 1, J + 1) = extrtab(J, I)
        Next J
    Next I
ma question est
pourquoi cette boucle placé dans une macro autocad met 5 minutes pour remplis une feuille excel de 3000 lignes
alors que placée dans une macro excel il ne lui faut plus que 12 secondes
0
cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 23
31 janv. 2008 à 01:53
L'Automation ?
Essaie d'utiliser une référence à Excel et la déclaration d'objets Excel plutôt que CreateObject...
Est-ce plus rapide ?

MPi²
Pour ceux qui programment sous Office, n'oubliez pas qu'il existe un forum dédié à ces applications VBA....... ICI
0
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 6
31 janv. 2008 à 02:04
euh !!!!!
Mpi  peux tu m'expliquer ce que tu entend par référence à excel et déclaration d'objet ?
car à te lire j'ai comme l'impression d'avoir ateint mon niveau d'incompétence
0
cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 23
31 janv. 2008 à 02:38
Bah non, c'est peut-être moi qui n'ai pas atteint ton niveau de compétence... En fait, je n'y connais rien à Autocad et VBA...

Tu gères Autocad à partir d'Excel ou Excel à partir d'Autocad ?

Comme tu sembles rechercher une session Excel, ça doit donc être à partir d'Autocad...oui ? Si c'est le cas, il y a peut-être un menu qui te pertte de dréer des références à divers objets comme des DLL ou OCX ou encore les applications Office, dont Excel...

Avant d'aller plus loin, est-ce que je me suis perdu entre les 2 limites des antipodes ?

MPi²
Pour ceux qui programment sous Office, n'oubliez pas qu'il existe un forum dédié à ces applications VBA....... ICI
0
pile_poil Messages postés 682 Date d'inscription vendredi 6 avril 2007 Statut Membre Dernière intervention 4 août 2012 6
31 janv. 2008 à 09:01
bah ! VBA est identique à quelques restrictions pres à VB6
et entre le VBA de Excel et celui de AutoCad il y a quelques petites nuances mais rien de bien méchant
différences qui tiennent surtout dans le fait que excel est en français et AutoCad en anglais
ainsi quand pour l'un quelque chose est VRAI elle est TRUE pour l'autre mais ce n'est pas cata à gérer et de plus dans le probleme qui m'intéresse il n'y a pas d'incompatibilité puisque entre les deux codes je n'ai fait pretiquement que du copier coller

En fait dans mon code le createobject et le getobject n'ont d'autre but que de créer une instance de Excel dans AutoCAD et moyenant
Set feuille = ExcelApp.Sheets("EXTRACT")
 je crée une liason avec  l'objet feuille de Excel et ensuite je peux dérouler mon code comme si j'étais dans une macro Excel
avec la contraine bien sûr de devoir toujours faire précéder l'action du nom de l'objet.
feuille.Cells(I + 1, J + 1) = extrtab(J, I)
dans excel la meme instruction s'écrit
Cells(I + 1, J + 1) = extrtab(J, I)

alors oui  il y a surement une façon différente de gérer les objets  Excel  mais là je ne sais pas faire du tout et de plus ne sait pas dans quelle direction chercher

il est certain que la solution de faire executer à Excel les macros le concernant est efficace mais cela m'oblige à avoir des macros des deux cotés et c'est plus lourd à adapter à chaque changement de version de l'un ou de l'autre des logiciels !
surtout d'ailleurs du coté office qui se fout royalement  de la compatibilité entre ses différentes versions !
et puis j'avoue avoir une certaine haine pour tout ce qui est microsoft alors je voudrais pouvoir n'avoir à faire à lui que le moins possible !
0
Rejoignez-nous