Somme TextBox via ListBox

Bonjour le Forum,

J'aurais besoin d'aide concernant l'affichage de la somme de ma 5e colonne de ma listBox dans un TextBox afin de rendre l'opération plus lisible et directement visualiser l'information. Pour faire simple, j'utilise un classeur qui récapitule les informations d'un autre classeur (il récapitule en allant piocher dedans). Le fichier où je vais piocher fais 800 lignes pour 19/20 colonnes. Dans ma listBox j'affiche uniquement 5 colonnes qui m'interesse et je fais le tri via une barre de recherche. Ce que j'aimerai faire, et qui ne marche pas, serait de faire la somme de ma 5e colonne de ma listBox (19e colonne de mon fichier de base) afin de l'afficher via une textbox. Malheureusement je n'arrive pas à faire cette opération. Serait il possible de m'aider dans ma quête de solution? Je ne suis pas très bon en VBA et le code à été fait suivant ce que j'ai pu voir dans les forum et marche bien mise à part la somme de la colonne.

Voici le code :

Dim f, choix(), Rng, xxxxx(), Ncol, ColVisu()

Private Sub Label1_Click()

End Sub

Private Sub Label2_Click()

End Sub

Private Sub Label3_Click()

End Sub

Private Sub ListBox2_Click()

End Sub

Private Sub UserForm_Initialize()
    Set wk_actual_hours = Application.Workbooks.Open("xxx")
    Set f = wk_actual_hours.Worksheets("xxxx")
   ColVisu = Array(7, 11, 13, 15, 19) ' colonnes à visualiser
   Set Rng = f.Range("A2:Z" & f.[o65000].End(xlUp).Row)
   xxxx = Rng.Value
   Ncol = UBound(ColVisu) + 1
   '-- en têtes de colonne ListBox
   X = 22
   Y = Me.ListBox1.Top - 12
   For Each K In ColVisu
     Set Lab = Me.Controls.Add("Forms.Label.1")
     Lab.Caption = f.Cells(1, K)
     Lab.Top = Y
     Lab.Left = X
     X = X + f.Columns(K).Width * 0.9
     temp = temp & f.Columns(K).Width * 0.9 & ";"
   Next
   temp = Left(temp, Len(temp) - 1)
   Me.ListBox1.ColumnCount = UBound(ColVisu) + 1
   Me.ListBox1.ColumnWidths = temp
   '--
   TblTmp = Rng.Value
   For i = LBound(xxxxx) To UBound(xxxx)
     ReDim Preserve choix(1 To i)
     For Each K In ColVisu
       choix(i) = choix(i) & xxxx(i, K) & " * "
     Next K
   Next i
   '--- valeurs initiales dans ListBox
   Dim Tbl(): ReDim Tbl(1 To UBound(xxxx), 1 To Ncol)
   For i = 1 To UBound(xxxx)
      c = 0
      For Each K In ColVisu
        c = c + 1: Tbl(i, c) = xxxxx(i, K)
      Next K
   Next i
   'TriMultiCol Tbl, LBound(Tbl), UBound(Tbl), 1
   Me.ListBox1.List = Tbl
   Me.Label1.Caption = Me.ListBox1.ListCount & " Ligne(s)"
   ListBox1.MultiSelect = Val_Somme

End Sub
Private Sub TextBox1_Change()
  If Me.TextBox1 <> "" Then
     mots = Split(Trim(Me.TextBox1), " ")
     Tbl = choix
     For i = LBound(mots) To UBound(mots)
        Tbl = Filter(Tbl, mots(i), True, vbTextCompare)
     Next i
     If UBound(Tbl) > -1 Then
        Dim b(): ReDim b(1 To UBound(Tbl) + 1, 1 To Ncol)
        For i = LBound(Tbl) To UBound(Tbl)
          a = Split(Tbl(i), "*")
          For K = 1 To Ncol: b(i + 1, K) = a(K - 1): Next K
        Next i
        Me.ListBox1.List = b
        Me.Label1.Caption = UBound(Tbl) + 1 & " Ligne(s)"

     End If
  Else
     UserForm_Initialize
  End If
End Sub

Private Sub BtnTotal_Click()
Dim X As Double 'Double si tu as des décimales
With Me.ListBox1
    For i = 0 To .ListCount - 1
        If .Selected(i) Then
            X = X + .List(i, 4)
        End If
    Next i
End With
Me.TextBox2 = X
End Sub

Les xxx sont mis pour le ne pas montrer le nom des fichiers, je ne pense pas que le pb viennent de la. Merci d'avance pour votre aide !

Bonjour,

Apparemment, vous avez déjà une macro qui s'en charge :

Private Sub BtnTotal_Click()
Dim X As Double 'Double si tu as des décimales
With Me.ListBox1
    For i = 0 To .ListCount - 1
        If .Selected(i) Then
            X = X + .List(i, 4)
        End If
    Next i
End With
Me.TextBox2 = X
End Sub

Elle fait la somme (pour les lignes sélectionnées) dans la dernière colonne de la listbox. Elle s'exécute au clic sur le bouton BtnTotal.

Pourquoi ne pas demander à la personne qui a fait ce code ?

Cdlt,

Bonjour,

Oui justement normalement cette fonction s'occupe du calcul, je l'ai ajusté pour mon code mais la valeur retourné dans ma listbox est toujours de 0, ce que je ne comprends pas.

Pour demander à la personne qui était à l'origine du code, le post date de 2013 donc pas certain d'avoir une réponse

Et en colonne 19 de votre base, comme en colonne 5 de votre ListBox, vous avez bien des nombres différents de 0 ?

Oui les nombres sont différents de 0. Il s'agit d'heures exactement (enfin elles sont au format chiffre type 2 et pas 2:00 pour simplifier)

Est-il de faire un essai :

Private Sub BtnTotal_Click()
dim test
test = Sommeselect(Me.ListBox1, 5)
msgbox test
msgbox me.ListBox1.ListCount
'Me.TextBox2 = X
end sub

function SommeSelect(LB as ListBox, Colonne as long) as double
With LB
    For i = 0 To .ListCount - 1
        If .Selected(i) Then SommeSelect = SommeSelect + .List(i, Colonne - 1)
    Next i
End With
End Sub

J'ai mis le code sous forme de fonction. Le résultat est renvoyé dans une variable puis affiché par une msgbox. Avec un fichier, ce serait mieux peut-être...

J'ai essayé de tester le code mais la ligne ci dessous présente une incompatibilité de type. Je ne comprends pas pourquoi ça marche sur les codes des autres et le miens retourne 0 uniquement. J'ai essayé d' appeler la fonction dans le initialize mais pareil aucun changement

test = SommeSelect(Me.ListBox1, 5)

Il faut le fichier sinon, je ne pourrais pas faire plus...

Il y a des variables cryptées xxxx, d'autres inutilisées Tbltmp, d'autres non déclarées et jamais initialisées Val_Somme (est-ce une fonction ?), donc je ne sais même pas si la multi-sélection est possible...

Vous avez compris ? Il faut sélectionner les lignes pour renvoyer une somme ! La fonction compte les lignes sélectionnées (en bleu) et pas juste les lignes filtrées. Pour les lignes filtrées :

function SommeFiltre(Colonne as long) as double
With Me.ListBox1
    For i = 0 To .ListCount - 1
        SommeFiltre = SommeFiltre + cdbl(.List(i, Colonne - 1))
    Next i
End With
End Sub

Pour l'incompatibilité de type, essayez :

Private Sub BtnTotal_Click()
Me.TextBox2 = Sommefiltre(5)
end sub

J'ai enlevé le paramètre ListBox pour le placer en dur dans la fonction, après essai infructueux. Il faudra modifier la fonction sommeselect de la même manière.

De mon côté, ça marche !

Cdlt,

Oui je comprends mieux, je ne pensais pas qu"il fallait passer par une sélection des lignes pour l'appliquer.

Je vais devoir remplacer les valeurs différents fichiers dû à la confidentialité à laquelle je suis contrains. J'essaie de faire le tri et je reviens vers vous ce soir. Sera t-il possible de passer par les messages privées ou vous préférez que le fichier soit partagés ici?

Je pense pas que ce soit la peine finalement. Comme je vous ai dit, je viens d'essayer et ça marche. Il faut utiliser les derniers codes que j'ai postés (en mettant la fonction dans un module normal). La fonction SommeFiltre permet de faire la somme des lignes obtenues après filtre, contrairement à celle que vous aviez au départ.

Essayez-là.

Et d'ailleurs, il n'est même pas nécessaire d'utiliser le bouton. Vous pouvez avoir la somme automatiquement en ajoutant une ligne dans cette macro :

Private Sub TextBox1_Change()
  If Me.TextBox1 <> "" Then
     mots = Split(Trim(Me.TextBox1), " ")
     Tbl = choix
     For i = LBound(mots) To UBound(mots)
        Tbl = Filter(Tbl, mots(i), True, vbTextCompare)
     Next i
     If UBound(Tbl) > -1 Then
        Dim b(): ReDim b(1 To UBound(Tbl) + 1, 1 To Ncol)
        For i = LBound(Tbl) To UBound(Tbl)
          a = Split(Tbl(i), "*")
          For K = 1 To Ncol: b(i + 1, K) = a(K - 1): Next K
        Next i
        Me.ListBox1.List = b
        Me.Label1.Caption = UBound(Tbl) + 1 & " Ligne(s)"
        Me.textbox2.value = sommefiltre(5) '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     End If
  Else
     UserForm_Initialize
  End If
End Sub

Cdlt,

La fonction avec le bouton marche mais lorsque j'enlève cette focntion pour rajouter la ligne dont vous parlez j'ai une erreur qui apparait dans la fonction SommeFiltre

Super !

Oui, vous pouvez déjà enlever la fonction sommeselect et la macro btnTotal si vous retenez mon dernier code.

Merci, bonne fin de journée à vous aussi !

Cette erreur survient quand vous n'avez qu'une seule ligne ou même avec plusieurs ?

Si elle n'a lieu qu'avec une seule ligne, essayez ça :

Private Sub TextBox1_Change()
  If Me.TextBox1 <> "" Then
     mots = Split(Trim(Me.TextBox1), " ")
     Tbl = choix
     For i = LBound(mots) To UBound(mots)
        Tbl = Filter(Tbl, mots(i), True, vbTextCompare)
     Next i
     If UBound(Tbl) > -1 Then
        Dim b(): ReDim b(1 To UBound(Tbl) + 1, 1 To Ncol)
        For i = LBound(Tbl) To UBound(Tbl)
          a = Split(Tbl(i), "*")
          For K = 1 To Ncol: b(i + 1, K) = a(K - 1): Next K
        Next i
        with Me.ListBox1
            if ubound(b) > 1 then .List = b else .column = application.transpose(b)
        end with
        Me.Label1.Caption = UBound(Tbl) + 1 & " Ligne(s)"
        Me.textbox2.value = sommefiltre(5)
     End If
  Else
     UserForm_Initialize
  End If
End Sub

Là, il faudrait que je voie le fichier par contre...

L'erreur subvient lorsqu'il y a plusieurs lignes. Ce que je ne comprends pas d'ailleurs. Je ne suis peut etre pas très fort en VBA mais ce que vous avez écrit me semble logique. Voici à quoi ressemble le code :

Private Sub TextBox1_Change()
  If Me.TextBox1 <> "" Then
     mots = Split(Trim(Me.TextBox1), " ")
     Tbl = choix
     For i = LBound(mots) To UBound(mots)
        Tbl = Filter(Tbl, mots(i), True, vbTextCompare)
     Next i
     If UBound(Tbl) > -1 Then
        Dim b(): ReDim b(1 To UBound(Tbl) + 1, 1 To Ncol)
        For i = LBound(Tbl) To UBound(Tbl)
          a = Split(Tbl(i), "*")
          For K = 1 To Ncol: b(i + 1, K) = a(K - 1): Next K
        Next i
        Me.ListBox1.List = b
        Me.Label1.Caption = UBound(Tbl) + 1 & " Ligne(s)"
        Me.TextBox2.Value = SommeFiltre(5) '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     End If
  Else
     UserForm_Initialize
  End If
End Sub
Function SommeFiltre(Colonne As Long) As Double
With Me.ListBox1
    For i = 0 To .ListCount - 1
        SommeFiltre = SommeFiltre + CDbl(.List(i, Colonne - 1))
    Next i
End With
End Function
'Private Sub BtnTotal_Click()
'Me.TextBox2 = SommeFiltre(5)
'End Sub

L'erreur (incompatibilité de type) intervient lors de la ligne ci dessous lorsque je commence à taper du texte dans la listbox1.

SommeFiltre = SommeFiltre + CDbl(.List(i, Colonne - 1))

Et vous n'avez que des nombres c'est ça ?

Essayez en changeant la fonction :

Function SommeFiltre(Colonne As Long) As Double
With Me.ListBox1
    For i = 0 To .ListCount - 1
        if .List(i, Colonne - 1) like "[0-9[-]*" then SommeFiltre = SommeFiltre + CDbl(.List(i, Colonne - 1))
    Next i
End With
End Function

A part des valeurs vides, je ne vois pas pour l'instant. Le code textbox1_change me semble bien...

Edit : j'ai laissé trainé un point malencontreusement. Je trouve ça étrange moi aussi. Sans fichier, je ne saurais pas répondre.

Oui je n'ai que des nombres décimaux.

Alors cette fois ci l'erreur est "Membre de méthode ou de données introuvable".

image

Voici le type de données extraite dans le TextBox

Si cela ne marche pas, le bouton marche, je resterai la dessus meme si la contrainte du clique est la, elle reste minime. Mais je ne comprends pas en effet pourquoi le pb est si important .

Bonjour, je n'avais pas vu votre edit. Alors il n'y a plus d'erreurs mais la textbox2 ne renvoie plus de somme mais toujours 0. Merci pour votre aide dans tous les cas.

Bonjour,

Ca veut dire qu'elle ne rencontre pas de caractère numérique ou de "-" en premier caractère sur la colonne 5 de la listbox. Comme j'ai dit, sans fichier, c'est compliqué.

Tout ce que je peux dire, c'est qu'une ligne me chiffonne dans l'initialisation de l'userform. Il y a concaténation avec " * ". Or, dans la macro textbox1_change, il y a séparation avec "*".

Voici un nouvel essai :

Function SommeFiltre(Colonne As Long) As Double
With Me.ListBox1
    For i = 0 To .ListCount - 1
        if trim(.List(i, Colonne - 1)) like "[0-9[-]*" then SommeFiltre = SommeFiltre + CDbl(trim(.List(i, Colonne - 1)))
    Next i
End With
End Function

ou alors, modifiez cette ligne dans la macro textbox1_change :

For K = 1 To Ncol: b(i + 1, K) = trim(a(K - 1)): Next K

Mais, comme vous avez dit hier, je ne vois pas pourquoi ça marcherait au clic et pas dans cette macro...

La fonction somme marche, incroyable merci beaucoup!!

Je dois avouer que je vais devoir me pencher sur la compréhension du programme parce que je ne comprends pas tout...

Merci encore pour votre aide très précieuse!!

Nickel ! Sans le fichier finalement ...

Oui, vous feriez bien car c'est pas un code évident du tout !

Le principe, c'est qu'on stocke dans un variable publique (choix) la concaténation des champs de la listbox, en les séparant d'une étoile * (au cours de l'initialisation)

Ensuite, en cas de changement sur la textbox1, on stocke tous les mots saisis et on les compare avec ce tableau (Tbl = choix) qui contient donc toutes les lignes de la listbox initiale mais sans colonne (car les colonnes ont été concaténées).

On applique un filtre (sur tbl) pour chaque mot. Ca permet d'affiner le tableau Tbl qui ne comporte alors que les lignes contenant les mots saisis.

Ensuite, on redivise chaque ligne du tableau tbl (split(tbl, "*")) dans un tableau a, dont les valeurs sont insérées dans le tableau b, de manière à restituer les valeurs issues du filtre dans la listbox en 2 dimensions.

Si vous avez des questions, n'hésitez pas, j'imagine que ce n'est toujours pas limpide...

Bonne continuation,

Cdlt,

Rechercher des sujets similaires à "somme textbox via listbox"