HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

tofprod

XLDnaute Nouveau
Bonjour à tout le monde,

Je suis déjà depuis pas mal de temps votre forum, j'y ai trouvé de nombreuses réponses à mes bribes de développement vba, une vraie mine d'infos très utiles !
N'étant pas un pro de vba (je me contente, et jusque là ça marche) de copier/coller des bouts de code pour arriver à mes fins. Seulement aujourd'hui et après un week-end d'arrachage de cheveux, je viens vers vous pour un p'tit coup de main.

j'ai un tableau (cf pj) composé d'une feuille "récap" (fixe), et de plusieurs feuilles "devis" (quantité de feuilles importées aléatoire, nom aléatoire, toujours la même mise en forme).

Je souhaite (tout simplement ... !) afficher dans mon "récap" la somme de chaque numéro de prix figurant dans toutes les feuilles (quelque soit le nom et le nombre).

Quelqu'un a t-il une soluce ? Merci d'avance
 

Pièces jointes

  • bordereau.xlsx
    28.6 KB · Affichages: 59

Modeste

XLDnaute Barbatruc
Re : HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

Bonjour tofprod et bienvenue à toi,

Je souhaite (tout simplement ... !) afficher dans mon "récap" la somme de chaque numéro de prix figurant dans toutes les feuilles
... Euh ... et que seraient les "numéros de prix" :confused:


D'autre part, avec tes petits bouts de code glânés à droite ou à gauche, tu n'avais pas de quoi rédiger une partie du code? Que penserais-tu d'utiliser l'événement Activate de la feuille Recap, pour mettre à jour le calcul?
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

Bonjour Tofprod et bienvenu, Modeste, bonjour le forum,

peut-être comme ça :

Code:
Sub Macro1()
Dim o As Object 'déclare la variable o (Onglet)
Dim d1 As Object 'déclare la variable d1 (Dictionnaire 1)
Dim d2 As Object 'déclare la variable d2 (Dictionnaire 2)
Dim tb1 As Variant 'déclare la variable tb1 (TaBleau 1)
Dim tb2 As Variant 'déclare la variable o (TaBleau 2)
Dim t() As Integer 'déclare le tableau de variables indéxées t (Total)

'**********************************************************************************
'récupère l'ensemble des "Nº de prix" du classeur sans doublon dans le tableau tb1
'récupère l'ensemble des "Désignation" du classeur sans doublon dans le tableau tb2
'**********************************************************************************
Set d1 = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 1
Set d2 = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 2
For Each o In Sheets 'boucle 1 : sur tous les onglet du classeur
    If Not o.Name = "RECAP" Then 'condition : si les nom de l'onglet n'est pas "RECAP"
        For Each cel In o.Range("A3:A31") 'boucle 2 : sur toutes les cellules cel de la plage A3:A31
            If cel.Value <> "" Then d1(cel.Value) = "" 'si la cellule n'est pas vide alimente le dictionnaire 1 "Nº prix"
            If cel.Value <> "" Then d2(cel.Offset(0, 1).Value) = "" 'si la cellule n'est pas vide alimente le dictionnaire 2 "Désignation"
        Next cel 'prochaine cellule de la boucle 2
    End If 'fin de la condition
Next o 'prochain onglet de la boucle 1

'************************************************************
'calcul des totaux dans le tableau de variables indexées t(i)
'************************************************************
ReDim t(d1.Count - 1) 'redimentionne le tableau des totaux t
tb1 = d1.keys 'récupère les Nº de prix sans doublons dans le tableau tb1
tb2 = d2.keys 'récupère les désignations dans le tableau tb2
For i = 0 To UBound(tb1) 'boucle 1 : sur tous les Nº de prix du tableau tb1
    For Each o In Sheets 'boucle 2 : sur tous les onglets du classeur
        If Not o.Name = "RECAP" Then 'condition : si les nom de l'onglet n'est pas "RECAP"
            On Error Resume Next 'gestion des erreurs (passe à la ligne suivante si une erreur a été générée)
            'définit le total t(i) (génère une erreur si le Nº de prix n'esxiste pas dans l'onglet o
            t(i) = t(i) + CInt(o.Range("A1:A31").Find(tb1(i), , xlValues, xlWhole).Offset(0, 2))
            If Err <> 0 Then Err = 0 'si une erreur a été gérérée, annule l'erreur
        End If 'fin de la condition
        On Error GoTo 0 'annule la gestion des erreurs
    Next o 'prochain onglet de la boucle 2
Next i 'prochain Nº de prix de la boucle 1

'*******************************************
'placement des données dans l'onglet "RECAP"
'*******************************************
Sheets("RECAP").Range("A4").Resize(d1.Count) = Application.Transpose(tb1) 'place les "Nº de prix" en A4 de l'onglet "RECAP"
Sheets("RECAP").Range("B4").Resize(d1.Count) = Application.Transpose(tb2) 'place les "Désignation" en B4 de l'onglet "RECAP"
Sheets("RECAP").Range("C4").Resize(d1.Count) = Application.Transpose(t) 'place les "Totaux" en C4 de l'onglet "RECAP"
End Sub
 

tofprod

XLDnaute Nouveau
Re : HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

Re-salut, bon ça a mis un peu de temps avant que je pige ! Merci encore pour ce magnifique coup de main, ça marche NICKEL (j'avoue que c'est quand même agaçant de voir la facilité avec laquelle vous traitez le sujet, et le temps passé (sans résultat :( pour un médiocre newbies comme moi :). J'ai un peu customisé le code en rajoutant un tableau pour les unités, puis un ptit Activate comme le suggère modeste.

Une dernière question ; je risque d'avoir des doublons (ex : 1 numéro de prix correspondant à 2 désignations différentes) car dans cette base, j'importe des anciennes saisies où des fois c'est un peu le boxon.

Où puis-je insérer un msgbox d'alerte pour sortir des boucles en indiquant le doublon ? (j'ai essayé, ça bugge (comme souvent avec moi))

Voici le code complété
Code:
Dim o As Object 'déclare la variable o (Onglet)
Dim d1 As Object 'déclare la variable d1 (Dictionnaire 1)
Dim d2 As Object 'déclare la variable d2 (Dictionnaire 2)
    Dim d3 As Object 'déclare la variable d3 (Dictionnaire 3)
    Dim d4 As Object 'déclare la variable d4 (Dictionnaire 4)
Dim tb1 As Variant 'déclare la variable tb1 (TaBleau 1)
Dim tb2 As Variant 'déclare la variable o (TaBleau 2)
    Dim tb3 As Variant 'déclare la variable tb3 (TaBleau 3)
    Dim tb4 As Variant 'déclare la variable tb4 (TaBleau 4)
Dim t() As Integer 'déclare le tableau de variables indéxées t (Total)

'**********************************************************************************
'récupère l'ensemble des "Nº de prix" du classeur sans doublon dans le tableau tb1
'récupère l'ensemble des "Désignation" du classeur sans doublon dans le tableau tb2
'récupère l'ensemble des "Unité" du classeur sans doublon dans le tableau tb3
'récupère l'ensemble des "Prix unitaire" du classeur sans doublon dans le tableau tb4
'**********************************************************************************
Set d1 = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 1
Set d2 = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 2
    Set d3 = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 3
    Set d4 = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 4
For Each o In Sheets 'boucle 1 : sur tous les onglet du classeur
    If Not o.Name = "RECAP" Then 'condition : si les nom de l'onglet n'est pas "RECAP"
        For Each cel In o.Range("A3:A31") 'boucle 2 : sur toutes les cellules cel de la plage A3:A31
            If cel.Value <> "" Then d1(cel.Value) = "" 'si la cellule n'est pas vide alimente le dictionnaire 1 "Nº prix"
            If cel.Value <> "" Then d2(cel.Offset(0, 1).Value) = "" 'si la cellule n'est pas vide alimente le dictionnaire 2 "Désignation"
                If cel.Value <> "" Then d3(cel.Offset(0, 3).Value) = "" 'si la cellule n'est pas vide alimente le dictionnaire 3 "Unité"
                If cel.Value <> "" Then d4(cel.Offset(0, 4).Value) = "" 'si la cellule n'est pas vide alimente le dictionnaire 4 "Prix Unitaire"
        Next cel 'prochaine cellule de la boucle 2
    End If 'fin de la condition
Next o 'prochain onglet de la boucle 1

'************************************************************
'calcul des totaux dans le tableau de variables indexées t(i)
'************************************************************
ReDim t(d1.Count - 1) 'redimentionne le tableau des totaux t
tb1 = d1.keys 'récupère les Nº de prix sans doublons dans le tableau tb1
tb2 = d2.keys 'récupère les désignations dans le tableau tb2
    tb3 = d3.keys 'récupère "unité" dans le tableau tb3
    tb4 = d4.keys 'récupère "prix unitaire" dans le tableau tb4
For i = 0 To UBound(tb1) 'boucle 1 : sur tous les Nº de prix du tableau tb1
    For Each o In Sheets 'boucle 2 : sur tous les onglets du classeur
        If Not o.Name = "RECAP" Then 'condition : si les nom de l'onglet n'est pas "RECAP"
            On Error Resume Next 'gestion des erreurs (passe à la ligne suivante si une erreur a été générée)
            'définit le total t(i) (génère une erreur si le Nº de prix n'esxiste pas dans l'onglet o
            t(i) = t(i) + CInt(o.Range("A1:A1000").Find(tb1(i), , xlValues, xlWhole).Offset(0, 2))
            If Err <> 0 Then Err = 0 'si une erreur a été gérérée, annule l'erreur
'            MsgBox "un doublon a été détecté, le calcul est à vérifier"
        End If 'fin de la condition
        On Error GoTo 0 'annule la gestion des erreurs
    Next o 'prochain onglet de la boucle 2
Next i 'prochain Nº de prix de la boucle 1

'*******************************************
'placement des données dans l'onglet "RECAP"
'*******************************************
Sheets("RECAP").Range("A3").Resize(d1.Count) = Application.Transpose(tb1) 'place les "Nº de prix" en A3 de l'onglet "RECAP"
Sheets("RECAP").Range("B3").Resize(d1.Count) = Application.Transpose(tb2) 'place les "Désignation" en B3 de l'onglet "RECAP"
Sheets("RECAP").Range("C3").Resize(d1.Count) = Application.Transpose(t) 'place les "Totaux" en C3 de l'onglet "RECAP"
Sheets("RECAP").Range("D3").Resize(d1.Count) = Application.Transpose(tb3) 'place les "Unité" en D3 de l'onglet "RECAP"
Sheets("RECAP").Range("E3").Resize(d1.Count) = Application.Transpose(tb4) 'place les "Prix Unitaire" en E3 de l'onglet "RECAP"

Merci,
 

tofprod

XLDnaute Nouveau
Re : HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

Excusez-moi pour cette question subsidiaire ; j'ai des #N/A et des mauvaises correspondances sur ma colonne unité, comme on peut le voir sur le code du post précédent, j'ai reproduit les tables à l'identique, tout marche excepté cette colonne unité... Quelle ligne ai-je mal saisi ? Merci d'avance et bonne soirée.
PS : je remets le xlsm en pj pour mieux visualiser...
 

Pièces jointes

  • bordereau.xlsm
    52.3 KB · Affichages: 65
  • bordereau.xlsm
    52.3 KB · Affichages: 77
  • bordereau.xlsm
    52.3 KB · Affichages: 70

Robert

XLDnaute Barbatruc
Repose en paix
Re : HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

Bonjour le fil, bonjour le forum,

En pièce jointe ton fichier modifié. J'ai résolu le problème des unités mais pas celui des doublons... Il te faudrait passer, je pense, par une référence unique tenant compte du Nº de prix et de la Désignation.
Le code :

Code:
Sub LotAPS()
Dim o As Object 'déclare la variable o (Onglet)
Dim d As Object 'déclare la variable d1 (Dictionnaire)
Dim tcle As Variant 'déclare la variable tcle (Tableau des CLÉs)
Dim tit As Variant 'déclare la variable tit (Tableau des ITems)
Dim t() As Integer 'déclare le tableau de variables indéxées t (Total)

Application.ScreenUpdating = False
ActiveSheet.Unprotect

'**********************************************************************************
'récupère l'ensemble des "Nº de prix" du classeur sans doublon dans le tableau tcle
'**********************************************************************************
Set d = CreateObject("Scripting.Dictionary") 'définit le dictionnaire 1
For Each o In Sheets 'boucle 1 : sur tous les onglets du classeur
    If Not o.Name = "RECAP" Then 'condition : si le nom de l'onglet n'est pas "RECAP"
        For Each cel In o.Range("A7:A1000") 'boucle 2 : sur toutes les cellules cel de la plage A7:A1000
            If cel.Value <> "" Then If Not d.exists(cel.Value) Then d.Add cel.Value, o.Name & "/" & cel.Row 'si la cellule n'est pas vide alimente le dictionnaire d
        Next cel 'prochaine cellule de la boucle 2
    End If 'fin de la condition
Next o 'prochain onglet de la boucle 1
tcle = d.keys 'récupère les Nº de prix sans doublons dans le tableau tcle (clés)
tit = d.items 'récupère les nom de l'onglet et numéro de ligne dans le tableau tit (items)

'************************************************************
'calcul des totaux dans le tableau de variables indexées t(i)
'************************************************************
ReDim t(d.Count - 1) 'redimentionne le tableau des totaux t
For i = 0 To UBound(tcle) 'boucle 1 : sur tous les Nº de prix du tableau tb1
    For Each o In Sheets 'boucle 2 : sur tous les onglets du classeur
        If Not o.Name = "RECAP" Then 'condition : si les nom de l'onglet n'est pas "RECAP"
            On Error Resume Next 'gestion des erreurs (passe à la ligne suivante si une erreur a été générée)
            'définit le total t(i) (génère une erreur si le Nº de prix n'esxiste pas dans l'onglet o
            t(i) = t(i) + CInt(o.Range("A7:A1000").Find(tcle(i), , xlValues, xlWhole).Offset(0, 2))
            If Err <> 0 Then Err = 0 'si une erreur a été gérérée, annule l'erreur
        End If 'fin de la condition
        On Error GoTo 0 'annule la gestion des erreurs
    Next o 'prochain onglet de la boucle 2
Next i 'prochain Nº de prix de la boucle 1

'*******************************************
'placement des données dans l'onglet "RECAP"
'*******************************************
With Sheets("RECAP") 'prend en compte l'onglet "RECAP"
    .Range("A7").Resize(d.Count) = Application.Transpose(tcle) 'place les "Nº de prix" en A7 de l'onglet "RECAP"
    .Range("C7").Resize(d.Count) = Application.Transpose(t) 'place les totaux en C7 de l'onglet "RECAP"
    For i = 0 To UBound(tit)
        .Cells(i + 7, 2).Value = Sheets(Split(tit(i), "/")(0)).Cells(Split(tit(i), "/")(1), 2)
        .Cells(i + 7, 4).Value = Sheets(Split(tit(i), "/")(0)).Cells(Split(tit(i), "/")(1), 4)
        .Cells(i + 7, 5).Value = Sheets(Split(tit(i), "/")(0)).Cells(Split(tit(i), "/")(1), 5)
        .Cells(i + 7, 6).Value = Sheets(Split(tit(i), "/")(0)).Cells(Split(tit(i), "/")(1), 6)
    Next i
End With 'fin de la prise en compte de l'onglet "RECAP"

'*******************************************
'Tri des Numéros d'articles
'*******************************************
    ActiveWorkbook.Worksheets("RECAP").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("RECAP").Sort.SortFields.Add Key:= _
        Range("A7:FIN"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    With ActiveWorkbook.Worksheets("RECAP").Sort
        .SetRange Range("A7:FIN")
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True, AllowSorting:=True
ActiveSheet.EnableSelection = xlUnlockedCells
Application.ScreenUpdating = True
End Sub
Le fichier :
 

Pièces jointes

  • Tofprod_v01.xlsm
    50.7 KB · Affichages: 49

tofprod

XLDnaute Nouveau
Re : HELP ! Recherche valeurs et somme sur un nombre (et noms) de feuilles aléatoires

ça y est ça marche ! j'ai remis une petite protection pour éviter le bug en cas de page unique. Pour les doublons, je pense que n'étant pas expert, je vais mettre une alerte en début de phrases, ça limitera un peu les erreurs de saisie...
Merci et bonne journée à tous
 

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
312 215
Messages
2 086 329
Membres
103 185
dernier inscrit
salhit