Formules par VBA

Résolu
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention   -  
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

Dans une feuille de classeur, j'ai un tableau de 2500 lignes dans lequel j'ai besoin d'insérer des RechercheV dans ses 126 colonnes ... la recherche porte sur une table de 5000 lignes et 137 colonnes....

Mettre les formules dans les 126 colonnes et 2500 lignes (soit 315 000 cellules) rend mon fichier inutilisable car beaucoup trop gros et trop lent.

Ainsi, j'aimerais savoir s'il est possible de passer par VBA pour effectuer les calculs et ne retranscrire que les résultats sur la feuille excel ?

Merci beaucoup de votre aide...

A voir également:

18 réponses

Morgothal Messages postés 1236 Date d'inscription   Statut Membre Dernière intervention   183
 
Salut,
Cette macro fonctionne, bien que je ne sois vraiment pas sûr qu'elle soit plus efficace que de "tirer" les formules sur le tableau :
Sub insere_recherchev()
Dim ligne, colonne As Long
Dim colrecherche, i As Long
Dim code As String

For ligne = 1 To 20
    For colonne = 1 To 10
        
        With Sheets("Import")
            code = .Cells(ligne + 4, 2)
            colrecherche = .Cells(2, colonne + 2)
        End With
               
        compteur = 1
        
        While Sheets("Liste Code").Cells(compteur + 4, 1) <> code
            compteur = compteur + 1
        Wend
        
        If Sheets("Liste Code").Cells(compteur + 4, colrecherche) <> " - " Then
            Sheets("Import").Cells(ligne + 4, colonne + 2) = Sheets("Import").Cells(ligne + 4, 1) * Sheets("Liste Code").Cells(compteur + 4, colrecherche)
        Else
            Sheets("Import").Cells(ligne + 4, colonne + 2) = 0
        End If
        
    Next colonne
Next ligne
End Sub 

A adapter bien evidemment en fonction des dimensions de ton tableau.
1
michel_m Messages postés 16602 Date d'inscription   Statut Contributeur Dernière intervention   3 314
 
Chose promise
pas besoin de trier
merci de me dire la durée d'éxécution suivant tes listes réelles pour mes statistiques et éventuellement amélioration de la rapidité

Option Explicit 

Sub calculer_montantsactionsparcode() 
Dim Derlig As Integer, Dercol_li As Byte, T_liste() 
Dim D_liste As Object, Lig As Integer 
Dim T_import(), Dercol_im As Byte 
Dim Cptr As Integer, Code As String, Col As Byte 
     'pour essai rapidité à supprimer à la livraison 
     Dim Start As Single 
     Start = Time 

Application.ScreenUpdating = False 
' -------Mise en mémoire RAM des données 
With Sheets("liste code") 
     Derlig = .Columns("A").Find("*", , , , , xlPrevious).Row 
     Dercol_li = .Rows(4).Find("*", , , , , xlPrevious).Column 
     'mémorisation tableau des coeffs des actions 
     T_liste = .Range(.Cells(5, "B"), .Cells(Derlig, Dercol_li)).Value 
     'creation dico couple code ligne 
     Set D_liste = CreateObject("scripting.dictionary") 
     For Lig = 5 To Derlig 
          D_liste.Add .Cells(Lig, "A").Value, Lig - 4 
     Next 
End With 

With Sheets("import") 
     Derlig = .Columns("A").Find("*", , , , , xlPrevious).Row 
     Dercol_im = .Rows(3).Find("*", , , , , xlPrevious).Column 
      'mémorisation tableau du montant des actions 
     T_import = .Range(.Cells(5, "A"), .Cells(Derlig, Dercol_im)).Value 


'------Remplissage du tableau des actions importées 
For Cptr = 1 To UBound(T_import) 
     Code = T_import(Cptr, 2) 
     If D_liste.exists(Code) Then 
          Lig = D_liste.Item(Code) 
          For Col = 1 To Dercol_li - 1 
               If IsNumeric(T_liste(Lig, Col)) Then 
                    T_import(Cptr, Col + 2) = T_liste(Lig, Col) * (T_import(Cptr, 1)) 
               Else 
                    T_import(Cptr, Col + 2) = T_liste(Lig, Col) 
               End If 
          Next 
     Else 
               T_import(Cptr, 2) = T_import(Cptr, 2) & " -code inconnu!" 
     End If 
Next 


  '------Restitution des montants suivant code et coeff 
  .Range("A5").Resize(UBound(T_import), Dercol_im) = T_import 
  .Activate 
End With 
     'pour essai rapidité à supprimer à la livraison 
     Application.ScreenUpdating = False 
     MsgBox ("calculs effectués en " & Time - Start & "  .secondes") 
End Sub 

Nota: j'ai considéré qu'il n'y avait pas de doublons dans la liste des codes feuilles liste et feuille import
si un code inconnu es importé, l'erreur est indiquée dans le tableau feuille import à ligne concernée


Michel
1
michel_m Messages postés 16602 Date d'inscription   Statut Contributeur Dernière intervention   3 314
 
bonjour
Écrire Timer au lieu de Time
(bug du lundi)
0
Morgothal Messages postés 1236 Date d'inscription   Statut Membre Dernière intervention   183
 
Bonjour,
Oui c'est possible.
Pour mieux t'aider, il faudrait que tu postes un extrait significatif de ton classeur sur ce fil, via cjoint.com par exemple. Tu pourras ensuite étendre la solution à tout ton classeur...
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

merci de cette réponse, un exemple du fichier est dispo à partir du lien suivant :
https://www.cjoint.com/?3Ihqs1CRKkF

Le premier onglet correspond à la feuille dans laquelle je mets les RechercheV et le deuxième onglet est la base sur laquelle porte la recherche.

merci beaucoup.
0

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

Posez votre question
eriiic Messages postés 24603 Date d'inscription   Statut Contributeur Dernière intervention   7 275
 
Bonjour,

Sans te compliquer la vie tu peux conserver tes formules sur la 1ère ligne (pour pouvoir les recopier pour une mise à jour) et faire un copier/collage spécial valeur sur toutes les autres lignes.

eric
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

Le problème est que lors de la mise à jour, je suis obligé de copier les formules sur toutes les lignes sauf que quand j'ai les 2500 lignes (au début, au fil du temps le nombre de ligne va vite augmenter) et les 126 colonnes, le temps de calcul de la formule est beaucoup trop lent.... enfin si je comprends bien ce que tu me dis...

lionel.
0
eriiic Messages postés 24603 Date d'inscription   Statut Contributeur Dernière intervention   7 275
 
Bonjour,

déjà si tu enlèves les "-" du 2nd tableau ta formule devient :
=RECHERCHEV($B5;'Liste Code'!$B$4:$L$24;C$2;0)*$A5

Et si tous tes codes sont présents et triés dans les 2 listes, tu insères une colonne A dans le tableau 2 et ta formule devient :
='Liste Code'!D5*$A5

Pour recopier les formules : sélectionner C5:L5 et faire un double-clic sur la poignée de recopie (petit carré noir en bas à droite de la sélection).

Teste déjà comme ça, pour faire un code vba le plus rapide possible il faudrait savoir si tous les codes sont présents et peuvent être (ou sont) triés.
Mais pas sûr qu'il soit beaucoup plus rapide si tu peux utiliser la formule réduite.

eric
0
michel_m Messages postés 16602 Date d'inscription   Statut Contributeur Dernière intervention   3 314
 
bonjour,

patience je te proposerai une macro en fin d'après-midi
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Merci à tous pour vos réponses,

Eric, je ne peux pas utiliser la deuxième formule la plus réduite car il peut y avoir plusieurs lignes dans l'onglet 1 avec les mêmes codes mais avec des données différentes. Je peux par contre effectivement utiliser la première formule réduite. Merci.

Morgothal et michel_m, merci pour le code, je teste tout ça et vous tiens au courant. Merci.
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour à tous,

Tout d'abord, à nouveau merci de vos contributions.

J'ai donc intégré le code de michel_m et sa marche super... Pour info, il faut 2,4 secondes pour le calcul de 1200 lignes et 126 colonnes...

Bonne continuation.
Lionel
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour à tous,

Je reviens vers vous suite au fait que vous m'avez super bien aidé lors de mon premier problème et qu'un nouveau problème un peu similaire arrive...

En fait, dans un classeur, j'ai deux onglets constitués pour chacun d'eux d'une base de données dont le nombre de colonnes et les intitulés de champs de colonnes sont identiques.
Les deux bases sont sensées être identiques mais ce n'est pas le cas...

L'objectif est donc de pouvoir identifier, en affichant (dans un troisième onglet ?) les différences entre les bases en indiquant ou se trouve la différence (Différence sur le Champ1 ?, ligne manquante dans l'autre base ?, différence sur le champ 3 ?, ....).

J'ai essayé en mettant des formules en fin de tableau (dans l'onglet Base2), cela me donne les bons résultats mais le problème est que la vrai version du fichier comporte environ 16 000 lignes par onglet et en reproduisant les formules pour les 12 colonnes de recherche, cela allourdi beaucoup trop le fichier....

Ainsi, pensez-vous qu'il serait possible de faire ces recherches via un code VBA ? Si oui, pourriez-vous m'aider à le trouver car je n'en suis hélas pas capable tout seul...

En recherchant sur les forums, j'ai trouvé comment faire des recherche via VBA mais cela ne suffit pas.

Voici le lien vers l'exemple du fichier en question :
https://www.cjoint.com/?3AxlpztwD4W

Merci beaucoup de votre aide.
0
michel_m Messages postés 16602 Date d'inscription   Statut Contributeur Dernière intervention   3 314
 
Bonjour,

Il y a plusieurs solutions mais je ne sais pas encore laquelle sera la moins longue
je regarderai tout en fin d'après-midi

mais peut-^tre lire ces conseils de Microsoft pour de "prochaines aventures" :o)
https://support.microsoft.com/fr-fr/office/utiliser-access-ou-excel-pour-g%c3%a9rer-vos-donn%c3%a9es-09576147-47d1-4c6f-9312-e825227fcaea?ocmsassetid=ha010210195&correlationid=d29af1f8-4e74-4502-b994-3b1f030cc1ff&ui=fr-fr&rs=fr-fr&ad=fr#BM2
0
Morgothal Messages postés 1236 Date d'inscription   Statut Membre Dernière intervention   183
 
Bonjour,
Ce code écrit en Feuil3, colonne A l'identifiant de la ligne où il y a une différence, et en colonne B quelle colonne et quelle ligne est différente.

Tu devrais pouvoir retrouver les différences via ces 3 informations.

Sub compare_bases()

Dim ligne, colonne, i, derlig As Integer

i = 1
derlig = Sheets(1).Range("A65500").End(xlUp).Row
For ligne = 2 To derlig
    For colonne = 1 To 12

        With Sheets(1)
            If .Cells(ligne, colonne) <> Sheets(2).Cells(ligne, colonne) Then
                If colonne <> 2 Then
                    Sheets(3).Cells(i, 1) = .Cells(ligne, 1)
                    Sheets(3).Cells(i, 2) = .Cells(1, colonne) & " à la ligne " & ligne
                    i = i + 1
                    Exit For
                End If
            End If
        End With
        
    Next
Next

End Sub

Je reste sur ce fil au cas ou ça ne répondrait pas au besoin !

A+
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour à vous deux,

Merci pour ce code qui fonctionne bien. Je vais essayer de l'adapter au résultat tel que je veux qu'il apparaisse.

En effet ce code répond au besoin tel que je l'ai formulé mais je n'ai pas été très bon dans l'explication du besoin du niveau de détail du résultat que je cherche.

En fait, j'aimerais que le résultat prenne la forme de l'onglet 3 tel que je le présente dans le fichier ci-après :
https://www.cjoint.com/?3AxoXw4Od0L

Merci beaucoup.
0
Morgothal Messages postés 1236 Date d'inscription   Statut Membre Dernière intervention   183
 
Re,
J'ai essayé de faire cette comparaison en VBA, le résultat est un peu lourdingue mais je n'ai pas réussi à trouver mieux ...
Voilà le fichier avec la macro.

A+ !
0
michel_m Messages postés 16602 Date d'inscription   Statut Contributeur Dernière intervention   3 314
 
Bon! j'arrivais avec une solution sur 5000 lignes (données bidon) durée < 1,5 secondes et crac! il faut que je refasse tout car l'énoncé était bâclé , faux et bien entendu sans un petit "excusez moi"...

2 heures de boulot bénévole pour rien!!!
donc pas question de passer ne serait ce qu'une minute sur ce B....L

Michel
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Merci Clément pour le code. Le résultat est déja très satisfaisant.

Michel, c'est vrai, je ne me suis pas escusé mais j'ai quand même admis que je n'avais pas été bon dans mon énoncé. J'ai posté le message avant même d'être moi même très clair dans ma tête sur ce que j'attendais exactement....

En tout cas, je suis très reconnaissant du travail que vous pouvez faire pour aider les autres, si je ne me suis pas excusé, ce n'est vraiment pas parceque je sous-estime votre travail et le temps que vous passez.

Je suis donc désolé si je vous ai fait perdre votre temps et je vous remercie quand même, à la fois pour les réponses à ce message et encore une fois pour les réponses à mon précédent problème...
0
lp.paris Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour à tous,

Bon, pour cloturer et au cas où d'autres auraient la même problématique que moi, voici ce que j'ai fait et qui donne le résultat attendu :
https://www.cjoint.com/?0AypXfiwFPm

C'est pas super satisfaisant en termes de temps de traitement (environ 8 minutes pour 20 000 lignes) mais c'est du bricolage amateur et sa répond au problème...

Si sa peut servir à quelqu'un ou si quelqu'un a des idées pour améliorer les temps de traitement...

Merci pour les précédentes contributions...

Lionel
0