Intialiser un nombre à 2 décimales et l'afficher dans le userform
Dans mon tableau j'ai des colonnes à nombres à 2 décimales. C'est la virgule qui est le séparateur.
La propriété de la colonne du tableau est en "nombre" avec "2 décimales". Les nombres s'affichent donc bien avec 2 décimales et la virgule comme séparateur.
Dans mon userform j'arrive à envoyer ma valeur saisie vers le tableau en nombre avec cette instruction :
Private Sub TextBoxDPCHT€_AfterUpdate()
' Dernier Prix Connu Hors Taxe en €uros
TextBoxDPCHT€ = Replace(TextBoxDPCHT€, ".", ",")
TextBoxDPCHT€ = Format(TextBoxDPCHT€, "##0.00")
End SubJe ne parviens pas à récupérer ces valeurs avec 2 décimales imposées, c'est à dire même quand il y a 1 ou 2 zéro.
Je récupère bien la valeur numérique, ( avec le ".Value" ) mais pas les zéros après la décimale.
Je n'arrive pas à définir le format
"##0.00"dans la ligne pour afficher les zéros.
J'ai ceci pour initialiser la textbox :
Private Sub UserForm_Initialize()
Dim NumLigne As Long
NumLigne = Feuil3.Range("D8")
Me.TextBoxNumLigne = NumLigne ' numéro de ligne du tableau, onglet Code_VBA (Feuil3)
Me.TextBoxDPCHT€.Value = Cells(NumLigne, 4).Value
End Subsvp, comment puis-je faire ?
merci d'avance
Bonjour
En général un userform renvoie du texte donc il faut convertir le contenu en nombre avant de formater car l'habit ne fait pas le moine
Bonjour,
Voici ma proposition. Je ne comprends pas trop où tu veux en venir avec cette succession d'événements.
Donc :
- après MAJ de TextBoxDPCHT€
- TextBoxDPCHT€ sera mis en *,00
- et reporté en D8
- et le format de la cellule sera mis en *,00
à l'initialisation du formulaire :
- TextBoxNumLigne prendra la valeur de D8 (format simple car le code proposé ne semble pas vouloir modifier ce format
- TextBoxDPCHT€ prendra la valeur formatée de D et de la ligne précisée en D8
Attention de bien faire la différence entre le format d'affichage à 2 décimales et la valeur réelle de la cellule à potentiellement plus de 2 décimales ! Je n'ai pas mis de verrou pour interdire une valeur saisie à plus de 2 décimale même si la cellule affichera seulement 2 décimales.
Voici le fichier.
Teste et dis-nous.
et voici ce que je crois que tu voulais faire : un formulaire où tu saisis un numéro de ligne dans TextBoxNumLigne, la valeur de D de cette ligne de Feuil3 est récupérée dans TextBoxDPCHT€, tu peux la modifier dans le formulaire et la reporter sur la feuille avec le bouton OK.
Attention de bien faire la différence entre le format d'affichage à 2 décimales et la valeur réelle de la cellule à potentiellement plus de 2 décimales ! Je n'ai pas mis de verrou pour interdire une valeur saisie à plus de 2 décimale même si la cellule affichera seulement 2 décimales.
Ce que tu voulais ?
Bonjour Alex et bonjour Chris78
Ce soir je suis fourbu, je n'ai pas le courage et le temps de tester vos propositions.
Je vous tiendrai au courant si j'arrive à comprendre comment vous avec fait.
NB : en fait j'aurai du supprimer la ligne de code avec le "Numligne" en "D8" qui vous a mené vers une fausse piste.
En fait, je récupère la valeur de la case de la 4 ème colonne car j'ai une instruction qui récupère le numéro de la ligne sélectionnée qui s'affiche en D8 (qui de fait n'est que l'adresse de la variable) Je ne vais pas développer ça ici pour ne pas vous embrouiller. (je vous expliquerai plus tard, bien sûr)
Me.TextBoxDPCHT€.Value = Cells(NumLigne, 4).ValueEn fait, j'ai mis ".Value" en pensant récupérer la valeur de la cellule en nombre.
Je vais donc adapter vos propositions à mon codage existant sur cette ligne.
Un grand merci à vous deux.
À bientôt
Bon... la curiosité étant plus forte que ma fatigue, j'ai adapté votre solution à mon code.
Me.TextBoxDPCHT€ = Format(ThisWorkbook.Sheets("Honda").Cells(NumLigne, 4), "#,##0.00")La feuille s'appelant "Honda" j'ai eu juste que ça à changer.
Je garde le fichier sous le coude.
Bravo à vous !
Je vous détaillerai autant que possible l'histoire de la case D8. ;)
Je ne sais plus comment on affiche un sujet en "résolu" sur votre forum.
Cool. Bravo.
En fait, j'ai mis ".Value" en pensant récupérer la valeur de la cellule en nombre.
Le .value à la suite d'une référence de cellule ou de nom de zone de texte permet de "lui dire" que tu veux modifier/insérer une valeur quelconque mais ne lui force pas un format. Il pourra appliquer le format qu'il reconnait même si pas toujours celui que souhaite l'utilisateur (ex : numérique en texte, date en texte, ...). Parfois une conversion est faite. En mettant ce .value il sait qu'il doit récupérer la valeur de la cellule et non pas une autre de ses propriétés (son code couleur, son quadrillage, .....). Toutefois si rien n'est précisé derrière la référence de la cellule Excel considère que tu veux .value par défaut donc il n'est pas obligatoire de le préciser (les puristes vont bondir sur leur chaise).
ThisWorkbook.Sheets("Honda").Cells(NumLigne, 4)
Je vois que tu as bien suivi mon exemple de formatage de ligne de code en ajoutant la "hiérarchie" devant la seule référence de cellule que tu mettais avant.
Ce point par contre est plus important que le précédent et permet de résoudre en amont grand nombre de questionnements et futurs soucis.
Dans ton exemple de code tu utilisais Cells(NumLigne, 4).Value et donc le code va chercher la valeur de la cellule Dx de la feuille active. Ce qui t'obligeais à activer à chaque fois une autre feuille si tu souhaitais travailler sur plusieurs feuilles (notamment dans les boucles ou les reports de valeurs d'une feuille à une autre). Je ne dis pas que ça ne marche pas je dis que c'est chronophage (chaque activation de feuille prend du temps d'exécution (oui on parle en fraction de seconde mais sur les grosses volumétries ça compte)).
Tu l'auras compris Sheets("Honda").Cells(NumLigne, 4) permet d'indiquer que tu souhaites intervenir/lire sur la cellule Dx d'une feuille bien précise sans avoir à l'activer avant et donc à perdre ce temps et c'est aussi bien plus facile de relecture de code puisque tu n'est plus obligé de chercher plus haut pour savoir quelle feuille tu vas modifier. Cet ajout n'est pas obligatoire mais très vivement conseillé (tu peux appliquer le même principe différemment avec un with mais je ne vais pas t'embrouiller.
Et pour finir ThisWorkbook.Sheets("Honda").Cells(NumLigne, 4) permet de lui préciser à quel classeur Excel tu fais allusion. Tu peux avoir plusieurs classeur Excel ouverts et ainsi tu lui définit précisément celui que tu veux. Avoue que ce serait bête de modifier la feuille "Honda" d'un autre classeur ouvert. Crois moi cela arrive plus souvent qu'on ne le crois (ex vécu : 2 classeurs ouverts A et B avant lancement du code, le code écrit dans A, j'étais en train de travailler sur B, je voulais lancer le code sur A j'ai donc basculé dans le code directement et lancé son exécution. Bah oui mais comme j'étais en train de travailler sur B bein c'était lui le classeur actif et c'est lui que j'ai modifié via le code même si le module était dans A (euh tu suis ?)))
Depuis je ne manque pas de bien préciser l'arborescence complète Classeur.Feuille.Cellule
ThisWorkbook = classeur dans lequel se trouve le code en cours d'exécution
ActiveWorkbook = classeur actif même si ce n'est pas celui où se trouve le code en cours d'exécution (en VBA tu peux travailler en simultané sur plusieurs classeurs)
Là encore d'autres façons de faire mais pour le moment on en restera là.
Un grand MERCI de tout ce petit cours que je vais m'attacher à mettre en pratique autant que de besoin.
Je vais vous expliquer comment je me sers de cette variable D8 et NumLigne.
Dans ma feuil1 "Honda" j'ai ce code :
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' on déclenche l'ouverture d'un formulaire uniquement depuis la zone de sélection.
' la colonne G, qui est le nom de la pièce est un champ obligatoirement rempli.
' la recherche s'étend de la cellule B12 jusqu'à la colonne N
' jusquà la ligne 3000 qui devrait largement suffire.
If Not Intersect(Target, Range("B12:N3000")) Is Nothing And Range("G" & Target.Row).Value <> Empty Then
' on récupère le numéro de la ligne de la sélection active sur l'onglet Code_VBA (feuille 3), liste numéro en D8
Feuil3.Range("D8").Value = Target.Row
' on déclenche l'ouverture d'un formulaire de modification (frm_Modification)
' ligne suivante à mettre en commentaire pour ne pas déclencher l'ouverture du formulaire de modification lors des ajouts via le formulaire AjouterHonda
ModificationHonda.Show
End If
End SubVous l'aurez compris, quand je clique sur une ligne, le formulaire ModificationHonda s'ouvre automatiquement.
Ce code n'est pas de mon cru, mais il semble correct et fonctionne à merveille. J'ai du le pomper ici sur un autre sujet...
Dans le code VBA de mon formulaire ModificationHonda , pour initialiser j'ai ça :
Private Sub UserForm_Initialize()
Dim NumLigne As Long
' Me.lblMessage = " vous pouvez désormais modifier la fiche de la pièce de CX Honda"
NumLigne = Feuil3.Range("D8")
' MsgBox NumLigne ' ligne de test pour contrôler que le numéro de ligne est bien identifié
Me.TextBoxNumLigne = NumLigne ' numéro de ligne du tableau, onglet Code_VBA (Feuil3)
Me.TextBox_04_96Fr = Cells(NumLigne, 34) 'colonne AH 04-96Fr
' chargement de la valeur numérique de la cellule
Me.TextBoxDPCHT€ = Format(ThisWorkbook.Sheets("Honda").Cells(NumLigne, 4), "#,##0.00") ' colonne D dernier prix connu DPC_HT_€
Me.TextBoxDPCTTC = Format(ThisWorkbook.Sheets("Honda").Cells(NumLigne, 16), "#,##0.00") ' colonne P DPC_TTC
.../...
end subJ'ai essayé plein de manip mais je n'arrive pas à enregistrer la saisie des prix HORS TAXE (sans le €) dans le tableau excel en nombre, il l'enregistre systématiquement en standard.
et puis je voulais, tant qu'à faire, faire que quand je saisi le montant HT que je montant TTC soit calculé en même temps.
dans ma case F8 j'ai le taux 19,60% d'affiché . Le tableau, qui n'a qu'une ligne, s'appelle Tab_TVA il est dans l'onglet Code_VBA.
pourtant je ne dois pas être loin... Ça m'agace...
Private Sub TextBoxHT€Adapable_AfterUpdate()
TextBoxHT€Adapable = Replace(TextBoxHT€Adapable, ".", ",")
TextBoxHT€Adapable = Format(TextBoxHT€Adapable, "#,##0.00")
TextBoxTTC€Adapable = TextBoxHT€Adapable * (ThisWorkbook.Sheets("Code_VBA").Cells(F8) + 1)
End SubJe vous joins mon ficher, je suis sûr que vous allez trouver où je patauge...
Merci de votre aide.
Regarde dans le code du bouton OK de ma réponse de lundi.
Là je ne peux pas ouvrir ton fichier sur mon smartphone.
Le problème ne vient pas des transformations que tu fais à "TextBoxHT€Adapable" mais de la manière dont tu veux accéder à la cellule "F8" de ta feuille "Code_VBA"
TextBoxTTC€Adapable = TextBoxHT€Adapable * (ThisWorkbook.Sheets("Code_VBA").Cells(F8) + 1)
Il ne faut pas confondre la syntaxe de Cells et de Range.
En gros...Range peut faire référence à une seule cellule ou plusieurs cellules tandis que Cells ne fait référence qu'à une seule cellule.
Si tu veux utiliser Cells(ligne, colonne) pour accéder à ta cellule "F8" alors la syntaxe est, au choix :
ThisWorkbook.Sheets("Code_VBA").Cells(8, 6) 'puisque la colonne "F" est la 6ème colonne
'OU
ThisWorkbook.Sheets("Code_VBA").Cells(8, "F")Si tu veux utiliser Range("adresse") pour accéder à ta cellule "F8" alors la syntaxe est :
ThisWorkbook.Sheets("Code_VBA").Range("F8")Mais dans tous les cas ta syntaxe te retournera erreur
ThisWorkbook.Sheets("Code_VBA").Cells(F8)Cells(ligne, colonne) est très pratique en utilisant le numéro de colonne dans une boucle mais par défaut j'utilise Range et pas Cells quand je connais la lettre de ma colonne (histoire de préférence et de lecture du code).
Et donc (le *1 est optionnel mais me permet une conversion sécuritaire d'un nombre ou chiffre typé initialement en texte en type numérique sans changement de valeur puis seulement de travailler avec) :
Private Sub TextBoxHT€Adapable_AfterUpdate()
TextBoxHT€Adapable = Replace(TextBoxHT€Adapable, ".", ",")
TextBoxTTC€Adapable = (TextBoxHT€Adapable * 1) * (ThisWorkbook.Sheets("Code_VBA").Range("F8") + 1)
'ou
'TextBoxTTC€Adapable = (TextBoxHT€Adapable * 1) * (ThisWorkbook.Sheets("Code_VBA").Cells(8, 6) + 1)
'ou
'TextBoxTTC€Adapable = (TextBoxHT€Adapable * 1) * (ThisWorkbook.Sheets("Code_VBA").Cells(8, "F") + 1)
TextBoxHT€Adapable = Format(TextBoxHT€Adapable, "#,##0.00")
TextBoxTTC€Adapable = Format(TextBoxTTC€Adapable, "#,##0.00")
End Sub
Tu verras ça marche mieux
Et pour finir en pinaillant ; je te conseille de toujours définir les arborescences de tes zones dans tes formulaires (Me.TextBoxHT€Adapable et ME.TextBoxTTC€Adapable) sur le même principe que tu l'as fait pour les feuilles.
Teste et dis nous.
Remarque quand même. Pense à coder des sécurités comme je l'ai fait dans mes fichiers précédents car dans ce "simple" code tu vas avoir droit à des erreurs si tu saisis des valeurs non numériques.....
Bonjour Alex
Encore un grand merci pour cette solution. Ça fonctionne bien et ça enregistre correctement en nombre dans le classeur, tout comme je le voulais. Youpi !
Tes explications sont supers et nécessaires pour comprendre et ne pas à avoir revenir dessus. Avec moults exemples sur ce qu'il ne faut pas faire aussi... et pourquoi de la chose. TOP !
Pour info, je réalise des tutos en mécanique, et je ne manque pas aussi d'expliquer pourquoi il ne faut pas faire certaines choses, surtout quand elles apparaissent plus faciles ou moins coûteuses, mais sont néfastes à plus ou moins brèves échéances. ( / fin de l’aparté)
J'avoue ne pas saisir correctement ton avant dernière recommandation :
Et pour finir en pinaillant ; je te conseille de toujours définir les arborescences de tes zones dans tes formulaires (Me.TextBoxHT€Adapable et ME.TextBoxTTC€Adapable) sur le même principe que tu l'as fait pour les feuilles.
C'est bien ce qu'il y avait déjà dans mon fichier, nan ?
Private Sub UserForm_Initialize()
.../...
Me.TextBoxHT€Adapable = Format(ThisWorkbook.Sheets("Honda").Cells(NumLigne, 64), "#,##0.00") ' colonne BL Prix adaptable HT en Euros
Me.TextBoxTTC€Adapable = Format(ThisWorkbook.Sheets("Honda").Cells(NumLigne, 65), "#,##0.00") ' colonne BM Prix adaptable TTC en Euros
end subFaudrait il que je fasse précéder toutes les lignes "
Cells(NumLigne, xx)par
ThisWorkbook.Sheets("Honda").de la section (je ne sais pas si ça s'appelle comme ça) "Initialize" ?
Ou bien je dois le faire ailleurs ? Dans la section "Sauvegarde " ? ??
Pour ta dernière recommandation :
Remarque quand même. Pense à coder des sécurités comme je l'ai fait dans mes fichiers précédents car dans ce "simple" code tu vas avoir droit à des erreurs si tu saisis des valeurs non numériques.....
Je pense que tu parles de la condition
If IsNumericet le contrôle qui suit / vidage de la cellule si ce n'est pas le cas.
D'ailleurs, je ne saisi pas bien pourquoi il y a un " * 1" à la fin de cette ligne.
Je comprends bien qu'il s'agit de multiplier par 1 la valeur, ce qui ne la change pas, mais pourquoi le faire ? Il doit bien y avoir une raison qui m'échappe...
J'avais bien idée de devoir mettre cette condition, mais plus tard (quand ça marche !), et comme on en est là, je vais le faire.
Bonjour Alex
Que penses tu de ce bout de code ?
Je n'ai fais que celle là pour l'instant, je dois faire l'autre et tout le formulaire d'ajout de référence au classeur.
Je te joins le fichier aux fins de tests et de contrôle de ton coté.
à mes tests, ça semble être correct (grâce à toi ! )
Private Sub TextBoxDPCHT€_AfterUpdate()
' Dernier Prix Connu Hors Taxe en €uros
Dim valeur_DPCHT€ As String
valeur_DPCHT€ = Me.TextBoxDPCHT€
If valeur_DPCHT€ <> "" Then
'remplacer le . éventuel
valeur_DPCHT€ = Replace(valeur_DPCHT€, ".", ",")
'vérifier que la saisie est un nombre
If IsNumeric(valeur_DPCHT€) Then
'formater TextBoxDPCHT€
TextBoxDPCHT€ = Format(Me.TextBoxDPCHT€, "#,##0.00")
' calcule le prix TTC et l'affiche dans la textbox TTC
TextBoxDPCTTC = (TextBoxDPCHT€ * 1) * (ThisWorkbook.Sheets("Code_VBA").Range("F8") + 1)
' formater TextBoxDPCTT€
TextBoxDPCTTC = Format(TextBoxDPCTTC, "#,##0.00")
Else
'vider la valeur
valeur_DPCHT€ = ""
' vider la textbox et afficher un message d'alerte
TextBoxDPCHT€ = ""
MsgBox ("il y a un caractère qui n'est pas un chiffre ou un séparateur de décimale." & Chr(10) & vbCrLf & _
"Vous ne devez saisir QUE des CHIFFRES, un POINT ou une VIRGULE." & Chr(10) & vbCrLf & _
"En cas d'erreur de saisie, la valeur enregistrée précédemment dans le classeur sera conservée."), vbExclamation, ". FORMAT DE PRIX INCORRECT"
End If
End If
End SubBonjour à tous,
J'ai donc complété mon code VBA et ça fonctionne plutôt bien.
Le sujet peut être marqué comme "RÉSOLU" mais je n'ai pas trouvé comment faire. :(
Un grand MERCI à Alex020181 qui m'a bien aidé et aussi appris comment faire.
Oui c'est ça. Actuellement si tu saisis "tata toto titi" ou "100.50.50" ... (donc du texte) avec le code actuel sans contrôle tu auras un bug puisqu'il ne va pas savoir multiplier ce texte par 19.6% (entre autre). Donc dis lui quoi faire si l'utilisateur se plante et saisis n'importe quoi.
Au lieu de vider la cellule (ou en même temps) vide ton champs TTC.
Quand tu récupères une valeur à partir d'une textbox elle est reconnu comme du texte (même si l'humain est capable de la comprendre comme un chiffre). Excel ne sait pas toujours faire des calculs à partir de nombres reconnus comme texte. En multipliant par 1 je transforme sa "reconnaissance" de texte vers une variable nombre sans changer sa valeur. Je peux ainsi faire ce que je veux avec cette variable reconnue comme un nombre.
Je vais regarder ton code modifié mais pas maintenant. Je pars au sport.
Bonjour Alex
Que penses tu de ce bout de code ?
Bien mieux (bravo) mais .....
Il te manque au moins 1 contrôle.
et le dernier prix HT me parait réagir quelque peu bizarrement non ?
et regarde comment sont retournés tes prix.
Ils sont reconnus comme du texte (tu n'as pas fais la conversion (*1 ou autre méthode)). Par défaut Excel aligne ce qu'il reconnait comme texte à gauche et comme numérique à droite. En plus il te précise via le triangle vert dans la cellule.
Autre point : si tu fermes ton formulaire et que tu veux le rouvrir sur la même pièce alors tu es obligé de sélectionner une autre ligne (ou une autre cellule de la même ligne) avant de retourner à la ligne voulue. Tu ne peux pas ré afficher le formulaire en cliquant de nouveau sur la même cellule.
Bon je critique mais je vois aussi que par rapport à ta première version il y a du mieux. Bravo.
Tu as 2h pour corriger ;)
2 exemples concrets des conséquences de tes mauvais formats de données :
les filtres ne s'appliqueront pas comme tu le voudraient (ici j'applique un filtre pour rechercher les valeurs <200 et tu vois que tes 2 valeurs reconnues texte "174,50" et "192,50" ne sont pas reprises dans les lignes filtrées)
certaines fonctions dans tes formules ne te donneront pas le résultat que tu souhaites (ici je cherche la somme d'une zone de cellules comprenant tes 2 valeurs reconnues texte et une valeur reconnue numérique et tu vois que seule la valeur reconnue numérique est prise en compte) --> ici bien sûr cette formule est pour l'exemple. Je me doute qu'avoir cette somme dans cette cellule ne t'est d'aucune utilité.
Autre conseil. Je ne complèterais pas les montants TTC par les données du formulaire si j'étais toi. Ces valeurs seraient alors statiques. Le jour ou ton taux de TVA change tu fais quoi ? Tu seras obligé de reprendre chacune de tes lignes pour corriger manuellement via ton formulaire. Tu es courageux. Je te conseille plutôt d'insérer une formule dans ton tableau pour calculer le TTC via le HT et le taux de TVA ainsi si tu modifies ton HT ou le taux de TVA alors ton TTC sera automatiquement mis à jour sans avoir à faire de corrections manuelles. Moi je dis ça je dis rien.

