XL 2010 Vlookup erreur

harry226h

XLDnaute Junior
Bonjour a tous
Je viens sollliciter votre aide sur un userform.
En fait j'ai un textbox qui puise des données dans un tableau en fonction de la box ''nom''.
Lorsque la valeur a rechercher est un nombre, la macro plante et affiche une erreur 1004. Mais si la valeur est une lettre elle s'execute normalement.
A noter egalement que lorsque la valeur recherchée n'existe pas la macro plante.
Comment puis je resoudre ces problemes?
Merci d'avance
 

Pièces jointes

  • TEST.xls
    42 KB · Affichages: 21

Dranreb

XLDnaute Barbatruc
Bonjour.
En remplaçant la TextBox nommée Texbox1 par une ComboBox nommée CBxNom :
VB:
Option Explicit
Private RngDon As Range, TVL(), LCou
Private Sub UserForm_Initialize()
   Dim T(), L&
   Set RngDon = Intersect(Feuil1.[A2:D20], Feuil1.UsedRange)
   T = RngDon.Columns(1).Value
   For L = 1 To UBound(T, 1)
      If VarType(T(L, 1)) = vbDouble Then T(L, 1) = CStr(T(L, 1))
      Next L
   CBxNom.List = T
   End Sub
Private Sub CBxNom_Change()
   If CBxNom.MatchFound Then
      LCou = CBxNom.ListIndex + 1
      TVL = RngDon.Rows(LCou).Value
   Else
      LCou = 0
      ReDim TVL(1 To 1, 1 To RngDon.Columns.Count)
      End If
   GarnirAutresContrôles
   End Sub
Private Sub GarnirAutresContrôles()
   TextBox2.Text = TVL(1, 2)
   TextBox4.Text = TVL(1, 3)
   End Sub
 

herve62

XLDnaute Barbatruc
Supporter XLD
Bonjour
L'erreur 1004 avec Vlookup est connue : il suffit de mettre un "on error resume next" au debut
par contre je cherche pourquoi on ne peut pas mixer nombre et texte ?
A 1ere vue c'est à cause du type : texte=variant et nombre = long
et on ne peut pas faire un "double" Dim
j'ai testé que des nombres avec Long > Ok , que du texte avec Variant > Ok
Si quelqu'un sait quoi !!!
 

Dranreb

XLDnaute Barbatruc
Non: vous avez changé le nom de l'objet interne encapsulé générateur d'évènements.
Il s'appelle toujours UserForm pour tous les UserForm construits autour de lui, quel que soit leurs noms. UserForm1 n'existe pas comme objet générateur d'évènements pour UserForm1. La UserForm1_Initialize n'est donc pas exécutée puisqu'elle en devient une procédure Private ordinaire qu'il faudrait invoquer pour qu'elle s'exécute.
C'est tout comme pour un objet Worksheet: le noyau c'est toujours Worksheet quel que soit le nom de l'objet Worksheet particulier ou celui de la feuille Excel dont il assume la représentation dans VBA.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bien. Je vous suggère de poursuivre cette discussion, parce que de mon coté je suis allé plus loin, au cas où ce serait bien la suite logique de l'évolution de ce classeur. Mais je ne vais pas joindre ce que j'ai fait, ni d'ailleurs le sauvegarder si vous ne me le demandez pas …
 

Dranreb

XLDnaute Barbatruc
j'aurais préféré que vous demandiez vous même des fonctionnalités supplémentaires mais enfin bon …
Le système d'accès aux données ne change pas, pas plus que les variables globales TVL() et LCou, et resterait le même que celui qui aurait été employé pour créer une nouvelle ligne ou en modifier une existante. La RngDon, en revanche à trouvé son logement ailleurs. Elle est devenue Cl.PlgTablo
 

Pièces jointes

  • CBxLiéesHarry226h.xlsm
    77.6 KB · Affichages: 13

harry226h

XLDnaute Junior
Merci à vous pour ces fonctionnalités.
J'aimerais également ajouter de nouvelles données dans la tableau.
En cliquant sur le bouton enregistrer une nouvelle ligne devrai être ajouter. Les données proviendrons de l'userfom, la valeur de chaque textbox sera copier dans la cellule correspondante et les textbox vidés.
Tous les textbox devons être impérativement remplis, sinon colorier la cellule vide.
Titre et ville = liste suivant colonnes correspondantes.

Merci d’avance
 

Pièces jointes

  • TEST ENREGIST.xls
    45.5 KB · Affichages: 11

Dranreb

XLDnaute Barbatruc
Le code de votre classeur serait à peu près :
VB:
Option Explicit
Private RngDon As Range, TVL(), LCou
Private Sub UserForm_Initialize()
   Dim T(), L&
   Set RngDon = Intersect(Feuil1.[A2:D20], Feuil1.UsedRange)
   Actualiser
   End Sub
Private Sub Actualiser()
   T = RngDon.Columns(1).Value
   For L = 1 To UBound(T, 1)
      If VarType(T(L, 1)) = vbDouble Then T(L, 1) = CStr(T(L, 1))
      Next L
   CBxNom.List = T
   End Sub
Private Sub CBxNom_Change()
   If CBxNom.MatchFound Then
      LCou = CBxNom.ListIndex + 1
      TVL = RngDon.Rows(LCou).Value
   Else
      LCou = 0
      ReDim TVL(1 To 1, 1 To RngDon.Columns.Count)
      End If
   GarnirAutresContrôles
   End Sub
Private Sub GarnirAutresContrôles()
   TextBox2.Text = TVL(1, 2)
   TextBox4.Text = TVL(1, 3)
   End Sub
Private Sub CommandButton1_Click()
   TVL(1, 2) = TextBox2.Text
   TVL(1, 3) = TextBox4.Text
   If LCou = 0 Then
      TVL(1, 1) = CBxNom.Text
      LCou = RngDon.Rows.Count
      RngDon.Rows(LCou).Copy
      RngDon.Rows(LCou).Insert
      LCou = LCou + 1
      Actualiser
   Else
      TVL(1, 1) = CBxNom.Text
      RngDon.Rows(LCou).Value = TVL
      End If
   End Sub
Mais ce serait un peu différent si la plage avait fait l'objet d'une mise sous forme de tableau Excel.
Remarquez la procédure Actualiser, vu qu'on est obliger de refaire la liste de la ComboBox.
Naturellement si on utilise un objet ComboBoxLiées nommé CL, on untilisera partout CL.PlgTablo au lieu de RngDon.
L'objet est muni d'une méthode pour Actualiser qui s'occupe de tout.
Ne pas confondre les ComboBox, seul lui étant spécifiés dans les CL.Add, servant à rechercher dans la base avec ceux servant à choisir des valeurs prédéfinies prise d'un table
Donnez des noms mnémoniques aux contrôles commençant par un trigramme pris de la colonne Trigram de cette table :
upload_2018-12-14_19-45-54.png
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Alors le principe c'est :
VB:
Private Sub CommandButton1_Click()
   TVL(1, 2) = TextBox2.Text
   TVL(1, 3) = TextBox4.Text
   If LCou = 0 Then
      TVL(1, 1) = CBxNom.Text
      LOt.ListRows.Add.Range.Value = TVL
      Actualiser
   Else
      LOt.ListRows(LCou).Range.Value = TVL
      End If
   End Sub
Avec LOt une variable globale As ListObject convenablement initialisée dans l'UserForm_Initialize.
Mais si on utilise un ComboBoxLiées, pas besoin: il a une propriété Lignes initialisée comme étant la collection ListRows du ListObject qu'il à lui même détecté lors de l'appel à sa méthode Plage. On peut donc faire des CL.Lignes.Add.Range et CL.Lignes(LCou).Range.Value, tout ça …
Il a aussi une méthode pour verser, en création, les valeurs des ComboBox dont il a la charge dans les bonnes colonnes de la première ou seule ligne d'un tableau VBA:
CL.ValeursVers TVL
 
Dernière édition:

harry226h

XLDnaute Junior
J'ai presque achever le fichier, je bloque sur une derniere tache.
Suivant le fichier joint, je souhaiterais que la box ''feuille'' ai pour source la colonne A de la feuille ''PARAM'', la box ''nom'' ai pour source la colonne B.
En cliquant sur resume une recherche est faite dans l'onglet identique a la valeur de la box ''feuille'' avec pour critere la valeur de la box ''Nom''.
Et le resultat escompté est :
Par exemple pour ''A'' rechercher dans la feuille ''TAV'', les dates pour lesquelles il y a une valeur. Ensuite afficher ces dates, les valeur trouvées ainsi que les commentaires, dans la feuille resume aux colonnes correspondantes.
Merci d'avance
 

Pièces jointes

  • TEST RESUME.xlsm
    37.3 KB · Affichages: 11

Discussions similaires

Statistiques des forums

Discussions
312 184
Messages
2 086 006
Membres
103 088
dernier inscrit
Psodam