Utiliser un masque prédéfini tout en remplissant un Userform

Bonjour,

Voila ce que je souhaiterais faire.

J'ai un deux userform qui se remplisse avec des textbox. Je souhaiterais une fois les variables rentré dans les deux userform 1 et 2 les réccupérer jusque la pas de probleme.

Seulement la ou ca ce complique. Une fois le userform2 validé je voudrais qu'il créer une feuil avec le nom de la fleur en utilisant le masque que j'ai créé tout en renseignant les informations dans le tableau du masque.

Exemple : nom de la fleur : TULIPE, donc il me créé une feuil intitulé TULIPE en utilisant le masque défini avec son tableau.

Une fois cela réalisé :

J'ai dans mon userform2 un bouton intitulé "Renseigner la prochaine fleur", je voudrais qu'il rouvre le userform2 pour pouvoir renseigné les informations toujours de la même fleur ici donc TULIPE seulement les champs "couleur, quantité, champ" seront différent. Une fois ces valeurs renseigné je voudrais qu'il l'ajoute à la deuxième page de la feuil TULIPE et ainsi de suite.

Code utilisé pour le userform1:

Private Sub CommandButton1_Click()
    UserForm2.TextBox1.Value = Me.TextBox1.Value
    UserForm2.Show
End Sub

Code utilisé pour le userform2:

Private Sub CommandButton1_Click()

Dim couleur, ville, quantite As String
Dim fleur$

couleur = TextBox2.Value
ville = TextBox3.Value
quantite = TextBox4.Value

Range("N13").Value = couleur
Range("N14").Value = ville
Range("N15").Value = quantite

fleur = TextBox1.Value
Range("L6").Value = fleur

On Error GoTo créerfeuil
Worksheets(fleur).Activate

On Error GoTo 0
Unload Me

Exit Sub

créerfeuil:
        Worksheets.Add after:=Worksheets(Worksheets.Count)
        ActiveSheet.Name = fleur

        Unload Me
End Sub

Private Sub CommandButton2_Click()

UserForm1.Show

End Sub

Merci à tous pour votre aide.

En PJ le fichier que j'utilise

22test1.xlsm (169.24 Ko)

Bonjour,

J'ai l'impression que tu compliques un peu à loisir... Difficile de comprendre pourquoi deux Userforms alors qu'un suffirait amplement ! Et ce passage par un masque qui n'en est pas vraiment un...

Enfin pour remettre un peu d'ordre dans tout ça, on peut utiliser ce masque comme modèle.

Je n'interviens pas là-dessus, mais il est conseillé aussi de renommer ses contrôles (et je le préconise également).

Ce sera pour la prochaine fois (car cela se fait au début !)

Pour revoir un peu le code : Userform1

Private Sub CommandButton1_Click()
    UserForm2.TextBox1.Value = Me.TextBox1.Value
    UserForm2.Show
    Unload Me
End Sub

Private Sub CommandButton2_Click()
    '?quel rôle ?
End Sub

Private Sub CommandButton3_Click()
    Unload Me
End Sub

Private Sub TextBox1_Change()
    TextBox1.Value = UCase(TextBox1.Value)
End Sub

Tu as certainement prévu une utilisation du bouton Retour mais on ne peut le déduire. Retour à quoi ?

Si tu mets tes libellés en majuscules, autant faciliter la saisie !

Pour Userform2 :

Private Sub CommandButton2_Click()
    UserForm1.Show
End Sub

Private Sub TextBox2_Change()
    TextBox2.Value = UCase(TextBox2.Value)
End Sub

Private Sub TextBox3_Change()
    If Not IsNumeric(TextBox3.Value) Then TextBox3.Value = ""
End Sub

Private Sub TextBox4_Change()
    TextBox4.Value = UCase(TextBox4.Value)
End Sub

Même compléments pour la saisie. D'autant qu'aucune vérification à la validation.

NB- La propriété TabStop de TextBox1 (préservi) doit être mise à False.

La procédure de validation :

Private Sub CommandButton1_Click()
    Dim fleur(3) As String, i%
    For i = 0 To 3
        fleur(i) = Controls("TextBox" & i + 1).Value
    Next i
    Application.ScreenUpdating = False
    On Error GoTo créerfeuil
    With Worksheets(fleur(0))
        On Error GoTo 0
        For i = 1 To 3
            .Range("N" & i + 12).Value = fleur(i)
        Next i
        .Activate
    End With
    Application.ScreenUpdating = True
    Unload Me
    Exit Sub
créerfeuil:
    ActiveSheet.Copy after:=ActiveSheet
    ActiveSheet.Name = fleur(0)
    Worksheets(fleur(0)).Range("L6") = fleur(0)
    Resume
End Sub

Tu l'analyseras ! Comme dit plus haut, le masque n'est pas utilisé comme relais mais sert de modèle : au lieu d'ajouter une feuille on copie le masque, et on sert directement la nouvelle feuille (et si elle existe déjà, on sert celle qui existe).

La copie est réalisée en gestion d'erreur.

J'ai introduit quelques boucles et un tableau, les longues énumérations deviennent vite fastidieuses et si on peut les éviter...

Je te signale aussi, que sur l'ensemble du code auquel je touche, je le remets toujours en forme, parfaitement indenté de façon classique. Et je n'apprécie guère de devoir retoucher un code que j'ai fourni, désindenté et avec diverses lignes intermédiaires vide rajoutées, ce qui ne permet plus à la lecture de se repérer d'un seul coup d'oeil ! ...

Voit si ça correspond à l'orientation de ton projet.


14lolo92-test1.xlsm (36.53 Ko)

Merci beaucoup MFerrand c'est énorme !!!

J'ai repris ton code en touchant le moins possible afin que tu puisse aussi te relire facilement.

J'ai essayé de décrypter un peu tout mais pas non plus facile facile j'ai mis des commentaires pour un peu mieux comprendre si c'est faux peux tu me les corriger? J'espere que je n'ai pas tout faux non plus. Lol. Merci encore

Sur le Userform1 j'ai viré le bouton retour qui ne servait à rien comme tu avais pu le souligner.

Userform1 :

Private Sub CommandButton1_Click()
    UserForm2.TextBox1.Value = Me.TextBox1.Value
    UserForm2.Show
    Unload Me

    ' 1- Peut on mettre une sécurité si le nom de la fleur n'est pas renseigné il écrit un msgbox (" Il manque le nom de la fleur ! ") et ne peux pas aller sur le userform2 ? 

End Sub

Private Sub CommandButton3_Click()
    Unload Me
End Sub

Private Sub TextBox1_Change()
    TextBox1.Value = UCase(TextBox1.Value) ' Pas nécessaire pour les majuscules mais c'est un + merci
End Sub

Pour le userform2, il faudrait essayé de traduire le vert en code si possible.

Private Sub CommandButton2_Click()
    Unload Me
    UserForm2.Show
    ' 1 - A cette étape si possible il faudrait faire une boucle pour que le userform2 se recharge en gardant en mémoire uniquement le nom de la fleur dans le textbox1.
    ' 2 - Une fois les nouvelles informations renseigné il faudrait qu'il ajoute sur la page 2 les nouvelles informations et non sur la page 1 et ainsi de suite si on veux renseigner à nouveau.
    ' Question : Peux t'on laisser les sauts de pages en mémoire dans le masque car une fois renseigné je devrais l'imprimer ?

End Sub

Private Sub TextBox2_Change()
    TextBox2.Value = UCase(TextBox2.Value)
End Sub

Private Sub TextBox3_Change()
    If Not IsNumeric(TextBox3.Value) Then TextBox3.Value = ""
End Sub

Private Sub TextBox4_Change()
    TextBox4.Value = UCase(TextBox4.Value)
End Sub

Pour le bouton validation du userform2, j'ai "essayé de comprendre" chaque étape et la c'est plus dur, si erreur peu tu me corriger ? Merci

Private Sub CommandButton1_Click()
    Dim fleur(3) As String, i%  ' 1 - Ici tu déclares trois variables comme des chaines de caractère ? , a quoi sert le i% ?
    For i = 0 To 3               ' 2 - Tu initiale des variables ?
        fleur(i) = Controls("TextBox" & i + 1).Value ' 3 - Pour chaque variable tu demandes d'enregistrer les 3 valeurs ?
    Next i ' 4 - Une fois la valeurs enregistré tu passe à la suivante jusqua 3 max ?
    Application.ScreenUpdating = False ' 5 - Cela permet de ne pas figer l'écran ?
    On Error GoTo créerfeuil ' 6 - Il créé un erreur afin de créer une feuille
    With Worksheets(fleur(0)) ' 11 - Il rentre dans la feuille dont la valeur est le nom de la fleur
        On Error GoTo 0 ' 12 - Si erreur il va sur 0 ?
        For i = 1 To 3 ' 13 - Tu initiales des 3 valeurs
            .Range("N" & i + 12).Value = fleur(i) ' 14 - Tu cherche la colonne N puis la ligne 13 et tu met la premiere valeur et ainsi de suite..
        Next i ' 15 - boucle qui continue jusqua 3
        .Activate ' 16 - ?
    End With ' 17 - On ferme l'instruction sur la page ?
    Application.ScreenUpdating = True ' 18 On ne fige pas l'écran
    Unload Me ' 19 - On ferme le userform2
    Exit Sub ' 20 - On sort
créerfeuil: ' 7 - Création de la feuille
    ActiveSheet.Copy after:=ActiveSheet '8 - Il copie le masque
    ActiveSheet.Name = fleur(0) ' 9 - Il prend le nom de la feuille avec la première valeur qui correspond au nom de la fleur
    Worksheets(fleur(0)).Range("L6") = fleur(0) ' 10 - Il copie le nom de la fleur dans la colonne L6
    Resume ' 10bis - ?
End Sub
17lolo92-test1.xlsm (36.96 Ko)

Bonjour,

On va reprendre point par point... en plusieurs fois si nécessaire.

Il va y avoir aussi quelques procédures à reprendre mais il va falloir que tu donnes quelques détails de plus sur ton projet pour qu'on puisse retenir la méthode la plus adéquate...

Je vais revenir...

A+ Bonne journée

Bonjour MFerrand,

D'accord, merci beaucoup pour ton aide.

Bonne journée également.

Re,

Commençons par les explications, elles serviront pour la suite et au-delà...

Private Sub CommandButton1_Click()
    Dim fleur(3) As String, i%  ' 1 - Ici tu déclares trois variables comme des chaines de caractère ? , a quoi sert le i% ?

Ce n'est pas tout à fait ça ! je déclare 2 variables :

  • une variable tableau, d'indice le plus élevé 3, donc de 4 éléments (0 à 3), l'indice minimal d'un tableau lorsqu'on ne l'indique pas est 0 (hors modification de l'Option Base), les éléments qui pourront être affectés à ce tableau seront de type texte (String) ;
  • et une variable i de type Integer qui servira de compteur de boucle.
On type les variable par l'instruction : As type (As String ou As Integer dans notre cas) mais il est possible pour certains types de données d'utiliser un caractère de déclaration de type : i% c'est identique à i As Integer, ou fleur$ identique à fleur As String.

J'en profite pour te rappeler que lorsque tu écris : Dim couleur, quantité, ville As String tu ne déclares qu'une seule variable de type String, couleur et quantité seront de type Variant comme toute variable non typée. Chaque variable doit être typée individuellement, il fallait donc écrire : Dim couleur As String, quantité As String, ville As String.

Ou (pour raccourcir la ligne) Dim couleur$, quantité$, ville$.

For i = 0 To 3               ' 2 - Tu initiale des variables ?

La variable tableau fleur sera bien initialisée à l'intérieur de la boucle, mais cette commande ne fait qu'initialiser la boucle dans laquelle i prendra successivement les valeurs 0 à 3.

fleur(i) = Controls("TextBox" & i + 1).Value ' 3 - Pour chaque variable tu demandes d'enregistrer les 3 valeurs ?

Voilà l'initialisation de la variable fleur qui va accueillir 4 éléments (et non 3 seulement) : les valeurs des TextBox1 à 4.

Next i ' 4 - Une fois la valeurs enregistré tu passe à la suivante jusqua 3 max ?

Voir ci-dessus.

Application.ScreenUpdating = False ' 5 - Cela permet de ne pas figer l'écran ?

Cette commande inhibe le rafraichissement de l'écran. Elle sert lorsque les commandes qui s'exécuteront à la suite provoqueront une modification de l'affichage écran, cela évite des modifications visuelles rapides pour l'utilisateur et surtout cela permet à l'exécution du code d'être plus rapide...

On Error GoTo créerfeuil ' 6 - Il créé un erreur afin de créer une feuille
    With Worksheets(fleur(0)) ' 11 - Il rentre dans la feuille dont la valeur est le nom de la fleur
        On Error GoTo 0 ' 12 - Si erreur il va sur 0 ?

La première ligne prend en charge une gestion d'erreur : si une erreur survient après cette commande, l'exécution du code sera basculée à l'étiquette créerfeuil et se poursuivra par ce qui suit cette étiquette de branchement.

La dernière ligne supprime cette gestion d'erreur pour revenir à l'effet normal (fatal !) des erreurs d'exécution : interruption de l'exécution du code...

La deuxième ligne par l'instruction With met en mémoire la feuille recherchée (fleur(0) correspond au nom de fleur qui désigne une feuille existante ou à créer). Toutes les expressions après cette ligne initiée par With, jusqu'à ce que l'instruction End With y mette fin, qui seront débutées par un point (.) réfèreront à l'objet mémorisé avec With.

Evidemment, si la feuille n'existe pas, une erreur surviendra (d'où la gestion d'erreur) que l'on mettra à profit pour la créer (avant de revenir sur cette instruction pour poursuivre la procédure).

        For i = 1 To 3 ' 13 - Tu initiales des 3 valeurs
            .Range("N" & i + 12).Value = fleur(i) ' 14 - Tu cherche la colonne N puis la ligne 13 et tu met la premiere valeur et ainsi de suite..
        Next i ' 15 - boucle qui continue jusqua 3

Nouvelle boucle qui va affecter aux cellules N13 à 15 de la feuille (déjà existante ou créée, nom recueilli dans fleur(0)) les autres éléments recueillis dans le tableaux fleur (couleur, quantité, ville).

        .Activate ' 16 - ?
    End With ' 17 - On ferme l'instruction sur la page ?

La feuille est activée (pour affichage à l'utilisateur en fin de procédure).

L'instruction End With sort de la mémoire la feuille qu'on y avait mis avec With.

    Application.ScreenUpdating = True ' 18 On ne fige pas l'écran
    Unload Me ' 19 - On ferme le userform2
    Exit Sub ' 20 - On sort

On rafraîchit l'affichage écran. On ferme le Userform. Et on sort de la procédure (pour ne pas exécuter ou reéxécuter le code gérant l'erreur éventuelle en créant la feuille si elle n'existait pas (qui suit).

créerfeuil: ' 7 - Création de la feuille
    ActiveSheet.Copy after:=ActiveSheet '8 - Il copie le masque
    ActiveSheet.Name = fleur(0) ' 9 - Il prend le nom de la feuille avec la première valeur qui correspond au nom de la fleur
    Worksheets(fleur(0)).Range("L6") = fleur(0) ' 10 - Il copie le nom de la fleur dans la colonne L6
    Resume ' 10bis - ?
End Sub

A la suite de l'étiquette de branchement sur erreur (provoquée par l'inexistence de la feuille recherchée), on procède à la création de la feuille.

On le fait par copie de la feuille masque (cette feuille est depuis le début du programme lancé par un bouton sur cette feuille, la feuille active...). On place la copie immédiatement derrière.

A ce moment, la copie devient la feuille active (un automatisme d'Excel !) : on la renomme donc du nom prévu.

On affecte également ce nom en L6. Ce qui évite de le faire dans le corps de la procédure (et ce nom étant mis à la création ainsi pour toutes les feuilles créées, on n'aura plus à le faire).

L'instruction Resume renvoie la poursuite de l'exécution du code à la ligne exacte sur laquelle est survenue l'erreur : on reprend donc avec With... qui trouvera maintenant la feuille qu'on vient de créer...

Voilà pour compléter les explications. Ouf !

Avant de poursuivre sur les réaménagements que tu souhaites j'aimerais éclaircir quelques questions :

1) Pourquoi 2 Userforms ?

Le premier ne fait qu'appeler le second en lui passant le nom cherché.

Le second suffirait donc amplement ! Et en ne faisant apparaître les TextBox 2 à 4 qu'après que TextBox1 soit servi, on aurait le même effet qu'actuellement en économisant un Userform...

2) La finalité de ton opération, car tu veux qu'on puisse mettre sur une feuille une 2e saisie, mais est-ce limité à deux ?

Cela pose évidemment un petit problème... On a évité jusqu'ici des procédures fastidieuses de mise en forme, ce qui est toujours souhaitable en utilisant des modèles chaque fois qu'on le peut.

Tout dépend de ce qui doit se passer ensuite, car là on n'en est qu'à la saisie visant à constituer des feuilles...

Selon les cas, il serait sans doute préférable d'utiliser la saisie pour constituer une base de données (éventuellement temporaire) et procéder à l'opération suivante une fois la saisie effectuée.

3) Un peu la même question mais sous un autre angle : un certain nombre d'indice laissent penser que les feuilles sont destinées à être imprimées. La notion de page dans Excel n'a d'existence que pour l'impression... Et dans ce cas la mise en forme évoquée ci-dessus n'en est plus une, mais une mise en page, ce qui est assez notablement différent.

Cela plaide en faveur d'un examen de la finalité du projet et des différentes phases du processus que tu mets en oeuvre pour le développer à partir d'une conception d'ensemble au lieu de le faire par petits bouts sans savoir à l'avance s'ils se raccorderont bien les uns aux autres de façon harmonieuse et efficace...

Cordialement.

Rechercher des sujets similaires à "utiliser masque predefini tout remplissant userform"