Modifier valeur cellule depuis une textbox
Hello à tous,
Je suis bloqué sur un petit truc tout bête. Depuis un UserForm je récupère le numéro d'un article.
Ce numéro d'article annonce un article dans la TextBox2.
Ce que je souhaite: Qu'un utilisateur puisse modifier l'article depuis l'UserForm et que cette modification vienne sur la cellule correspondante dans le fichier.
Private Sub UserForm_Initialize()
'Je reprends les valeurs de la feuille 1:
TextBox1 = Sheets("Feuil1").Range("A2")
Dim LaRecherche As String
LaRecherche = Application.WorksheetFunction.VLookup(TextBox1, Sheets("Feuil1").Range("ARTICLES"), 2, False)
TextBox2.Value = LaRecherche
End SubEx: Je change "Pommes" par "Pommes Golden", je clic sur valider et ça va donc modifier la valeur de la cellule B2.
En fait, je souhaite que la colonne B (TextBox2) soit modifiée en fonction de la valeur de la colonne A (TextBox1).
Info: Le fichier remis est une version très allégée du fichier que j'utilise (qui pèse plus de 50 mégas car il y a des photos et références). Mais au moins nous avons un petit fichier :D
Info 2: pas de bouton pour ouvrir l'UserForm car "petit Soucis" avec mon code :(
Bonjour PatPatrouille,
Voir fichier joint. J'ai nommé la colonne des n° d'article "REF_ARTICLES" et ajouté un bouton sur la feuille pour ouvrir le formulaire.
Cdlt,
Cylfo
Bonjour Cylfo,
Tout premièrement, merci pour le retour si rapide. C'est parfait! J'ai juste modifié un paramètre car la référence modifiée ne pouvait plus être modifiée par la suite (les modifs n'étaient pas pris en compte).
J'ai tout simplement fait une remise à 0 des paramètres du formulaire puis une fermeture après validation et cela rend fonctionnelle les modifications suivantes.
Private Sub btnValider_Click()
Dim vLigRef As Variant
With Me.cbRefArticle
' S'assurer qu'une référence a été sélectionnée
If .ListIndex <> -1 Then
' Qu'une modification a été apportée
If UCase(Me.tbArticle.Value) <> UCase(.List(.ListIndex, 1)) Then
' Recherche le n° de la ligne concernée par la référence
vLigRef = Application.Match(CLng(.Value), Sheets("Feuil1").Range("REF_ARTICLES"), 0)
If Not IsError(vLigRef) Then
Sheets("Feuil1").Range("ARTICLES").Cells(vLigRef, 2).Value = Me.tbArticle.Value
vLigRef = "" '<== MES MODIFICATIONS
tbArticle = "" '<== MES MODIFICATIONS
Me.Hide '<== MES MODIFICATIONS
End If
Else
MsgBox "AUCUNE MODIFICATION N'A ÉTÉ APPORTÉE!", vbExclamation, "Modification abandonnée"
End If
End If
End With
End SubAvant de finaliser, quelle différence entre Unload Me et Me.Hide?
Merci.
Re,
je reviens vers toi car j'essaie d'adapter ton code à mon besoin avec quelques difficultés. Dans mon fichier d'origine, quand je clic pour l'ouverture du UserForm, il va automatiquement me détecter sur quel article je suis situé avec:
Private Sub UserForm_Initialize()
'Je reprends les valeurs de la feuille HOME:
UF_IQ_TBINFOS.SetFocus
TB_NUMBER = Sheets("DATA").Range("C7")
TB_CT1 = Sheets("HOME").Range("B7")
TB_CT2 = Sheets("HOME").Range("D7")
TB_CT3 = Sheets("HOME").Range("F7")
Dim LaRecherche As String
LaRecherche = Application.WorksheetFunction.VLookup(TB_NUMBER, Sheets("INFO_QUALITE").Range("INFOQUALITE"), 2, False)
UF_IQ_TBINFOS.Value = LaRechercheDu fait que je récupère les infos via un recherchev dans VBA :
VLookup(TB_NUMBER, Sheets("INFO_QUALITE").Range("INFOQUALITE"), 2, False)mon formulaire m'affiche correctement l'article (UF_IQ_TBINFOS) correspondant à mon numéro d'article (TB_NUMBER) grace à une table de données située sur la feuille INFO_QUALITE, table "INFOQUALITE".
C'est à ce moment-là que je souhaiterais apporter les modifications dans UF_IQ_TBINFOS dans la table INFOQUALITE.
Il faudrait que ce que je modifie dans UF_IQ_TBINFOS soit alors appliquer dans la feuille INFO_QUALITE sur la ligne correspondante au TB_NUMBER.
J'essaie donc d'adapter le code que tu m'as remis sans vraiment y arriver.
Voici ce que j'ai fait (qui ne bug pas pourtant mais qui ne fait rien non plus):
Private Sub UserForm_Initialize()
'Je reprends les valeurs de la feuille HOME:
UF_IQ_TBINFOS.SetFocus
TB_NUMBER = Sheets("DATA").Range("C7")
TB_CT1 = Sheets("HOME").Range("B7")
TB_CT2 = Sheets("HOME").Range("D7")
TB_CT3 = Sheets("HOME").Range("F7")
Dim LaRecherche As String
LaRecherche = Application.WorksheetFunction.VLookup(TB_NUMBER, Sheets("INFO_QUALITE").Range("INFOQUALITE"), 2, False)
UF_IQ_TBINFOS.Value = LaRecherche
End Sub
Private Sub UF_IQ_VALIDER_Click()
Dim vLigRef As Variant
With Me.TB_NUMBER
' S'assurer qu'une référence a été sélectionnée
If UCase(Me.UF_IQ_TBINFOS.Value) <> UCase(Me.TB_NUMBER) Then
' Recherche le n° de la ligne concernée par la référence
vLigRef = Application.Match(CLng(.Value), Sheets("INFO_QUALITE").Range("A6:A103"), 0)
If Not IsError(vLigRef) Then
Sheets("INFO_QUALITE").Range("B6:B103").Cells(vLigRef, 2).Value = Me.TB_NUMBER.Value
vLigRef = ""
TB_NUMBER = ""
Me.Hide
End If
Else
MsgBox "AUCUNE MODIFICATION N'A ÉTÉ APPORTÉE!", vbExclamation, "Modification abandonnée"
End If
End With
End SubRe,
Sans fichier, je ne suis pas certain de te répondre correctement mais je tente quand même une réponse
Si j'ai bien compris, TB_NUMBER est un textBox qui contient la référence de l'article et UF_IQ_TBINFOS, un autre TextBox qui contient la dénomination de l'article et c'est cette dénomination que tu veux pouvoir changer et répercuter dans la table INFOQUALITE.
Si c'est bien cela, dans le code, il y a des incohérences :
- Dans la procédure UF_IQ_VALIDER_Click
If UCase(Me.UF_IQ_TBINFOS.Value) <> UCase(Me.TB_NUMBER) Then- Attention tu compares la dénomination à la référence (donc normalement il y aura toujours une différence). Il faudrait dans la procédure "UserForm_Initialize" que tu stockes la dénomination initiale de l'article dans une variable déclarée au niveau module (Là je l'ai nommée cNomArticleInit) et alimentée par la variable LaRecherche juste après la ligne
UF_IQ_TBINFOS.Value = LaRecherchecNomArticleInit = UCase(LaRecherche)
- Le test correct serait donc
If UCase(Me.UF_IQ_TBINFOS.Value) <> cNomArticleInit Then
- Attention tu compares la dénomination à la référence (donc normalement il y aura toujours une différence). Il faudrait dans la procédure "UserForm_Initialize" que tu stockes la dénomination initiale de l'article dans une variable déclarée au niveau module (Là je l'ai nommée cNomArticleInit) et alimentée par la variable LaRecherche juste après la ligne
- Il ne se passe rien car dans
vLigRef = Application.Match(CLng(.Value), Sheets("INFO_QUALITE").Range("A6:A103"), 0)la fonction Match doit renvoyer une valeur d'erreur. La référence de l'article est-elle numérique ?- si non, il faut remplacer
CLng(.Value)par simplement.Value - si elle est numérique, sans fichier (anonymisé) je ne sais pas ...
- si non, il faut remplacer
- Dans la ligne
Sheets("INFO_QUALITE").Range("B6:B103").Cells(vLigRef, 2).Value = Me.TB_NUMBER.Valuetu affectes la référence de l'article à la dénomination ...- Il me semble qu'il faudrait plutôt
Sheets("INFO_QUALITE").Range("B6:B103").Cells(vLigRef, 2).Value = Me.UF_IQ_TBINFOS.Value
- Il me semble qu'il faudrait plutôt
Je crois comprendre que la table INFOQUALITE a comme étendue la plage "A6:B103", si c'est bien cela, il vaudrait mieux que tu nommes les plages A6:A103 et B6:B103 ce qui t'éviterait d'avoir à modifier le code si la plage évolue OU encore mieux que tu utilises un tableau structuré ...
Cdlt,
Cylfo
Bonsoir Cylfo,
Déjà je trouve très bien ta réponse sans fichier. Un grand merci (si je pouvais, je te remercierais avec une p'tite bière!).
Quant au code, je pense que demain je vais tout de même faire un fichier que je pourrais remettre ici, cela sera certainement plus simple et plus parlant.
Pour tes réponses:
La référence est-elle numérique: OUI
Plage A6:B103: C'est bien cela. Cette plage se nomme "INFOQUALITE" et c'est d'ailleurs là que vLookup prend forme
LaRecherche = Application.WorksheetFunction.VLookup(TB_NUMBER, Sheets("INFO_QUALITE").Range("INFOQUALITE"), 2, False)
UF_IQ_TBINFOS.Value = LaRechercheEn effet, quand j'ouvre le formulaire, il prend la valeur de la TextBox TB_NUMBER (le numéro d'article) et va dans la table le rechercher entre A6 et A103 pour retourner la désignation correspondante située entre B6 et B103. Et c'est bien cette désignation que je souhaite pouvoir modifier.
Voilà pourquoi je ne peux donc pas renommer les plages comme tu l'indiques sinon cela annulerait le vLookup au démarrage de l'UserForm.
Mais si je mets
cNomArticleInit = UCase(LaRecherche)
Comme tu l'indiques sous
UF_IQ_TBINFOS.Value = LaRecherche
je doute que cela puisse marcher car UF_IQ_TBINFOS.Value = La Recherche se trouve dans le UserForm Initialize alors que cNomArticleInit sera utilisé au moment de cliquer sur le bouton valider.
Bref, je vais vraiment faire un petit fichier demain qui me permettra d'être plus précis dans mes demandes mais à ce stade je dois déjà te remercier énormément pour ton retour.
Bonne soirée.
Re,
Ok, j'attends le fichier. Idéalement il faut que ce soit le fichier réel MAIS dans lequel les données sont anonymisées / banalisées sinon si tu refabriques un fichier il y aura toujours le risque que les différences soient sources de complication pour reporter les modifications.
Concernant la déclaration de la variable cNomArticleInit, il faut qu'elle soit déclarée en tête de module donc en dehors de toute procédure pour que sa portée soit globale au module lié au UserForm. Exemple ci-dessous :
Option Explicit ' si tu utilises cette option
Dim cNomArticleInit as String
Private Sub UserForm_Initialize()
' le code de la procédure
End Sub
Private Sub UF_IQ_VALIDER_Click()
' le code de la procédure
End SubCdlt,
Cylfo
Bonjour Cylfo, j'espère que tu vas bien juste avant ce week-end :D
Voici le petit fichier qui reprend bien l'aspect du réel mais en bien plus petite taille.
Je continue de mon côté à modifier ton code car le but est aussi d'apprendre de mes erreurs. Je vais tenter de travailler dessus ce week-end, sinon lundi
Effectivement tu verras que le fichier n'a pas grand chose mais je t'avais dit que je mettrai à dispo un fichier pour pourvoir avancer dessus.
Bien à toi.
Bon week-end.
P.
Re,
En retour, le fichier modifié (j'ai mis des commentaires dans le code).
Bon week-end à toi,
Cdlt,
Cylfo
Bonsoir Cylfo,
J'espère que tu as passé un très bon week-end. Je tiens à te remercier pour la solution. Honnêtement, quand j'ai vu que cela fonctionnait j'ai essayé de le faire par moi-même et après je voulais comparer ton retour mais ça ne marchait pas. Un peu frustré tout de même j'ai été comparé ta solution et la mienne. Effectivement il y avait quelques détails à changer mais j'étais réellement sur la bonne voie.
Je fais donc le transfert vers mon "gros" fichier et ça ne marche pas... J'ai analysé chaque lignes de ton code et pourtant il fonctionne bien. Maintenant je sais d'où viens mon soucis et c'est bête, vraiment. Sur le fichier original, le n° d'article n'est pas un texte à l'état pur mais une formule qui va concatener ce code article (1 pour la famille, 2 pour le conditionnement et 1 pour la matière). Recherche V ne prends pas en compte les formules et me retourne un #N/A. Si je tape 111 ça fonctionne, si je garde ma formule, ça bug. J'ai donc essayé de passer le résultat en texte mais sans succès.
Je teste donc diverses options comme remplacer la formule RECHERCHEV par
=INDEX(TEXTE(LST_ARTICLES;0);EQUIV(B3;INFOQUALITE;0);2)Je ne parviens malheureusement toujours pas.
Est-ce que tu as une autre formule magique pour que cela fonctionne?
Dans l'attente de ton retour, je continue de tester diverses options. Si j'en trouve une qui fonctionne, je te réponds par ici.
Encore une fois, merci.
Bonjour PatPatrouille,
Les fonctions prennent en compte la valeur de la cellule que celle-ci soit directement saisie ou le résultat d'une formule. Donc le souci n'est pas lié à la formule mais au fait que d'un côté tu as du texte et de l'autre du numérique.
Voit fichier ci-joint, formule du RECHERCHEV et code modifiés. Dans le code, j'ai laissé la ligne originale en commentaire suivie de la ligne modifiée.
Cdlt,
Cylfo
Bonjour Cylfo,
un grand merci pour toute ton aide. J'ai finalement compris d'où venait le soucis et tout fonctionne à présent. Comme je t'ai dit, si je pouvais te remercier autour d'une petite bière, cela me ferait bien plaisir.
Bien à toi.
Patrick.