Premier programme Excel VBA userform

Re,

Bon le zoom c'est pas l'idéal, je regarde cela dès que possible.

et j'ai fait un enregistrement et la fermeture à la fin du test.

Çà en mode phase de tests ce n'est pas l'idéal non plus. ce n'est rien à faire et cela peut attendre au niveau de la finalisation du programme.

oui, c'est sur, mais on peut les commenter pour les rendre inactive.

mais j'étais content d'avoir compris un petit bout du code, et surtout réussi à modifier sans tout casser.

parce que pour le moment, je ne comprend pas grand chose, j'ai l'impression que chaque ligne fait référence à une variable pour faire une action mais les actions sont nommées elle aussi sous forme de variables, sans parler des instruction que je ne connais pas donc je passe plus de temps à chercher à quoi servent les instructions etc, pour essayer de décoder le code.

en même temps, c'est bénéfique, ça me donne des idées pour les fichiers que j'ai déjà fait et ou j'ai des formules qui impliquent jusqu'à une quarantaine de sous formule pour trouver la bonne cellule. par exemple, si le résultat d'un test est 42, je lit la première ligne, si ce n'est pas = 42, je lis la deuxième, etc, jusqu'à trouver la bonne ligne, et ensuite récupérer le contenu d'une cellule qui se trouve dans cette ligne mais dont je calcule aussi le numéro de colonne en fonction du nom. ça fonctionne, mais je dois réduire la fenêtre Excel au maximum pour avoir environ la moitie de la formule dans la barre de formule.

donc je verrai pour retravailler mes autres fichiers quand celui la sera terminé

Re,

je lit la première ligne, si ce n'est pas = 42, je lis la deuxième, etc

Çà c'est la méthode simple, maintenant tu as la solution d'utiliser une fonction. Prêt c'est parti pour les explications.

Le but d'une fonction c'est de renvoyer un résultat par exemple la fonction ci-dessous

' // Ici la fonction qui est du type Long
Public Function Multiplie(ByVal Nombre1 As Long, Nombre2 As Long) As Long 
    Dim ReturnValue as Long
    ReturnValue = Nombre1 * Nombre2
    Multiplie = ReturnValue
End Function

' // La fonction peut être appelée dans n’importe quel module, exemple
Private Sub ThisWorkbook_Open
    MsgBox "La multiplication vaut : " & Multiplie(3, 2)
End Sub

Maintenant un exemple concret du classeur sur lequel tu bosses.
Au lieu de boucler à chaque fois que l'on veux faire une recherche, on va créer un fonction qui le fait pour nous.

Dans le module Settings tu as la fonction GetListRow elle te permet de récupérer une ligne dont une colonne contient une valeur recherchée :

'@Description "Retourne une ligne d'un tableau depuis la recherche d'une valeur dans une colonne"
Private Function GetListRow(ByVal Table As Excel.ListObject, ByVal ColumnName As String, ByVal Value As Variant) As Excel.ListRow
    Dim Formula As String
    Dim index As Long

    If TypeName(Value) = "String" Then Value = """" & Value & """" Else Value = Value * 1
    Formula = "iferror(match({value},{table}[{column}],0),0)"
    Formula = Replace(Formula, "{value}", Value)
    Formula = Replace(Formula, "{table}", Table.Name)
    Formula = Replace(Formula, "{column}", ColumnName)
    index = Evaluate(Formula)
    If index > 0 Then Set GetListRow = Table.ListRows(index)
End Function

Je me sert pratiquement toujours de l'intelisence de VBA ça facilite la saisie teste en saisissant dans un module tabsmanagement. tu auras ceci :

image

Cela te montre les procédures et fonctions qui sont dans le module. Voilà pourquoi il faut donner des noms explicites aux modules.
Cette fonction ne peux pas tout faire, si la valeur recherchée est présente plusieurs fois, c'est la première qui sera sélectionnée. Je m'en sert principalement pour récupérer une ligne par rapport à son ID unique (Voir dans le tableau structuré)

Donc si j'ai besoin de modifier une ligne ou de remplir des contrôles par rapport aux valeurs d'une ligne, j'appelle la fonction :

Private Sub cmdValid_Click()
    ' // J'affecte une variable ListRow
    Dim itemRow As Excel.ListRow

    '  // Ici je récupère la ligne
    '  // Quand c'est un object on utilise Set 
    Set itemRow = TabsManagement.GetListRow(Factory.InitDataBase, "ID", ContactNom.Column(0))
    With itemRow
    '  // Ici je parcours les cellules de la ligne, et je leurs affecte la valeur du contrôle correspondant
        .Range(.Parent.ListColumns("N° Seq").index).Value = CDate(ContactDate + ContactHeure)
        .Range(.Parent.ListColumns("Prénom").index).Value = StrConv(ContactPrenom.Value, vbProperCase)
        .Range(.Parent.ListColumns("Date").index).Value = CDate(ContactDate.Value)
        .Range(.Parent.ListColumns("Heure").index).Value = CDate(ContactHeure.Value)
        .Range(.Parent.ListColumns("Courriel").index).Value = LCase(ContactCourriel.Value)
        .Range(.Parent.ListColumns("Sexe").index).Value = ContactGenre.Value
        .Range(.Parent.ListColumns("Date de naissance").index).Value = CDate(ContactAnniversaire.Value)
        .Range(.Parent.ListColumns("Age").index).Value = DateDiff("yyyy", CDate(ContactAnniversaire.Value), Date)
    End With
End Sub

En détails :

image

GetListRow demande 3 Arguments :

  • Le ListObject (tableau structuré) où l'on va cherché la ligne.
  • Le nom de la colonne où se fait la recherche.
  • La valeur cherchée.

Concernant le tableau structuré où doit se faire la recherche on pourrait le renseigné directement avec par exemple ThisWorkbook.Worksheets("Base").Range("vt_Datas").ListObject. Mais là encore j'utilise une fonction qui se trouve dans le module Factory. Pourquoi ? Tout simplement pour ne pas être obliger de se rappeler du nom des tableaux, de plus si l'on change le nom du tableau plus besoin de vérifier tout le code. je ne change le nom que dans une fonction.

bonjour,

je vais essayer de digérer tout ca, et voir dompter la bête en créant un autre userform pour la partie test audio, comme ça si ça fonctionne on pourra l'intégrer le code dans le fichier et si ça ne fonctionne pas je n'abime rien, mais en attendant je vais devoir mettre le projet en pause une quinzaine de jours :

mon cumulus vient de lâcher et comme les ennuis ne viennent jamais seul, je part demain réparer la voiture de mon fils, il as eut un soucis mécanique ce matin en partant au travail et comme il as besoin d'une voiture il prendra la mienne pendant que je répare la sienne, donc je part demain matin et j'arriverai chez lui en fin d'après midi. ca me laisse le Week end pour contrôler l'étendu de dégâts et commander les pièces pour réparer.

ensuite le temps que ça arrive, j'essayerai de bosser un peu sur le fichier et quand j'aurai reçu les pièces, je répare son auto, tout ça prendra bien une bonne semaine et en rentrant je remplace mon cumulus.

Bonjour,

Pas de problème, on ne bouge pas.

merci de votre compréhension, j'avais vraiment pas prévu de faire 800km pour aller à Nantes cette semaine. surtout pour rester seul vu qu'il travaille.

bon ça fera quand même plaisir de le revoir, il n'est pas revenu depuis son départ en Aout.

bonjour tout le monde,

ça y est, je suis de retour parmi vous, j'ai pas eut le temps d'avancer sur le programme, j'ai même fais pire que mieux, maintenant ça ne fonctionne plus.

heureusement que j'ai fait une copie pour travailler dessus.

Bien le bonjour,

Hum, c'est la base les sauvegardes.

Une méthode que j'utilise ce n'est surement pas la meilleure.

Je copie et colle le classeur, je renomme le classeur d'origine en v1.1, premier chiffre pour les version majeures deuxième pour les versions mineures.

Je renomme la copie avec le non d'origine du classeur , je ne garde que deux classeur dans le dossier principal, les autres finissent dans un dossier Save.

bonjour tout le monde,

après mon retour de Nantes, j'ai fait des petits travaux de jardinage et l'entretien de la maison donc je n'ai pas vraiment eut le temps de m'occuper du programme mais cette semaine j'ai quand même avancé un peu.

donc Jean Paul, je n'ai pas trouvé pourquoi ton programme ne fonctionnai plus, donc j'ai repris la sauvegarde que j'ai mise de coté pour les insertions ultérieur de code, et comme je t'avais dit avant de partir a Nantes, je suis reparti sur un nouveau userform (en fait mon premier que j'ai épuré) pour avancer sur le test en lui même puisque la page d'accueil du tien était quasiment terminé.

et comme j'avais dit que j'aurai essayé d'avancer, je ne voulais pas revenir les mains vide alors j'ai cherché et je pense être sur la bonne voie.

les explications fonctionnent, mais ça c'était simple, le test avance mais as encore quelques problèmes :

Excel dit bien les mots à la bonne cadence, mais sur le test 1 je n'arrive pas à récupérer la frappe et mon chrono reste toujours à 0, par contre le test 2 récupère bien la frappe mais seulement avec une boite de dialogue et est très lent.

je te met mon avancé, je sais qu'il faut d'abord terminer la page d'accueil mais comme je casse tout à chaque fois que j'y touche, te serait il possible de le commenter afin que je comprenne comment ton code fonctionne.

Bonjour,

serait il possible de le commenter afin que je comprenne comment ton code fonctionne.

C'est un peu compliqué de commenter tout le code, donne moi des exemple de ce qui n'est pas compris et j'en ferais une explication.

Excel dit bien les mots à la bonne cadence, mais sur le test 1 je n'arrive pas à récupérer la frappe et mon chrono reste toujours à 0, par contre le test 2 récupère bien la frappe mais seulement avec une boite de dialogue et est très lent.

Je regarde cela dès que j'ai une minute...

bonjour,

c'est vrai que j'ai mis un peu de temps, mais comme tu l'as dis, c'est compliqué de commenter le code, et j'ai passé beaucoup de temps a chercher sur le site microsoft pour le faire.

donc, voila, j'ai tout commenté et j'ai mis des " ? " quand je ne sais pas à quoi ça sert.

par contre, je n'ai toujours pas trouvé comment on change de frame dans l'userform ni le code des frames.

je te mets ton fichier commenté.

Bonjour à tous,

Petit retour sur le fichier :

Sur ce style de code :

' ?
Private Sub cmdDisplaySystemNames_Click()
    Administrateur.DisplaySystemNames
End Sub

Si je n'ai pas mis de description c'est tout simplement que c'est un contrôle du formulaire, ici en occurrence un des boutons de la Frame Administrateur du formulaire Accueil.
C'est valable pour les autres boutons qui sont en fait des Labels détournés en boutons, concernant les méthodes MousseDown et MousseUp c'est tout simplement pour recréer l'enfoncement du bouton, on déplace le bouton de 1 pixel vers la droite et le bas puis on le remet à sa place initiale.

Comme je le dis souvent Les commentaires tues les commentaires, donc il faut mettre un minimum de commentaires, avec une explication rapide.

Bien entendu il faut connaître les bases pour, par exemple Les variables, et ne pas rajouter de commentaires dans le style :
Dim IsValid As Boolean ' variable "isvalid" renvoie vrai ou faux
Donc dans un premier temps se familiariser avec les variables.

J’évite aussi la notation Hongroise qui selon moi alourdi le code donc :
Je nomme un champ texte, Nom, ou NomPatient, etc. et non pas txtNom, de même pour par exemple le bouton de navigation que j'ai nommer tout simplement Navigation.

Maintenant décortiquons quelques lignes de code :

' // initialisation userform
Private Sub UserForm_Initialize()
    ' // On se positionne sur la page accueil du multipage
    MultiPage1.Value = 0

    ' // On charge la zone de liste déroulante
    Genre.List = VBA.Array("Féminin", "Masculin")

    ' // Le bouton valider est actif si tous les contrôles sont remplis
    ValiderSaisie.Enabled = (IsValidEntries = True)

    ' // On désactive le bouton de navigation et de test Speech si l'on n'est pas en mode tests
    Dim TestMode As Boolean
    ' // La fonction GetParams récupère la valeur d'un paramètre dans le tableau des paramètres
    ' // Cela me permet de sauvegarder certains paramètres à la fermeture du classeur.
    ' // Cette fonction à comme paramètres : Le Tableau structuré (qui conteient les paramètres, Le paramètre recherché (ici "Miscellaneous.TestsMode") et la valeur renvoiyée si le^paramètre n'est pas trouvé
    TestMode = GetParams(Factory.InitSettingsTab, "Miscellaneous.TestsMode", False)
    ' // Ici je détermime si le bouton Navigation doit-être visible ou pas, selon la valeur de TestMode
    Navigation.Visible = (TestMode = True)
    ' // Ici je détermime si le bouton TestSpeechCommand doit-être visible ou pas, selon la valeur de TestMode
    TestSpeechCommand.Visible = (TestMode = True)

    ' // On initialise les dimensions du formulaire
    InitForm
End Sub

Un autre exemple :

'@Description "Initialise les dimensions du formulaire"
Private Sub InitForm()
    Static OpenState As Boolean                  ' // Déclaration d'une variable en Static (Elle garde sa valeur tant que le classeur est ouvert et que le code n'est pas stoppé sur une erreur par exemple)
    Select Case OpenState                        ' // Une variable Boolean a une valeur False à l'initialisation, un Long = 0, Un String = "", un Object = Nothing...
        Case False                               ' case = faux
            Me.Width = 774                       ' taille
            With OpenClose                       ' // Le With évite de répéter le nom du contrôle
                .Left = Me.Width - 42            ' taille - 42 à gauche
                .Picture = Me.OpenPicture.Picture ' ouvrir photo
            End With
            OpenState = Not (OpenState)          ' // Not inverse la valeur de la variable Vrai devient Faux

        Case True                                ' case = vrai
            Me.Width = 971                       ' taille
            With OpenClose                       ' // Le With évite de répéter le nom du contrôle
                .Left = Me.Width - 42            ' taille - 42 à gauche
                .Picture = Me.ClosePicture.Picture ' ouvrir photo
            End With
            OpenState = Not (OpenState)          ' // Not inverse la valeur de la variable Vrai devient Faux
    End Select
End Sub

De bons réflexes qu'ils faut acquérir :

000530
Rechercher des sujets similaires à "premier programme vba userform"