Recuperation liste déroulante
Bonjour,
En pleine création d'un formulaire de saisie et d'enregistrement auto des données saisies, je n'arrive pas en enregistrer dans une cellule, le choix qu'un utilisateur devra faire dans une liste déroulante (combox). J'arrive à récupérer les données saisies dans la zone du text du formulaire. Merci d'avance pour votre aide
Voici un bout de mon code :
Private Sub btnSaveData_Click()
Dim ligne As Integer
'S'il y a des erreurs detectées, on annule la saisie
If MsgBox("Etes-vous sûre des données saisies ?", vbYesNo, "Vérification saisies") = vbYes Then
dateSaisie = Format(Date, "dd/mm/yyyy") 'insertion auto de la date de saisie
Select Case (listeRefBase)
'**********gestion de la feuille 10645******************
Case Is = 10645 '***************************************
Sheets("10645").Activate
ligne = ligneVide()
Cells(ligne, 1).Select
ActiveCell = dateSaisie
ActiveCell.Offset(0, 1).Value = listTypeTest '******************* LISTE DEROULANTE DANS LE FORMULAIRE
ActiveCell.Offset(0, 2).Value = listRefBase ****************** LISTE DEROULANTE DANS LE FORMULAIRE
ActiveCell.Offset(0, 3).Value = txtOfEb.Value ****************** A partir de là, zone de texte dans le formulaire
ActiveCell.Offset(0, 4).Value = txtOfPiece.Value
ActiveCell.Offset(0, 5).Value = txtDateCoupeEb.Value
ActiveCell.Offset(0, 6).Value = txtMi1.Value
ActiveCell.Offset(0, 7).Value = txtMi2.Value
ActiveCell.Offset(0, 8).Value = txtMi3.Value
ActiveCell.Offset(0, 9).Value = txtMi4.Value
ActiveCell.Offset(0, 10).Value = txtMf1.Value
ActiveCell.Offset(0, 11).Value = txtMf2.Value
ActiveCell.Offset(0, 12).Value = txtMf3.Value
ActiveCell.Offset(0, 13).Value = txtMf4.Value
ActiveCell.Offset(0, 14).Value = txtCom.Value
MsgBox "Données enregistrées !", vbOKOnly + vbInformation, "Confirmation"
Bonsoir,
Je ne vois pas quel est le problème que tu soulèves ! ? Une fichier d'illustration aurait permis peut-être d'y voir plus clair.
Ta proc. citée est incomplète : un seul Case et pas de End Select... [NB- Il faudrait penser à utiliser les balises code pour citer du code, ça permet de mieux le lire, et s'il est indenté, on le lira encore mieux !
On ne voit pas quel choix tu n'arrives pas à enregistrer puisque tu ne le dis pas !
Mais à ce qu'il apparaît de ton code :
- On ne voit qu'une variable déclarée, alors que plusieurs sont utilisées, (peut-être sont -elles déclarées au niveau module, mais si c'est le cas ce n'est pas a-priori une bonne idée...
- Certaines apparaissent inutiles comme dateSaisie pour y affecter la date du jour, et qui plus est la formater !!
Ce qui est particulièrement à éviter, on la trnsforme en texte et on la rend vulnérable.
Il suffisait d'une affectation directe :
......... = Dateet la date sera mise au format de la cellule s'il préexiste, ou au format par défaut (jj/mm/aaaa) si la cellule était au format standard (qu'Excel se charge de modifier automatiquement.
- L'utilisation de Activate, Select, ActiveCell... ne fait pas non plus partie de ce qui fait un bon code, précis et efficace...
- Et l'affectation cellule par cellule, au fil d'une longue énumération, manque aussi quelque peu d'élégance... VBA fournit de nombreux outils (boucles, tableaux...) permettant un travail précis en produisant moins de code écrit.
- Pour revenir sur les dates, il semble qu'il y en ait d'affectée en provenance de TextBox. Pour éviter les surprises, une date issue de TextBox se convertit toujours en date lors de l'affectation.
Cordialement.
Bonjour, merci pour la réponse rapide,
Je précise que je suis tout à fait novice dans le VBA et tout ce que vous dites ne m'étonnes pas du tout ^^ Je suis loin de savoir comment utiliser les fonctions les plus "safe" et "élégantes" comme vous dites, je compte sur vous pour me montrer des exemples pour en apprendre d'avantage ^^
Voici donc mon code entier et plus bas une illustration de ce que devrait faire mon code (on voit sur la feuille excel que le choix fait dans la liste déroulante du formulaire n'a pas été enregiistré, toutes les autres variables l'ont été)
Private Sub txtMf1_Change()
If txtMf1 <> "" Then
btnSaveData.Enabled = True
Else
btnSaveData.Enabled = False
End If
End Sub
'******************************
'PARAMETRES INITIAUX DU FORMULAIRE
'******************************
Private Sub UserForm_Initialize()
With Me.listeTypeTest
.AddItem "liner"
.AddItem "vmq"
.AddItem "composite"
End With
With Me.listeRefBase
.AddItem "10 645"
.AddItem "10 656"
End With
End Sub
'********************************************************
'SAUVERGARDE DES DONNEES : BOUTON ENREGISTRER LES DONNEES
'********************************************************
Private Sub btnSaveData_Click()
Dim ligne As Integer
'S'il y a des erreurs detectées, on annule la saisie
If MsgBox("Etes-vous sûre des données saisies ?", vbYesNo, "Vérification saisies") = vbYes Then
dateSaisie = Format(Date, "dd/mm/yyyy") 'insertion auto de la date de saisie
Select Case (listeRefBase)
'**********gestion de la feuille 10645******************
Case Is = 10645 '***************************************
Sheets("10645").Activate
ligne = ligneVide()
Cells(ligne, 1).Select
ActiveCell = dateSaisie
ActiveCell.Offset(0, 1).Value = listTypeTest
ActiveCell.Offset(0, 2).Value = listRefBase
ActiveCell.Offset(0, 3).Value = txtOfEb.Value
ActiveCell.Offset(0, 4).Value = txtOfPiece.Value
ActiveCell.Offset(0, 5).Value = txtDateCoupeEb.Value
ActiveCell.Offset(0, 6).Value = txtMi1.Value
ActiveCell.Offset(0, 7).Value = txtMi2.Value
ActiveCell.Offset(0, 8).Value = txtMi3.Value
ActiveCell.Offset(0, 9).Value = txtMi4.Value
ActiveCell.Offset(0, 10).Value = txtMf1.Value
ActiveCell.Offset(0, 11).Value = txtMf2.Value
ActiveCell.Offset(0, 12).Value = txtMf3.Value
ActiveCell.Offset(0, 13).Value = txtMf4.Value
ActiveCell.Offset(0, 14).Value = txtCom.Value
MsgBox "Données enregistrées !", vbOKOnly + vbInformation, "Confirmation"
Case Is = 10656 '***************************************
Sheets("10656").Activate
ligne = ligneVide()
Cells(ligne, 1).Select
ActiveCell = dateSaisie
ActiveCell.Offset(0, 1).Value = listTypeTest.Value
ActiveCell.Offset(0, 2).Value = listRefBase.Value
ActiveCell.Offset(0, 3).Value = txtOfEb.Value
ActiveCell.Offset(0, 4).Value = txtOfPiece.Value
ActiveCell.Offset(0, 5).Value = txtDateCoupeEb.Value
ActiveCell.Offset(0, 6).Value = txtMi1.Value
ActiveCell.Offset(0, 7).Value = txtMi2.Value
ActiveCell.Offset(0, 8).Value = txtMi3.Value
ActiveCell.Offset(0, 9).Value = txtMi4.Value
ActiveCell.Offset(0, 10).Value = txtMf1.Value
ActiveCell.Offset(0, 11).Value = txtMf2.Value
ActiveCell.Offset(0, 12).Value = txtMf3.Value
ActiveCell.Offset(0, 13).Value = txtMf4.Value
ActiveCell.Offset(0, 14).Value = txtCom.Value
MsgBox "Données enregistrées !", vbOKOnly + vbInformation, "Confirmation"
Case Else
MsgBox "Veuillez verifier la référence de base selectionnée !"
End Select '***********fin de la boucle Case******************
Else: MsgBox "Modifier la saisie"
Exit Sub
End If
End Sub
'******************************
'FERMETTURE DE LA FEUILLE EXCEL : BOUTON QUITTER
'******************************
Private Sub btnExitSheet_Click()
Workbooks("essaiGonflement").Close SaveChanges:=True
End Sub
'******************************
'FONCTION RECHERCHE DE LA LIGNE VIDE
'******************************
Private Function ligneVide()
ligneVide = 2
While Not IsEmpty(Cells(ligneVide, 1))
ligneVide = ligneVide + 1
Wend
End FunctionBonjour,
Je ne suis jamais enclin à travailler sur des images...
Mais je peux te dire que : "10 645", "10645" et 10645 sont 3 valeurs différentes.
Si nous ne pensez pas m'aider, je pense qu'il est inutile de répondre à ma demande.
Si vous aviez lu ne serait ce que la moitié de mon code, vous n'écririez pas ce genre de remarque inutile. Mais merci quand même
Bonjour Teddy, bonjour mferrand
Je suis désolée, mais mferrand a raison
Donc, si tu veux que l'on taide, un extrait de ton fichier ne pourra que nous aider à te répondre, le code et les images ne suffisent pas pour voir où est le problème
"10 645", "10645" et 10645 sont 3 valeurs différentes
C'est exact
Donc un fichier, merci
A+
Re
Autres incohérences :
With Me.listeTypeTest
.AddItem "liner"
.AddItem "vmq"
.AddItem "composite"
End With
With Me.listeRefBase
.AddItem "10 645"
.AddItem "10 656"
End WithActiveCell.Offset(0, 1).Value = listTypeTest
ActiveCell.Offset(0, 2).Value = listRefBaseRemplissage liste
copie sur la feuille:
list .... sans e
A voir
Re
Autres incohérences :
With Me.listeTypeTest .AddItem "liner" .AddItem "vmq" .AddItem "composite" End With With Me.listeRefBase .AddItem "10 645" .AddItem "10 656" End WithActiveCell.Offset(0, 1).Value = listTypeTest ActiveCell.Offset(0, 2).Value = listRefBaseRemplissage liste
copie sur la feuille:
list .... sans e
A voir
Super ! c'est effectivement cette incohérence que j'avais pas vu qui faisait beuguer mon code ^^ Tout fonctionne à merveille maintenant, meme si je sais que mon code est loin d'être optimisé :p
Autre question, comment forcer un utilisateur en entrer du texte au lieu d'un nombre par exemple ? Idem pour une date ?
Rebonjour Patty !
J'ajouterais qu'à titre personnel, au vu de certains éléments du code, je m'inquièterais plus si cela ne déclenche pas d'erreur !
Car une erreur oblige à chercher et trouver pour la surmonter, alors que débusquer des anomalies ne produisant pas d'erreur c'est une tout autre histoire...
Bonjour Teddy, bonjour mferrand
Je suis désolée, mais mferrand a raison
Donc, si tu veux que l'on taide, un extrait de ton fichier ne pourra que nous aider à te répondre, le code et les images ne suffisent pas pour voir où est le problème
"10 645", "10645" et 10645 sont 3 valeurs différentes
C'est exact
Donc un fichier, merci
A+
Autant pour moi, j'avais pas très bien compris le message de M. ferrand alors, je ne savais pas qu'il demandait le fichier excel ^^
J'ai résolus mon problème, mais je souhaiterais vraiment savoir qu'elle est la manière la plus efficace de travailler sur une feuille sans utiliser Sheets.Activate ?
Faut-il obligatoirement activer une feuille avant de pouvoir y enregistrer des données ? Ne peut-on pas cacher cette activation pour éviter qu'un utilisateur du formulaire voit les feuilles defiler sous ses yeux ?
Merci
Bonjour à tous
comment forcer un utilisateur en entrer du texte au lieu d'un nombre par exemple ? Idem pour une date ?
Pour le texte , sur l'évènement de ton textbox
Private Sub TextBox2_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If InStr("1234567890", Chr(KeyAscii)) <> 0 Then KeyAscii = 0: Beep
End SubPour la date : peut-être cela ??
Dim Texte as string
Texte=textbox1.text
If IsDate(Texte) = True Then
Texte = CDate(Texte)
textbox1.Text = Texte
Else
MsgBox ("Entrer une date !!" )
End If A voir
Re
j'ai oublié
pour éviter sheets.activate:
With Sheets("tafeuille")
EndWithBonjour,
je souhaiterais vraiment savoir qu'elle est la manière la plus efficace de travailler sur une feuille sans utiliser Sheets.Activate ?
Faut-il obligatoirement activer une feuille avant de pouvoir y enregistrer des données ?
Tu actives une feuille quand l'utilisateur a besoin de la voir. Dans tout autre cas c'est une opération parasite, et qui prend donc du temps pour rien, car VBA n'a pas besoin de voir...
Tu peux travailler avec VBA sur une feuille masquée, sans jamais la rendre visible, à plus forte raison pas besoin de l'activer (sauf utilisation de commandes Excel exigeant que la feuille soit visible... Excel te le fais savoir si tu l'oublies !)
Pour éviter le défilement, c'est à dire la mise à jour de l'affichage lorsqu'une intervention a lieu sur la feuille active, on introduit une ligne de commande dans ce cas :
Application.ScreenUpdating = Falsequi inhibe le rafraîchissement de l'écran (lequel ralentit en outre l'exécution). Pas besoin de ramener la valeur à True (sauf besoin en cours d'exécution), Excel s'en charge dès la macro terminée.
Quand on n'active pas, on désigne la feuille sur laquelle on intervient par son nom, et on évite les répétitions au moyen d'une instruction With... End With :
With Worksheets("10645")
' à l'intérieur de cette instruction, toute expression précédée d'un point
' réfère à la feuille mise sous bloc With, on prend soin de ne pas en omettre...
.Cells(ligne, 1) = ...
End WithOutre l'économie d'écriture qu'apporte cette instruction, elle produit surtout une accélération de l'exécution (feuille plus rapidement accessible). C'est donc particulièrement conseillé...
On peut imbriquer des blocs With, mais avec des objets dépendants les uns des autres (par exemple on crée un sous-bloc With avec .Cells... parce qu'on va définir simultanément plusieurs propriétés de la cellule : Value, Interior.Color, Font...)
On ne mettra pas une autre feuille sous bloc With à l'intérieur de ce bloc, cela risquerait de cafouiller : dans un tel cas, on affecte l'autre feuille à une variable objet Worksheet, et on utilisera la variable (qui permet également une accélération de l'accès).
Cordialement.
Re
j'ai oublié
pour éviter sheets.activate:
With Sheets("tafeuille") EndWith
Merci pour toutes les réponses, seulement, j'ai essayé d'utiliser le code que vous m'avez donné, l'enregistrement ne s'effectue malheureusement pas sur la bonne feuille, voici mon code modifié, surement une erreur dedans :
Dim dateSaisie As Date
Dim ligne As Integer
Dim f10645 As Worksheet
Set f10645 = Sheets("10645")
Dim f10656 As Worksheet
Set f10656 = Sheets("10656")
'S'il y a des erreurs detectées, on annule la saisie
If MsgBox("Etes-vous sûre des données saisies ?", vbYesNo, "Vérification saisies") = vbYes Then
dateSaisie = Format(Date, "dd/mm/yyyy") 'insertion auto de la date de saisie
Select Case (listeRefBase)
'**********gestion de la feuille 10645******************
Case Is = 10645 '***************************************
With f10645 ' A LA PLACE DE SHEETS.ACTIVATE, mais n'enregistre pas sur la bonne feuille 10645
ligne = ligneVide() ' Decallage vers une ligne vide avant insertion de la saisie
Cells(ligne, 1).Value = dateSaisie
Cells(ligne, 2).Value = listeTypeTest.Value
Cells(ligne, 3).Value = listeRefBase.Value
Cells(ligne, 4).Value = txtOfEb.Value
Cells(ligne, 5).Value = txtOfPiece.Value
Cells(ligne, 6).Value = txtDateCoupeEb.Value
Cells(ligne, 7).Value = txtMi1.Value
Cells(ligne, 8).Value = txtMi2.Value
Cells(ligne, 9).Value = txtMi3.Value
Cells(ligne, 10).Value = txtMi4.Value
Cells(ligne, 11).Value = txtMf1.Value
Cells(ligne, 12).Value = txtMf2.Value
Cells(ligne, 13).Value = txtMf3.Value
Cells(ligne, 14).Value = txtMf4.Value
Cells(ligne, 15).Value = txtCom.Value
End WithRE
Cells(ligne, 1).Value = dateSaisie
Cells(ligne, 2).Value = listeTypeTest.Value
Cells(ligne, 3).Value = listeRefBase.Value
Cells(ligne, 4).Value = txtOfEb.Value
Cells(ligne, 5).Value = txtOfPiece.Value
Cells(ligne, 6).Value = txtDateCoupeEb.Value
Cells(ligne, 7).Value = txtMi1.Value
Cells(ligne, 8).Value = txtMi2.Value
Cells(ligne, 9).Value = txtMi3.Value
Cells(ligne, 10).Value = txtMi4.Value
Cells(ligne, 11).Value = txtMf1.Value
Cells(ligne, 12).Value = txtMf2.Value
Cells(ligne, 13).Value = txtMf3.Value
Cells(ligne, 14).Value = txtMf4.Value
Cells(ligne, 15).Value = txtCom.Valueavec with, tu dois faire précéder tous tes CElls d'un point
.Cells etc...
A +
RE
Cells(ligne, 1).Value = dateSaisie Cells(ligne, 2).Value = listeTypeTest.Value Cells(ligne, 3).Value = listeRefBase.Value Cells(ligne, 4).Value = txtOfEb.Value Cells(ligne, 5).Value = txtOfPiece.Value Cells(ligne, 6).Value = txtDateCoupeEb.Value Cells(ligne, 7).Value = txtMi1.Value Cells(ligne, 8).Value = txtMi2.Value Cells(ligne, 9).Value = txtMi3.Value Cells(ligne, 10).Value = txtMi4.Value Cells(ligne, 11).Value = txtMf1.Value Cells(ligne, 12).Value = txtMf2.Value Cells(ligne, 13).Value = txtMf3.Value Cells(ligne, 14).Value = txtMf4.Value Cells(ligne, 15).Value = txtCom.Valueavec with, tu dois faire précéder tous tes CElls d'un point
.Cells etc...
A +
Super !!
Seulement, dernière petite question avant de clore ce sujet,
Je sais maintenant comment interdire la saisie de chiffres dans un textbox, mais comment faire pour interdire la saisie de lettres alphanumériques et caractères speciaux ? Autrement dit autoriser uniquement la saisie de chiffres ?
Merci d'avance
Re
POur la saisie de chiffres uniquement :
Private Sub TextBox6_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If InStr("1234567890", Chr(KeyAscii)) = 0 Then KeyAscii = 0: Beep
End SubA mettre dans l'évènement du textbox concerné
A+