AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006
-
6 sept. 2006 à 22:41
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006
-
11 sept. 2006 à 16:27
Hey there, bon ben deja obnjour a tous (c'est mon premier post :)), et déja ça commence bien je suis pas sur d'avoir posté dans la bonne section lol.
Enfin bon, voila je debute en vba mais j'ai quelques connaissances en VB. En fait pour mon stage, je dois faire un appli (vb6) pour ma boss à partir de vb6 et qui utilise des fichiers excel et .csv.
L'un des premiers truc que j'ai à faire c'est cheker une liste dans un fichier .csv (donc tout les champ une colonne quoi) avec un autre liste dans un autre fichier. En gros, disons que dans un fichier excel j'ai une liste de nouvel recette(une recette par champ) et que je veux cheker si elles sont déja présente dans le livre de recette (toujours un recette par champ).
Donc tout happy, je fais ma connection aux deux fichiers, je fais une double boucle tout ce qu'il y a de plus normal, et la c'est le drame... ça prend un temps terrible... Bon il faut imaginer que la liste des nouvelles recette a 1000 entree et que le livre de recette en a 10000, la d'accord on peut comprendre que ça prenne longtemps. Moi aussi je suis d'accord.
Mon code:
'Check receipts
Set eWorkSheet1 = exl.Worksheets(2)
If Form2.Check1 = "1" Then
'Sales
i = 2
a = a + 5
While eWorkSheet.Cells(i, 5) <> "" 'les cellules de mes recettes a cheker
u = False
b = 2
While eWorkSheet1.Cells(b, 1) <> "" And u = False ' tant que je trouve pas la recette dans le book (si je la trouve ça break)
If eWorkSheet.Cells(i, 5) = eWorkSheet1.Cells(b, 1) Then '
u = True
End If
b = b + 1
Wend
If u = False Then 'je ne fais pas dajout direct mais je sort dans un autre fichier les recettes a rajouter
eWorkSheet2.Cells(a, 1) = "The receipt" & eWorkSheet.Cells(i, 5) & " has to be added to the receipt book."
a = a + 1
End If
End If
i = i + 1
Wend
End If
Print "Brands checked"
Maintenant, on en arrive à la partie que je compre po :
Jusqu'a présent ma boss utilisait cette macro excel pour faire le truc:
Et en fait en utilisant ça, ça va genre facilement 20 fois plus vite...
Donc ma premiere question c'est : Est-ce que ça va plus vite du fait que tout le boulot est fait sous excel et que du fait que je developpe mon projet sous vb6 la connection avec les deux fichier ralenti le traitement (fasse à la fonction VLOOKUP donc notamment); ou est-ce que je m'y suis simplement pris comme un manche?(si oui, i beg your pardon, excel et vb ensemble, j'etais vierge il y a deux jours xD).
Ensuite j'aimerais savoir sil es tpossible d'utiliser des fonction comme vlookup directement depuis vb6 par example dans l'optique de faire aller mon traitement à la meme vitesse que feu la macro de ma boss?
En vous remerciant d'avance, pour toute aide, réponse, etc...
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 8 sept. 2006 à 11:14
Ben, on est bien d'accord que la je recherche si ce que contient chaque cellule de la colonne 1 de ma feuille 1 est deja dans la colonne 1 de ma feuille 2? J'aimerais avoir un retour: "oui je lai trouver" ou "non, je ne l'ai pas trouver".
Cela dans loptique de faire juste un rapport a la fin (ou un gros msgbox) "oui il faut ajouter la(les recettes lignes) des lignes: x, y z, etc.... au livre de recette"
Par contre, un Dim ilier as boolean
ilier = Call ........ , vb n'apprecie pas trop.
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 8 sept. 2006 à 11:49
Bon j'ai rien dit en fait: j'ai maintenant :
While eWorkSheet.Cells(i, 2) <> ""
Call eWorkSheet1.Columns(1).Find(eWorkSheet.Cells(i, 2), , , , xlByRows, xlNext)
i = i + 1
Wend
ça passe nikel sur les petits fichier a tester: ~10 000 ligne.
mais bon sur ceux de 60 000 = overflow :c
Le truc maintenant c'est que j'hesite a continuer sur le find (sachant que les plus gros fichiers passerons pas >.<. Ou a tenter de trouver un autre moyen qui me permette de les traiter.
Genre "coller" le find dans une case du fichier excel et apres juste faire une boule pour voir sil a trouver ou pas les truc:
Fichier 1 a cheker:
A B C
Recette1 donc coller le find ici pour qu'il me mette un jai trouver ou non
Recette2
Recette3
Recette4
Recette5
Recette6
...
Recette70000 et tirer le truc jusque la
Puis ensuite juste parcourir une fois la colonne c a partir de vb pour relever les index des recettes a ajouter.
De toute evidence le overflow vient de VB, donc peut etre que cette methode eviterait a vb de saturer puisque tout le traitement se ferait sous excel, tu penses pas?
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 8 sept. 2006 à 14:03
Jai tester ta methode elle est cool, cependant j'ai encore ce putain d'overflow... J'ai donc simplement tester de faire des prints sur 60000 lignes:
While i < 60000
eWorkSheet.Cells(i, 2)="test"
i=i+1
Wend
J'ai toujours l'overflow. J'en conclu que vb ne gere pas un fichier excel depassant une certaine taille (en quantiter de rows columns).
Maintenant ma nouvel question se rapporte a mon post precedent. Pensez vous qu'il soit possible de faire faire tout les traitement sous excel sans aucune boucle sous vb?
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 8 sept. 2006 à 14:06
dsl post pas fini: je sais que je ne pourrais pas retourner les resultats pour chaque rows a VB pour le ;ontrer a l'utilisateur, ça overflowerait de nouveau, il faudrait je sais pas mettre les resultats dans un nouveau fichier excel pourquoi pas...
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 8 sept. 2006 à 14:17
Sinon, une question tres conne... je peux pas faire ça en tant que macro excel que je mettrais en module dans mon appli vb. Et faire en sorte que une fois que j'ouvre mon fichier excel, celui-ci utilise la dites macro?
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 9 sept. 2006 à 19:29
Après différents tests
- méthode Find
- Copie de formules et recherche des erreurs
- Copie des valeurs dans des tableaux et vérification de ceux-ci
La dernière méthode semble être la plus rapide, mais c'est long quand même.
Il y a une bonne différence entre travailler sous Excel directement et via VB.
Mon test consistait à vérifier deux onglets de 60000 lignes chacun
Pour accélérer la recherche, il faudrait que le tableau recherché
diminue à chaque item identique. Je sais comment ajouter des items
dynamiquement à un tableau (Redim Preserve), mais je ne vois pas
comment éliminer de façon rapide un item rendu inutile (?) La recherche
en serait accélérée pas mal.
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 9 sept. 2006 à 20:09
Bon ben la façon la plus rapide que j'ai trouvée est de copier les
nouvelles données à vérifier dans un tableau, de mettre les données
originales dans une String et d'utiliser Instr() Environ 4 à 5 minutes
pour vérifier 60000 données dans les 2 classeurs (Celeron 1.2 GHz)
Comme j'ai utilisé des chiffres pour créer mes données (plus rapide),
je dois modifier ces données en String, séparées par un point-virgule
pour bien identifier chaque valeur. Ce ne sera possiblement pas
nécessaire pour toi (?)
Private Sub Form_Load()
Set xlApp = New Excel.Application
Set xlBook1 = xlApp.Workbooks.Open(App.Path & "\Classeur1.xls")
Set xlSheet1 = xlBook1.Sheets("Feuil1")
Set xlBook2 = xlApp.Workbooks.Open(App.Path & "\Classeur2.xls")
Set xlSheet2 = xlBook2.Sheets("Feuil1")
End Sub
Private Sub Form_Unload(Cancel As Integer)
xlApp.Quit
Set xlBook1 = Nothing
Set xlSheet1 = Nothing
Set xlBook2 = Nothing
Set xlSheet2 = Nothing
Set xlApp = Nothing
End Sub
Private Sub Command1_Click()
Dim I As Long, nbLignes As Long, strTemp As String, strResult As String
Dim Tablo2() As String
Dim Temps As Single
Temps = Timer 'pour calculer le temps
'copier le "nouveau" classeur et mettre les données entre guillemets et ;
En fait t'as rentré desz séries de dix chiffre à chaque fois? Mes recettes ne sont souvent pas terminer par un . donc je vois pas trop comment savoir quelle est la fin.
J'avais fait un truc sumilaire au début. J'avais prix les données du premier fichier pour les mettres dans un tableau en éliminant les doublons. On doit arriver a diviser les recettes à verifier par 40 de cette maniere et je stockait les numeros de ligne aussi. J'avais un tableau pour les recettes et un pour les lignes ou elles étaient présentes.
Genre nameR() et rowR()
clafoutit 3;7;9
tarete tatin 5;6
etc...
Ouais c'est important que je note à quelles lignes sont les trucs a checker et je vois pas comment les chopper en fait avec le coup du... jai rien dit
Je vais garder ta méthode sur la fin je pense avec le coup de topper tout les trucs deja existant dans un chaine ça semble bien malin ça.
Et je vais refaire comme j'avais fait un tableau pour le nouveau classeur mais faut que je trouve un feinte pour a la fois eliminer les doublons et arriver a garder les numeros de lignes ou les recettes sont présentes.
Et ci au final le temps pue soit je lenvoi chier car faut le dire avec ses macros en 5 minutes c'est fait aussi... Hé mais attends si c'est fait en 5 minutes c'est bon... Jsui dans les temps... Sweet vais faire marcher tout ça au boulot demain.
P.S. Note que ça faisait deux jours que je cherchait sil y avait pas moyen de faire ça plus vite avec des copiers collers de vba pour que le traitement se fasse sous excel :x.
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 10 sept. 2006 à 16:57
Sinon oui pour la seconde partie, on mettre des ; n'est pas necessaire nan? Vu qu'on le laisera dans la chaine.
Sinon oui je vais faire comme ça pour la premiere phase:
Je vais lire à la main chaque donnée de ma colonne, à chaque ligne je mettrais dans un String temp=worksheet(i,2) , puis je testerais si temp est deja dans mon tableau. S'il n'y est pas je l'ajoute, sil y est déja j'ajoute juste le numéro de la ligne. Sinon je suis con j'ai oublier si les tableau à deux dimension existaient en VB (jvais verifier ça lol). Sinon oui, tu pense que chopper toutes les donnée une par une est moins efficient que ton GetText (dont j'ignorais l'existance [tu m'as appris un truc la{merci}]).
AlexDam
Messages postés31Date d'inscriptionmercredi 6 septembre 2006StatutMembreDernière intervention10 octobre 2006 11 sept. 2006 à 16:27
J'ai fini... enfin... on a fini lol. Ouais j'ai juste fais en sorte que le premier tableau n'ai pas de doublons. Comme ça:
Dim k As Integer
For k = 0 To 3000
namep(k) = ""
rowp(k) = ""
Next k
a = 0
i = 2
Dim tempcell As String
Print "aa"
tempcell = eWorkSheet.Cells(i, 2)
Print "a"
While tempcell <> ""
bool = False
k = 0
While k <3000 And bool False And namep(k) <> ""
If tempcell = namep(k) Then
bool = True
rowp(k) = rowp(k) & ";" & i
End If
k = k + 1
Wend
If bool = False Then
namep(a) = tempcell
rowp(a) = i
a = a + 1
End If
i = i + 1
tempcell = eWorkSheet.Cells(i, 2)
Wend
Et bon donc en supprimant tout les doublons je fais trois fois la recherche (trois colonne en fait ^^) et je fais un rapport dans un autre fichier excels des trucs a rajouter le tout en 4 minutes pour un fichier a checker de 60 000 row... autant dire que ça pete!
Donc voila jvoulais vous remercier tout les deux qui avez passer du temp a m'aider pour ma merde. Donc voila /bow ^.~ J'y serais peut etre aussi arriver sans vous mais vous m'avez aider a gagner pas mal de temps.
A plouche sur le forum (pas forcement en tant que mendiant comme cette fois :-))