Programmation de mon 1er USF / MULTIPLE FONCTIONS

Bonjour,

Après de multiples tentatives pour y arriver seule, je m'avoue vaincue et je lance un appel à l'aide pour tenter de finir mon userform.

Je travaille avec Excel 2003.

J'ai souhaiterai mettre au point ce fichier afin de m'aider dans mon travail quotidien de gestion budgétaire.
C'est ma première programmation pour un userform et je bloque sur pas mal de choses :

Mon souhait serait de regrouper dans le même formulaire les fonctions de saisie de nouvelles dépenses, de consultation de la base de données qui s'afficherait dans une listeview, de modification des données saisies.

J'aimerai que ma listeview affiche en permanence ma base de données.

J'ai tenté de programmer certaines cellules pour que les résultats s'affichent simultanément dans les combobox ou listbox, mais ça ne fonctionne pas toujours.

Les problèmes que je n'arrive pas à résoudre, malgré mes recherches journalières depuis plus d'un mois :

1) les dates ne s'affichent pas au format date dans les combobox et listbox. Je suis obligée de renseigner ces cases avec une liste car n'étant pas la seule à devoir travailler sur ce fichier, j'aimerai harmoniser les saisies;

2)les codes : référence 1 et 2 ne fonctionnent pas. Ils devraient permettre de rapatrier le numéro de tiers et un code de tri des enveloppes pour le futur TCD;

3) Je m'arrache les cheveux depuis 1 mois afin d'afficher ma base de données dans ma listeview, en vain.

J'ai téléchargé des tonnes de cours vba, mais rien n'y fait, je n'arrive pas à terminer ce travail, qui est loin d'être terminé, car ensuite je dois faire un TCD, triant les dépenses réelles et prévisionnelles, avec un affichage par enveloppe.

Je dois également générer des graphiques faisant apparaître l'évolution des dépenses par enveloppe ...
Donc je ne suis pas sortie de l'auberge comme on dit, c'est pourquoi j'apprécierai vraiment un petit coup de main pour avancer, car là je piétine depuis pas mal de temps;

Merci d'avance aux personnes qui prendront le temps de se pencher sur mon fichier.

https://www.sendbox.fr/share/?2426A0B49BFA

10 réponses

  1. Bonsoir,

    Tu as résolu ton problème ou as tu encore besoin d'aide.
    Impossible de récupérer ton fichier, ça fonctionne mieux par
    https://www.cjoint.com/
    1) Tu vas dans https://www.cjoint.com/
    2) Tu cliques sur [Parcourir] pour sélectionner ton fichier
    3) Tu descends en bas de la page pour cliquer sur [Créer le lien Cjoint]
    4) Au bout de quelques secondes la deuxième page s'affiche, avec le lien
    en bleu souligné ; tu le sélectionnes et tu fais "Copier"
    5) Tu reviens dans ta discussion sur CCM, et dans ton message de réponse
    tu fais "Coller"

    1. Bonjour passionofdream,
      J'avance doucement dans mon projet, ce n'est pas facile mais ça me passionne donc je m'accroche et quand je n'arrive pas d'une façon j'essaie de faire autrement, en même temps j'ai pas trop le choix ...
    2. Peux tu mettre ton fichier ici pour voir où tu en es et te donner un coup de main éventuel
  2. Bonjour,

    Dans les faits, travailler avec une structure revient à ceci :

    Trois éléments de travail :

    Un formulaire d'affichage (ou une feuille Excel servant d'affichage)
    Une structure d'éléments
    Une feuille de calcul

    1.) Les informations transit de la feuille de calcul à la structure et termine dans le formulaire.

    Lecture :
    Feuille Excel -> Traitement -> Formulaire
    Donnée de calcul -> Calcul et Conversion -> Données d'affichage

    2.) Les informations transit du formulaire à la structure et termine dans la feuille de calcul.

    Écriture :
    Formulaire -> Traitement -> Feuille Excel
    Donnée d'affichage -> Calcul et Conversion -> Données de calcul

    Référence : Structure de données 101 (Modélisation)

    K
    1. Bonsoir Kalissi,

      Je te remercie infiniment pour ton aide, malheureusement je me suis littéralement noyée dans tes dernières instructions , j'ai bossé tout le week end, en vain, je n'y suis pas arrivée.

      Etant pressée par ma hiérarchie, j'ai donc continué sur mon fichier test pour ne pas perdre de temps. J'avance petit à petit mais j'ai toujours du mal à comprendre la logique du développement VBA, je ne sais pas où placer les codes, quels termes employer, et pourtant j'ai imprimé des tonnes de cours trouvés sur le net ...

      Si tu es toujours d'accord pour m'aider, j'aimerai comprendre pourquoi certains de mes codes VBA ne fonctionnent pas, notamment pour l'affichage des cases : facture arrivée depuis (ListBox2), délai de traitement (ListBox3), code (TextBox1), N° dossier (TextBox2) et N° tiers (TextBox4). En parallèle, certaines de mes cellules de ma base de données ne sont pas renseignées par mon formulaire, malgré les codes insérés. J'aimerai pouvoir obtenir le même résultat que l'affichage de la case EURO de mon formulaire, qui se fait instantanément.

      J'aimerai pouvoir réussir à passer cette étape pour m'atteler aux boutons de commandes RECHERCHER et MODIFIER, sachant que je vais encore me griller quelques neurones à chercher des solutions, mes compétences en programmation VBA étant quasiment nulles.

      Je te remercie d'avance pour ton aide précieuse. Ci-joint mon fichier test

      https://www.sendbox.fr/index.php?/63605d496d10e95e/TABLEAU-GESTION-BUDGETAIRE-DERNIERTEST.xls
  3. voici ce que ça donne :

    1.) Travailler sans les structures :

    Private Sub Combobox10_Change()
        
        DATA.Range("e10").Value = Fonctions.DeterminerDateArriveeSansStructure(ComboBox10.Text)
        
        DATA.Range("e13").Value = ListBox2.Value      'transfert nombre de jours "arrivée" dans feuille DATA
        DATA.Range("f13").Value = ListBox3.Value      'transfert délai de traitement dans feuille DATA
    
    End Sub
    '
    


    Dans un module nommé Fonctions :

    Public Function DeterminerDateArriveeSansStructure(ByVal zDate As String) As Date
    
        Dim Valeur As String
        Dim DateReel As Date
        
        Valeur = zDate
        DateReel = CDate(Valeur)
        DeterminerDateArriveeSansStructure = DateReel
        
    End Function
    '
    


    2.) Travailler avec les structures

    Private Sub Combobox10_Change()
        
        Traitement.DtReception.AfficherDateReception = ComboBox10.Text
        Traitement = Fonctions.DeterminerDateArriveeAvecStructure(Traitement)
        DATA.Range("e10").Value = Traitement.DtReception.CalculDateReception
        
        DATA.Range("e13").Value = ListBox2.Value      'transfert nombre de jours "arrivée" dans feuille DATA
        DATA.Range("f13").Value = ListBox3.Value      'transfert délai de traitement dans feuille DATA
    
    End Sub
    '
    


    Dans un module nommé Fonctions :

    Public Function DeterminerDateArriveeAvecStructure(ByRef zStruc As StructureGlobal) As StructureGlobal
    
        Dim Valeur As String
        Dim DateReel As Date
        
        Valeur = zStruc.DtReception.AfficherDateReception
        DateReel = CDate(Valeur)
        zStruc.DtReception.CalculDateReception = DateReel
        DeterminerDateArriveeAvecStructure= zStruc
        
    End Function
    '
    


    K
    1. Bonjour,

      Je comprends bien la problématique.

      Des solutions il y en a ... au départ il aurait été souhaitable d'effectuer une encapsulation des données.
      Je veux dire de structurer les données et répliquer cette modélisation dans le code.

      Il est clair qu'on ne pense pas à tous cela du premier coup. Il y a plus de trente ans que je développe,
      et ce n'est pas venue tout seul.

      Donc, voici ma proposition, à toi de voir si celle ci te parait trop complexe.

      Sous VB.NET, je dérive les objets c'est plus simple, mais en VBA il te faudrait apprendre à
      travailler avec les modules de classe et ce serait probablement trop d'un seul coup.

      La solution alternative est de passer par les structures (i.e. les types).

      Tous les éléments de ton formulaire doivent demeurer des éléments d'affichage.

      1.) Première étape, structurer tes données, dans un module spécifique, créé les structures

      Exemple :
      Option Explicit
      
      '
      ' Décrlaration de type
      '
      
      Public Type StReception
                  AfficherDateReception As String
                  CalculDateReception As Date
      End Type
      
      Public Type StDevis
                  AfficherDateDevis As String
                  CalculDateDevis As Date
      End Type
      
      Public Type StFacture
                  AfficherDateFacture As String
                  CalculDateFacture As Date
                  Montant As Double
      End Type
      
      
      Public Type StructureGlobal
                  DtReception As StReception
                  DtDevis As StDevis
                  DtFacture As StFacture
      End Type
      '
      
      '
      ' Déclaration de variable globale
      '
      
      Public Traitement As StructureGlobal
      
      


      2.) Comprendre comment travaillé avec la(es) structure(s)

      Exemple :
      Public Function CalculMontant(ByRef zStruc As StructureGlobal) As StructureGlobal
      
          Dim NbrJours As Integer
          Dim DateDeb As Date
          Dim DateFin As Date
          
          DateDeb = zStruc.DtDevis.CalculDateDevis
          DateFin = zStruc.DtReception.CalculDateReception
          
          NbrJours = 0
          
          While DateDeb < DateFin
              NbrJours = (NbrJours + 1)
              DateDeb = DateAdd("d", 1, DateDeb)
          Wend
          
          zStruc.DtFacture.Montant = NbrJours * (Montant * 0.5)
      
          CalculMontant = zStruc
      
      End Function
      '
      


      3.) Créer des fonctions personnaliser qui traite l'information afficher dans les éléments
      du formulaire de façon a placer dans les cellules les valeurs adéquates.

      La cellule contient une valeur, cette valeur est déposé par programmation dans la structure
      dans la partie calcul (i.e. zStruc.DtDevis.CalculDateDevis), par programmation tu transforme
      cette valeur en chaine de caractères pour l'affichage (i.e. zStruc.DtDevis.AfficherDateDevis = CStr(zStruc.DtDevis.CalculDateDevis). Et ainsi dans le combobox on obtient combobox.additem(zStruc.DtDevis.AfficherDateDevis).

      C'est ce que l'on appelle l'encapsulation. Chaque élément n'est accédé que par une et une seule méthode.
      Un accès lecture et un accès écriture. Une fois la structure défini et les méthodes de lecture/écriture de la structure défini, ça devient un charme de travaillé avec le tout.

      Je vais te pondre une méthode qui renseigne une cellule à partir de la valeur d'un combobox, elle sera semblable à la fonction DateDuJour.

      K
      1. re:

        Dans l'immédiat, cette version-ci fonctionne :

        Option Explicit
        '
        
        Public Function DateDuJour() As String
        
            Dim DateJour As Date
            Dim ChaineDate As String
            Dim Mois As String
            Dim Jour As String
            
            Application.Volatile
            
            DateJour = Now
            
            Mois = CStr(Month(DateJour))
            If (Len(Mois) = 1) Then
                Mois = ("0" & Mois)
            End If
            Jour = CStr(Day(DateJour))
            If (Len(Jour) = 1) Then
                Jour = "0" & Jour
            End If
            
            ChaineDate = (Year(DateJour) & "-" & Mois & "-" & Jour)
            
            DateDuJour = ChaineDate
        
        End Function
        '
        


        VBA et les dates, c'est toujours spécial. Même sous VB.NET je dois parfois faire des pirouettes pour valider différents formats de dates.

        K
        1. Bonjour Kalissi,
          Alors les dates s'affichent effectivement correctement dans le formulaire. Par contre, ces combobox "date" renseignent les cellules E10, E13 et F13 de la feuille DATA, qui servent à faire les calculs de délais. Les dates malheureusement sont recopiées dans le mauvais format, du coup les calculs sont faussés. J'ai essayé pas mal de choses, mais j'avoue que je bloque encore. Si tu as une idée ça résoudrait déjà un problème.

          J'essaie d'alterner car si je passe trop de temps sur un blocage, je n'avance plus, donc en parallèle je tente de résoudre les petits beugs qui apparaissent mais franchement je ne suis pas sortie de l'auberge avec ce fichier... En tous cas je te remercie beaucoup de prendre sur ton temps pour m'aider.
      2. Bonjour,

        En effet, j'ai oublié une étape ... désolé...

        Donc, à partir du fichier d'origine ...

        1.) Dans la plage [ ListeDate ], modifier le format de toutes les cellules pour le format [ Standard ]
        2.) Détruire la formule dans la cellule G3
        3.) Copier la petite fonction DateDuJour ci-haut dans un module
        4.) Ajouter la nouvelle fonction à la cellule.

        Étangement j'ai la même erreur avec Excel 2013, erreur que je n'ai pas avec Excel 2002.

        Je vais devoir creusé.

        K
        1. J'ai oublié.

          Il te faut sélectionné de nouveau la date dans l'un des combobox pour que celle-ci s'affiche correctement.

          K
          1. Bonjour,

            Étape 2 :

            Sur la feuille DATA

            Dans la cellule G3, détruire la fonction que tu as installé.

            Dans l'éditeur de VB, créer un nouveau module que tu pourras renommer Fonctions.

            Ajoute cette fonction dans ce module :

            Option Explicit
            '
            
            Public Function DateDuJour() As String
            
                Dim DateJour As Date
                Dim ChaineDate As String
                
                Application.Volatile
                
                DateJour = Now
                
                ChaineDate = Format(DateJour, "yyyy-MM-dd")
                
                DateDuJour = ChaineDate
            
            End Function
            '
            


            Repositionne toi sur la cellule G3

            Ajoute une fonction, dans la liste déroulante (Ou sélectionné une catégorie) , choisir [ Personnalisées ]

            Ajoute la fonction DateDujour.

            Tu auras un message, mais n'en tiens pas compte.

            Dans la liste déroulante de tes dates de ton userform, la date s'affiche maintenant correctement.

            K
            1. Bonjour Kalissi,

              1) J'ai suivi tes instruction, mais, il se produit un beug lorsque j'exécute mon formulaire. Ca bloque au niveau du mot "Format" de la fonction DateDuJour. Impossible d'aller plus loin.

              Aujourd'hui, j'ai dupliqué mon fichier en faisant d'autres essais, entre autre, j'ai supprimé tous les combobox "date" en les remplaçant par des listbox. Pour les 2 combobox "date" qui me servaient à faire mes calculs de délais (date de réception) et (délai de traitement) dans DATA.

              Je les ai remplacés chacun par 3 listbox, 1 pour le JOUR, 1 pour le MOIS et l'autre pour l'ANNEE. Ensuite j'ai bidouillé sur ma feuille excel en concaténant les 3 cellules destinataires des 2x3 listbox pour obtenir une cellule "date" au bon format. J'ai réussi à reproduire ce que je voulais mais j'aime pas trop la méthode "bricolage" utilisée. J'aimerai bien y arriver avec ta proposition ... Si tu peux me dire ce qui ne va pas pour débloquer l'exécution de l'userform.

              2) Je me suis aperçue qu'en modifiant Les listes de la feuille DATA, pour une raison de confidentialité, j'ai provoqué des beug dans mes combobox (listes déroulantes dépendantes). J'ai passé toute la journée à reprendre ligne par ligne toutes les plages nommées. Sur les 15 références "enveloppes" qui ne fonctionnaient plus, il m'en reste toujours 2 qui bloquent.J'ai donc repris mon fichier d'origine en y reprenant tout ce qui avait été fait sur le fichier test.

              3) J'ai remplacé ma listview par une listbox car j'ai trouvé des tutos qui m'ont permis d'afficher dans mon userform les colonnes Excel que je souhaitais.

              J'avance doucement et je te remercie une fois encore pour ton aide. Si tu as une proposition pour débloquer le beug llié à la fonction DateDuJour, je suis preneuse.

              Merci.
          2. Bonjour

            Pour le format date dans les combobox vous pouvez essayer ceci

            Private Sub ComboBox12_Change()
            ComboBox12.Value = CDate(ComboBox12.Value)


            End Sub

            Ceci dit votre USF aurait besoin d'être redéfini à mon avis en le simplifiant.
            Essayez de mieux définir ce que vous souhaitez obtenir

            1. Merci beaucoup, je teste tout ça en espérant que ça va fonctionner.
              Cordialement,
          3. Bonjour,

            Observations :

            1.) Ce classeur contient beaucoup de plages nommées. Pour pouvoir décortiquer le tout
            il faut connaître ces plages nommées.

            Recommandation : Créer une nouvelle feuille Excel et rouler la macro ci-dessous pour avoir
            une liste des plages nommées avec les adresses correspondantes.

            Public Sub ListeNoms_OrdreFeuilles()
                
                Dim NomPlage As Name
                Dim PlageNom As Range
                Dim Boucle As Integer
                Dim NumLigne As Integer
             
                NumLigne = 1
                On Error Resume Next
             
                For Boucle = 1 To Worksheets.Count
                    
                    For Each NomPlage In Worksheets(Boucle).Parent.Names
                        Set PlageNom = Nothing
                        Set PlageNom = NomPlage.RefersToRange
             
                        If Not PlageNom Is Nothing Then
                            If Worksheets(Boucle).Index = PlageNom.Worksheet.Index Then
                                Cells(NumLigne, 1).Value = NomPlage.Name
                                Cells(NumLigne, 2).Value = NomPlage.RefersToRange.Value
                                Cells(NumLigne, 3).Value = NomPlage.RefersToRange.Address
                                
                                Worksheets(1).Hyperlinks.Add Anchor:=Cells(NumLigne, 4), _
                                    Address:="", SubAddress:=NomPlage.RefersToRange.Address(external:=True)
                                NumLigne = NumLigne + 1
                            End If
                        End If
             
                    Next NomPlage
                    
                Next Boucle
                
            End Sub
            


            2.) Le problème d'affichage de Dates

            Sour VBA, comme avec tous les langages que j'ai utilisé à ce jour, il faut distinguer
            le contenant du contenu.

            Un combobox est un contenant.
            Une date est un contenu.

            Or sous VBA un combobox est un contenant qui n'accepte qu'un contenu string.
            Une date n'est pas un contenu string, c'est un contenu date.

            La propriété RowSource du combobox10 pointe sur une plage nommé "ListeDate" et
            les cellules de cette plage sont au format "Date". Il y a incompatibilité de type.

            Tu ne peux pas mettre un contenu Date dans un contenant de type string.

            Il faut donc convertir le contenu afin de l'afficher dans le contenant.

            Ex.:
            Private Sub InitCombo_10()
            
                Dim PlageNomme As String
                Dim Cellule As Range
                Dim DateSelectionne As Date
                
                For Each Cellule In Sheets("DATA").Range("ListeDate")
                    DateSelectionne = Cellule.Value
                    If (DateSelectionne <> "00:00:00") Then
                        cbxDateReception.AddItem CStr(DateSelectionne)
                    End If
                Next Cellule
                
            End Sub
            


            C'est l'instruction CStr qui converti ici le contenu date en contenu string.
            J'ai fait simple ici et je n'ai pas vérifier l'effet de la transformation, il est
            probable qu'il y ait un formatage à faire pour obtenir la date au format souhaité.

            Donc toujours garder en tête que le contenu et le contenant doivent
            obligatoirement être de même type.

            Astuce : Pour conserver une date au format texte dans une cellule, introduire un apostrophe.

            ActiveCell.Value = " '2018-02-19 "
            Les espaces ne sont qu'a titre de clarté du texte => "'2018-02-19"

            La cellule conservera sont type string (i.e. texte).

            K
            1. Bonjour Kalissi,
              Merci infiniment d'avoir pris le temps de me répondre.
              Je ne sais pas si j'ai bien compris tes instructions, je vais déjà répertorier toutes mes cellules nommées et mettre le nouveau fichier en ligne.
              K
            2. Bonjour,

              Effectivement l'USF utilise de nombreuses références et il serait peut être souhaitable de simplifier en redéfinissant ce que vous souhaitez obtenir par cet USF.

              Comme indiqué par Kalissi, les combobox "n'aiment" pas le format date.

              Cependant vous pouvez tester ceci

              Private Sub ComboBox12_Change()
              ComboBox12.Value = CDate(ComboBox12.Value)
              
              End Sub


              par exemple.

              Cordialement
            3. @PassionofdreamBonjour Passionofdream et merci de te pencher sur mon fichier, j'ai vais tester ta proposition.
              Cordialement,