XL 2010 Paramétrer une macro pour charger un ou plusieurs tableaux

KIM

XLDnaute Accro
Bonjour le Forum, bonjour les ami(e)s,
Avec les modules de classe de Dranreb que j'en remercie vivement ainsi que le forum, j'ai créé une macro T_ParOP_DR_SITE_vT012 de synthèse avec en finale 3 tableaux liés TS, TSdr et TSop à charger dans une seule feuille (FT02) à partir de la ligne 4.
Application.EnableEvents = False
FT02.[A4].Resize(1000000, CFin).ClearContents
FT02.[A4].Resize(L, CFin).Value = TS
FT02.[A50].Resize(Ld, CFin).Value = TSdr
FT02.[A70].Resize(Lo, CFin).Value = TSop
Application.EnableEvents = True

Selon le besoin je dois charger dans la feuille FT02 1 ou 2 ou l'ensemble de ces tableaux et dans un ordre selon la demande. Pour éviter de créer 3 macros, 1 macro par tableau,
1/ Est-il possible de créer une autre macro paramétrée basée sur la macro T_ParOP_DR_SITE_vT012 pour le chargement de ces tableaux selon le besoin, en paramètre le nom des tableaux ? ou autre méthode ?
2/ le début de chaque tableau est figé, ligne 4, ou 50 ou 70, est-il possible de les charger l'un après l'autre avec un décalage de 5 lignes car les données évoluent et les lignes ne sont pas figées?
Merci d'avance pour votre aide
KIM
 

Pièces jointes

  • KIM_GiGg_20170508.xlsm
    369.8 KB · Affichages: 36

Dranreb

XLDnaute Barbatruc
Bonjour.
Si tu ne veux pas tout sommer tu ne peut pas utiliser la méthode Somme de l'objet SsGr. Il faut cumuler toi même ceux qu'il faut retenir :
VB:
               For Each Détail In STATUT.Co
                  If Détail(32) <> "Oui" Then TS(L, C) = TS(L, C) + Détail(25): TS(L, 10) = TS(L, 10) + Détail(25)
                  Next Détail
 

KIM

XLDnaute Accro
Re,
Actuellement j'analyse les usages des locaux. Le bât se retrouve dupliquer avec sa surface autant de fois que d'usages de ces locaux.
Avec TS(L, 11) = TS(L, 11) + SIT.Somme(12) j'ai la somme totale de tous les bât avec les surfaces des bât dupliqués.
Y-a-t-il une astuce d'avoir la somme des surfaces de chaque bât pris en compte une seule fois sans les doublons ?

Merci
KIM
 

Dranreb

XLDnaute Barbatruc
Je n'ai plus le fichier sous les yeux et je n'ai pas envie de le réouvrir.
Mais je suppose qu'il y a une erreur de SsGr dont il faut prendre la Somme. Ou alors il faut simplement faire TS(L, 11) = SIT.Somme(12) juste avant le Next SIT. Enfin du moins si c'est une ligne par SIT.
 

KIM

XLDnaute Accro
Bonsoir Dranreb,
J'ai réduit au minimum le code pour aller l'essentiel. Les SsGr sont déclarés sans l'ordre : OP/DR/SITE/BAT/STATUT
Jusqu'à maintenant j"avais dans mes données une ligne par BAT. Maintenant j'ai plusieurs lignes par BAT. Les doublons concernent le code du BAT et les 2 surfaces du BAT SUB et SUN.
Tous les calculs sont bons sauf pour les 2 col 10 et 11. La surface SUB et SUN par site cumule les doublons. J'ai testé plusieurs codes mais je n'ai pas réussi à calculer la bonne surface sans les doublons.
J'ai besoin de ton aide et t'en remercie par avance.
KIM

Sub T_ParOP_DR_SITE_vU001()
Dim PlgDon As Range, TS(), L&, C&, DR As SsGr, OP As SsGr, SIT As SsGr, BAT As SsGr, STATUT As SsGr, Détail
Dim TotOP() As Double, TotDR() As Double
Dim CFin As Long, LFin As Long

Dim DCols As Dictionary, ColTitre As Long, ColDép As Long
ColTitre = 27
ColDép = 13

Set PlgDon = ColUti(FBase4.[A10:AI10])
Set DCols = DicInvent(PlgDon, ColTitre, ColDép): CFin = ColDép + DCols.Count
LFin = PlgDon.Rows.Count
ReDim TS(1 To LFin, 1 To CFin), TotOP(4 To CFin), TotDR(4 To CFin)
'
For C = 1 To ColDép - 1: TS(1, C) = Array("OP", "DP", "SITE", "Nb BAT", "Nb BatP", "Nb lignes", "Nb sites", "Nb DR", "", "SUB", "SUN", "Surf Locaux")(C - 1): Next C
C = C - 1: For Each Détail In DCols.Keys: C = C + 1: TS(1, C) = Détail: Next Détail
C = C + 1: TS(1, C) = "Surface Totale"
'
FU01.[A4].Resize(1, CFin).Value = TS

L = 1
For Each OP In Gigogne(PlgDon, 10, 1, 2, 8, ColTitre) 'OP/DR/SITE/BAT/STATUT
For C = 4 To CFin: TotOP(C) = 0: Next C

For Each DR In OP.Co
For C = 4 To CFin: TotDR(C) = 0: Next C
For Each SIT In DR.Co
L = L + 1
TS(L, 1) = OP.Id
TS(L, 2) = DR.Id
TS(L, 3) = SIT.Id
TS(L, 4) = SIT.Count 'Nb BAT

For Each BAT In SIT.Co
If Right$(BAT.Id, 1) = "0" Then TS(L, 5) = TS(L, 5) + 1
For Each STATUT In BAT.Co
C = DCols(STATUT.Id)
For Each Détail In STATUT.Co
If Détail(32) <> "Oui" Then TS(L, C) = TS(L, C) + Détail(25): TS(L, 12) = TS(L, 12) + Détail(25)
Next Détail
Next STATUT
TS(L, 6) = TS(L, 6) + BAT.Count: Next BAT 'Nb lignes
TS(L, 8) = Empty: TS(L, 9) = Empty

TS(L, 10) = SIT.Somme(15)
TS(L, 11) = SIT.Somme(16)
For C = ColDép To ColDép + DCols.Count - 1: TS(L, ColDép + DCols.Count) = TS(L, ColDép + DCols.Count) + TS(L, C): Next C
For C = 4 To CFin: TotDR(C) = TotDR(C) + TS(L, C): Next C, SIT

L = L + 1
TS(L, 1) = "Total " & OP.Id & " de la ": TS(L, 2) = DR.Id: TotDR(7) = DR.Count 'Nb sites
For C = 4 To CFin: TS(L, C) = TotDR(C): TotOP(C) = TotOP(C) + TotDR(C): Next C
TS(L, 8) = Empty: TS(L, 9) = Empty
L = L + 1: Next DR

L = L + 1: TS(L, 1) = "Total pour " & OP.Id: TotOP(8) = OP.Count 'Nb OP
For C = 4 To CFin: TS(L, C) = TotOP(C): Next C
L = L + 1: Next OP

Application.EnableEvents = False
FU01.[A4].Resize(1000000, CFin).ClearContents
FU01.[A4].Resize(L, CFin).Value = TS
Application.EnableEvents = True
End Sub
 

Pièces jointes

  • KIM_20170530.xlsm
    430.6 KB · Affichages: 33

Dranreb

XLDnaute Barbatruc
Il devrait être possible de faire Détail = BAT.Co(1).Co(1)
juste derrière For Each BAT In SIT.Co pour récupérer la 1ère ligne Détail attachée au premier STATUT
Mais il faut faire toi même le cumul une seule fois des colonnes 15 et 16 qui s'y trouvent.
 
Dernière édition:

KIM

XLDnaute Accro
Merci Dranreb,
Je ne connaissais pas cette syntaxe.
Peux-tu stp m'expliquer pourquoi on écrit 2 fois Co(1) ?
Le "1" pour récupérer la 1è ligne. Si on met "2" cela veut-dire récupérer la 2è ligne ou les 2 premières lignes ?

Je retrouve ainsi mes surfaces sans les doublons comme suggéré :
For Each BAT In SIT.Co
Détail = BAT.Co(1).Co(1)
TS(L, 10) = TS(L, 10) + Détail(11)

Je récupère le nombre de bâtiment par STATUT.count.
Avec Détail, peut-on faire Détail.count ?
Merci encore et Bonne journée
KIM
 

Dranreb

XLDnaute Barbatruc
Bonjour.
C'est en somme une contraction de Set STATUT = BAT.Co(1) suivi de Détail = STATUT.Co(1)
Oui le 1 c'est pour récupérer le 1er membre de la propriété Co, laquelle est une Collection. 2 récupèrerait le 2ième et SIT.Co(SIT.Count) le dernier.
Mais au bout du compte ce n'est plus un SsGr mais une table de Variant qui est renvoyée, et elle n'a ni propriété ni méthode puisque ce n'est pas un objet.
 

KIM

XLDnaute Accro
Bonjour Dranreb,
1/ Pour une hiérarchie OP/DR/SITE/BAT et avec 1 BAT par ligne dans le fichier source je retrouve le bon nombre de BAT par OP, DR et SITE :
For Each OP In Gigogne(PlgDon, 10, 1, 2, 8, ColTitre) 'OP/DR/SITE/BAT/
For Each DR In OP.Co
For Each SIT In DR.Co
L = L + 1
TS(L, 1) = OP.Id
TS(L, 2) = DR.Id
TS(L, 3) = SIT.Id
TS(L, 4) = SIT.Count 'Nb BAT
For Each BAT In SIT.Co
Je retrouve dans TS(L,4) le bon nombre de BAT.

2/ Pour la même hiérarchie OP/DR/SITE/BAT et avec plusieurs même BAT par ligne dans le fichier source j'ai utilisé ta méthode préconisée en rajoutant :
.......
For Each BAT In SIT.Co
Détail = BAT.Co(1).Co(1)
TS(L, 10) = TS(L, 10) + Détail(11)
For Each Statut In BAT.Co
C = DCols(Statut.Id)
For Each Détail In Statut.Co
...
et là je ne retrouve plus le même nombre de BAT avec TS(L, 4) = SIT.Count 'Nb BAT

Me suis-je trompé quelque part ?
Merci de ton aide

KIM
 

Dranreb

XLDnaute Barbatruc
Bonsoir.
Non je ne vois pas ce qui cloche dans ce code sortit de son contexte.
SIT.Count devrait toujours donner le nombre de SsGr que contient SIT.Co, donc le nombre de BAT, chacun pouvant avoir plusieurs Statut, lesquels peuvent contenir plusieurs lignes.
Tu sais que dans le TIdxFusion.xlsm que tu m'avait un jour demandé, il y a une Sub AuditCollectionGigogne qui permet d'analyser une collection rendue par la fonction Gigogne ?
Elle y est utilisée dans le module de Worksheet FTestGig représentant une feuille nommée "Test fonction Gigogne"
 
Dernière édition:

KIM

XLDnaute Accro
Bonjour Dranreb et le fil,
Pb résolu, le problème vient des données dans la base elle même. Mes tableaux de bord pour des données arborescentes OP/DP/SIT/BAT tourne bien.
Je reviens vers toi pour une question de simplification du tableau résultat.
For Each OP In Gigogne(PlgDon, 10, 1, 2, 8, ColTitre)
je retrouve dans le fichier TS le récap pour chaque OP.
Pour éviter de ne pas créer une autre macro, comment je peux filtrer la sortie dans TS pour une valeur donnée de OP sans modifier la structure de la macro ?
J'ai placé : IF OP = "NSR" then après For each OP in Gigogne
et avant Next OP, end if.

Cela n'a pas fonctionné.
Comment faire, Merci d'avance.
KIM
 

Dranreb

XLDnaute Barbatruc
Bonjour.
If OP.Id = "NSR"
Un objet SsGr n'a pas de propriété par défaut, il faut préciser celle qu'on veut.
Ce n'est pas complètement impossible d'en définir une, mais ça ne peut pas se faire par les moyens de VBE, et ça fait un peu bricolage…
D'ailleurs si c'était plus facile, je préfèrerait définir comme telle la propriété Co.
 

KIM

XLDnaute Accro
Bonjour Dranreb,
Ouf, un oubli de ma part. en effet cela fonctionne avec If OP.Id = "NSR". D'ailleurs tu as raison, si je dois traiter seulement le cas "NSR", il faut repenser la macro. Pour le moment la demande est occasionnelle.

Une question concernant la fonction VerserTitres :Comment faire pour dupliquer 2 fois les titres de DCols avec VerserTitres ?

Actuellement, pour dupliquer 2 fois les titres des colonnes de DCols, une fois pour la somme et l'autre pour le nombre j'utilise l'ancienne méthode :
C = C - 1: For Each Détail In DCols.Keys: C = C + 1: TS(1, C) = Détail: Next Détail
C = C + 1: TS(1, C) = "Somme Totale"
For Each Détail In DCols.Keys: C = C + 1: TS(1, C) = Détail: Next Détail
C = C + 1: TS(1, C) = "Nb Total DP": C = C + 1: TS(1, CFin) = "Nb Total SIT"
TS17b.[A4].Resize(1, CFin).Value = TS 'Copie des titres à partir de A4

Le but est de réduire le code.
Merci encore
KIM
 

Discussions similaires

Statistiques des forums

Discussions
312 187
Messages
2 086 024
Membres
103 097
dernier inscrit
Benduch