tableau de bord

cathodique

XLDnaute Barbatruc
Bonsoir, http://cjoint.com/?0CrthDt22KS

Avant d'exposer mon problème, je dois vous dire que j'ai posté cette discussion sur un autre Forum. Par rapport à l'avancement, je donnerai à l'un et à l'autre de toutes réponses pour le partage.

Ma première approche a été les auto-filtres, j'utilise un userform pour effectue la sélection d'un type et d'une date, toute la suite sera traitée par rapport à ces 2 critères qui sont transférés sur la feuille TxBord.

Voilà, afin de faire une espèce de tableau de bord, je dois extraire des données d'une BD et transférer celles-ci sur la feuille "TxBord", en effectuant un premier filtre dont les critères sont les valeurs VAL18=Sheets("TxBord").Range("H4") et VAL3=Sheets("TxBord").Range("D4")

J'ai fait une partie du code en utilisant des dictionnaires (que je ne maitrise pas très bien), je suis parvenu à extraire les valeurs de 3 colonnes VAL4, VAL5 et VAL6.

Pour les autres colonnes, il y a quelques calculs à faire, je commence par les plus simples:
1 - Pour VAL9 et VAL10 c'est la moyenne des colonnes correspondantes filtrées
2 - Pour VAL7, c'est la différence entre la plus valeur et la plus petite des lignes visibles (à partir 2ème ligne visible)
3- Pour %VAL, c'est le ration entre le nombre de cellules (VAL10) dont la valeur est <=-600 et le nombre de cellules non vides de la même colonne (VAL10)
4 - Pour VAL15, ça se complique un peu, sommer les valeurs (val15) pour lesquelles VAL8= "S" ou "PS ou "CPS" à laquelle il faudra soustraire la somme des cellules dont en colonne VAL8, il y aura "I" ou "ADF" ET dont la cellule correspondante en VAL11 est vide
5 - Pour densité, elle se calcule ainsi: Résultat pour VAL19/(Pi*(Convert(VAL6,"in","m"))*VAL7)

En vous remerciant, j'ai commencé avec les dictionnaires mais toutes autres approches sera la bienvenue.

Je vous avoue que je suis un peu septique que mon code aboutisse tel que je l'ai commencé. Et ce, par rapport à toutes les recherches que j'ai effectué et les différentes discussions que j'ai consulté.

Cordialement,
Code:
Option Explicit

Sub Tx_Bord()
Dim i As Long, J As Long, k As Long, NBd As Long, NCr As Long, DL As Long, LaDate As Long, x As Long, y As Long
Dim TypeCamp As String
Dim ShBd As Worksheet, ShTxB As Worksheet
Dim Plage As Range, C As Range, v As Range
Dim Prise(), Ouvrage(), Tronçon()
Dim tOuv As Object, tTrc As Object
Dim temp As Variant, temp1 As Variant, temp2 As Variant
Dim Ligne
 
Application.ScreenUpdating = False
 
Set ShBd = Worksheets("BD")
ShBd.AutoFilterMode = False
NBd = ShBd.Cells(ShBd.Rows.Count, 1).End(xlUp).Row
  
Set ShTxB = Worksheets("TxBord")
With ShTxB
    DL = .Cells(.Rows.Count, 2).End(xlUp).Row
    If DL > 7 Then .Range("A8:K" & DL).Clear
    
    LaDate = .Range("C4")                    'DATE
    TypeCamp = .Range("H4")                   'REFERENCE
    
    With ShBd
            '.AutoFilterMode = False
            .Range("A1:AA" & NBd).AutoFilter Field:=18, Criteria1:=TypeCamp
            .Range("A1:AA" & NBd).AutoFilter Field:=3, Criteria1:=CDate(LaDate)
             
            Set tOuv = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
            For Each C In .Range("D2:D" & NBd).SpecialCells(xlCellTypeVisible)
            tOuv(C.Value) = ""
            Next C 'prochaine cellule de la boucle
            temp = tOuv.Keys 'récupère le dictionnaire sans doublon dans le tableau temp
            For i = 0 To UBound(temp) 'boucle 1 : sur toutes les valeurs uniques du tableau temp
'Stop
               .Range("A1:AA" & NBd).AutoFilter Field:=4, Criteria1:=temp(i)
              
                Set tTrc = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
                Set Plage = .Range("E2:E" & NBd).SpecialCells(xlCellTypeVisible)
                For Each C In Plage 'c In .Range("E2:E" & NBd).SpecialCells(xlCellTypeVisible)
                If Not tTrc.Exists(C.Value) Then tTrc.Add C.Value, C.Offset(0, 1).Value
                Next C 'prochaine cellule de la boucle
                temp1 = tTrc.Keys 'récupère le dictionnaire sans doublon dans le tableau temp
                temp2 = tTrc.items
                For J = 0 To UBound(temp1) 'boucle 1 : sur toutes les valeurs uniques du tableau temp
                    .Range("A1:AA" & NBd).AutoFilter Field:=5, Criteria1:=temp1(J)
' Stop
                     
                          ShTxB.Cells(J + 8, 2) = temp(i)    'solution trouvée
                          ShTxB.Cells(J + 8, 3) = temp1(J)   'solution trouvée
                          ShTxB.Cells(J + 8, 4) = temp2(J)   'solution trouvée
                          ShTxB.Cells(J + 8, 5) = ""         'solution non trouvée, moyenne cellules visibles col9
                          ShTxB.Cells(J + 8, 6) = ""         'solution non trouvée, moyenne cellules visibles col10
                          ShTxB.Cells(J + 8, 6) = ""         'solution non trouvée
                          ShTxB.Cells(J + 8, 7) = ""         'solution non trouvée
                          ShTxB.Cells(J + 8, 8) = ""         'solution non trouvée
                          ShTxB.Cells(J + 8, 9) = ""         'solution non trouvée
                          ShTxB.Cells(J + 8, 10) = ""        'solution non trouvée
                
                Next J
            Next i
                      
            .AutoFilterMode = False
        End With
 End With
Set ShBd = Nothing
Set ShTxB = Nothing
End Sub
 
Dernière édition:

cathodique

XLDnaute Barbatruc
Re : tableau de bord

Bonjour,

88 visiteurs et aucunes réactions.

Conclusion, mon sujet n'est pas intéressant, soit il a trop de questions poser à la fois, soit trop compliqué ou bien très mal exposé. Ce fil fait suite à mon précédent où j'avais exposé le problème en partie.

Mais bon! Après une bonne nuit blanche, je suis parvenu tant bien que mal à terminer ce que j'avais commencé.

N'étant qu'un amateur du dimanche, je suis sûr que mon code n'est pas "orthodoxe", mais il fonctionne.

j'ai découvert la fonction "soustotal" qui m'a sorti d'affaire. J'avoue que je sous-estimais cette fonction,

je pensais qu'elle ne servait qu'à faire des sous-totaux sur une feuille contenant un groupe Plan.

J'ai abordé ce fichier avec mes maigres connaissances du VBA. J'attends vos remarques et critiques pour améliorer ce code.

Ce n'est sûrement pas la bonne approche, car je sais que ce problème aurait pu être résolu en utilisant les tableaux (Array).

Hélas! je ne les maitrise pas du tout. Bon, voilà pour le partage j'édite mon code.
Code:
 Option Explicit
 Dim a, b, d, e, f
Sub Tx_Bord()
Dim i As Long, J As Long, k As Long, NBd As Long, NCr As Long, DL As Long, LaDate As Long, x As Long, y As Long
Dim TypeCamp As String
Dim ShBd As Worksheet, ShTxB As Worksheet
Dim Plage As Range, C As Range, v As Range
Dim Prise(), Ouvrage(), Tronçon()
Dim tOuv As Object, tTrc As Object
Dim temp As Variant, temp1 As Variant, temp2 As Variant
Dim Ligne
 
Application.ScreenUpdating = False
 
Set ShBd = Worksheets("BD")
ShBd.AutoFilterMode = False
NBd = ShBd.Cells(ShBd.Rows.Count, 1).End(xlUp).Row
  
Set ShTxB = Worksheets("TxBord")
With ShTxB
    DL = .Cells(.Rows.Count, 2).End(xlUp).Row
    If DL > 7 Then .Range("A8:K" & DL).Clear
    
    LaDate = .Range("C4")                    'DATE
    TypeCamp = .Range("H4")                   'REFERENCE
    
    With ShBd
            '.AutoFilterMode = False
            .Range("A1:AA" & NBd).AutoFilter Field:=18, Criteria1:=TypeCamp
            .Range("A1:AA" & NBd).AutoFilter Field:=3, Criteria1:=CDate(LaDate)
             
            Set tOuv = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
            For Each C In .Range("D2:D" & NBd).SpecialCells(xlCellTypeVisible)
            tOuv(C.Value) = ""
            Next C 'prochaine cellule de la boucle
            temp = tOuv.keys 'récupère le dictionnaire sans doublon dans le tableau temp
            For i = 0 To UBound(temp) 'boucle 1 : sur toutes les valeurs uniques du tableau temp
'Stop
               .Range("A1:AA" & NBd).AutoFilter Field:=4, Criteria1:=temp(i)
              
                Set tTrc = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
                Set Plage = .Range("E2:E" & NBd).SpecialCells(xlCellTypeVisible)
                For Each C In Plage 'c In .Range("E2:E" & NBd).SpecialCells(xlCellTypeVisible)
                If Not tTrc.Exists(C.Value) Then tTrc.Add C.Value, C.Offset(0, 1).Value
                Next C 'prochaine cellule de la boucle
                temp1 = tTrc.keys 'récupère le dictionnaire sans doublon dans le tableau temp
                temp2 = tTrc.items
                For J = 0 To UBound(temp1) 'boucle 1 : sur toutes les valeurs uniques du tableau temp

                    .Range("A1:AA" & NBd).AutoFilter Field:=5, Criteria1:=temp1(J)
                    
  'Stop
                          ShTxB.Cells(J + 8, 2) = temp(i)    'VAL4
                          ShTxB.Cells(J + 8, 3) = temp1(J)   'VAL5
                          ShTxB.Cells(J + 8, 4) = temp2(J)   'VAL6
                                                    
                          ShTxB.Cells(J + 8, 5) = WorksheetFunction.Subtotal(101, ShBd.Range("I1:I" & NBd)) 'MOY VAL9
                          ShTxB.Cells(J + 8, 5).NumberFormat = "0"
                          
                          ShTxB.Cells(J + 8, 6) = WorksheetFunction.Subtotal(101, ShBd.Range("J1:J" & NBd))  'MOY VAL10
                          ShTxB.Cells(J + 8, 6).NumberFormat = "0"
                          
                            ' nouveau filtre pour somme1-somme2
                            .Range("A1:AA" & NBd).AutoFilter Field:=8, Criteria1:="=CPS", _
                          Operator:=xlOr, Criteria2:="=S"
                            a = WorksheetFunction.Subtotal(109, ShBd.Range("O1:O" & NBd))
        
                            .Range("A1:AA" & NBd).AutoFilter Field:=8, Criteria1:="=I", _
                            Operator:=xlOr, Criteria2:="=JI"
                            .Range("A1:AA" & NBd).AutoFilter Field:=11, Criteria1:="="
                                b = WorksheetFunction.Subtotal(109, ShBd.Range("O1:O" & NBd))
                                
                                ShTxB.Cells(J + 8, 7) = a - b
        
                                .Range("A1:AA" & NBd).AutoFilter Field:=11
                                .Range("A1:AA" & NBd).AutoFilter Field:=8
                            
                            ShTxB.Cells(J + 8, 9) = WorksheetFunction.Subtotal(104, ShBd.Range("G1:G" & NBd)) _
                          - WorksheetFunction.Subtotal(105, ShBd.Range("G1:G" & NBd)) 'max-min filtrer
                             d = ShTxB.Cells(J + 8, 9).Value
                                                        
                            ShTxB.Cells(J + 8, 8) = (a - b) / (WorksheetFunction.Pi() * _
                            (WorksheetFunction.Convert(temp2(J), "in", "m") * d)) 'densité
                            ShTxB.Cells(J + 8, 8).NumberFormat = "0.00"" µA/m²"""
    
                            e = WorksheetFunction.Subtotal(103, ShBd.Range("I1:I" & NBd)) 'nbval filter
                            
                            .Range("A1:AA" & NBd).AutoFilter Field:=9, Criteria1:="<=-600"
                            f = WorksheetFunction.Subtotal(103, ShBd.Range("I1:I" & NBd))
                            .Range("A1:AA" & NBd).AutoFilter Field:=9

                          ShTxB.Cells(J + 8, 10) = (f / e)
                          ShTxB.Cells(J + 8, 10).NumberFormat = "0%"
                          ShTxB.Cells(J + 8, 11) = "" '
                      
                 Next J
            Next i
                      
            .AutoFilterMode = False
        End With
 End With
Set ShBd = Nothing
Set ShTxB = Nothing
End Sub

Cordialement,
 

MJ13

XLDnaute Barbatruc
Re : tableau de bord

Bonjour Cathodique

Merci pour ta solution :).

Mais il faut te dire que plus le problème est complexe et moins tu auras de réponses, car cela demande un investissement en temps et en neurones.

La preuve, hier, tu as eu beaucoup de solutions car le problème était asssez simple à comprendre :eek:.
 

cathodique

XLDnaute Barbatruc
Re : tableau de bord

Bonjour Mj13,

Content de te revoir. Oui en effet, plus le problème est simple et plus il y a de la participation.

Je pense que tu seras d'accord avec moi, pour un novice tel que moi, il n'est pas simple de monter une macro fiable avec des bribes de code. Comme tu as pu le constater hier, j'ai eu de plusieurs solutions aussi différentes les unes que les autres.

Quoique mon code n'est pas parfait, des erreurs subsistent encore. Je viens de m'en rendre compte après avoir remis en fonction l'userform de sélection du type et de la date (sur la feuille txbord), il fallait enlever le filtre pour passer au "i" suivant
Code:
       Next J
.Range("A1:AA" & NBd).AutoFilter Field:=5
Next i
Mais en passant au "i" suivant (c'est la variable temp), j'ai remarqué que la ligne transférer sur la feuille "txbord" de la précédente boucle est écrasée par les données de la boucle suivante.

Il y a quelque chose qui ne va pas, car il faut que ça aille à la ligne suivante. Je cherche depuis un moment mais je n'ai pas encore trouvé, aurais-tu une idée?

Merci, je dois mettre un code qui tourne à 100% sinon ça ne va pas du tout.

Cordialement,
 

job75

XLDnaute Barbatruc
Re : tableau de bord

Bonjour cathodique, Michel,

car cela demande un investissement en temps et en neurones.

En effet donc juste un conseil.

Chaque fois qu'on se pose un problème ou qu'on crée une macro compliqués il faut se demander s'il n'y a pas plus simple.

En tout cas moi je fonctionne comme ça.

A+
 

cathodique

XLDnaute Barbatruc
[RESOLU] : tableau de bord

Bonjour Job75,

Je ne suis qu'un autodidacte amateur. j'ai donc travaillé avec peu de connaissances en VBA.
Je sais que ce problème aurait pu être résolu avec les tableaux que je ne maitrise pas du tout.
J'ai effectué beaucoup de recherches sur le net et énormément de tests, et ça ne tourne pas rond.
Donc une aide me sera d'une grande utilité.

Merci beaucoup.
NB: ajouter +i pour la prochaine boucle
Code:
ShTxB.Cells(J + 8 + i, 2)
Cordialement,
 
Dernière édition:

Discussions similaires

Réponses
2
Affichages
110

Statistiques des forums

Discussions
312 027
Messages
2 084 767
Membres
102 658
dernier inscrit
karima