pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDernière intervention 4 août 2012
-
30 janv. 2008 à 18:32
pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDerniè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 )
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201822 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
pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDernière intervention 4 août 20126 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 !!!!!
bigfish_le vrai
Messages postés1835Date d'inscriptionvendredi 13 mai 2005StatutMembreDernière intervention20 novembre 201314 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:
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
pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDernière intervention 4 août 20126 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
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201822 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
pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDernière intervention 4 août 20126 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
pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDernière intervention 4 août 20126 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
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201822 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
pile_poil
Messages postés682Date d'inscriptionvendredi 6 avril 2007StatutMembreDernière intervention 4 août 20126 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 !