XL 2019 Combobox à partir d'un fichier fermé

gui64600

XLDnaute Nouveau
Bonjour,
Jai un fichier source.xlsm qui en colonne A de la feuille "source" contient des noms.
Je voudrais dans un autre fichier résultat.xlsm créer une combobox me permettant une saisie semi-automatique des noms du fichier source en cellule C2

Le fichier A est fermé.

Merci de votre aide
 

Dudu2

XLDnaute Barbatruc
Bonjour,
Je récupère des codes divers trouvés ici ou là pour faire une fonction que fait ça avec du SQL, car je n'ai trouvé que ça.
La difficulté avec cette requête "SQL SELECT * FROM" c'est qu'elle retourne un peu ce qu'elle veut et considère la 1ère ligne comme le nom des champs qu'elle ne rend pas et qu'il faut donc récupérer séparément et que si il n'y a que la 1ère ligne on ne récupère rien.
Je vais essayer de couvrir tous les cas et je posterai le fichier.

Sinon, si tu n'as pas trop de noms en colonne A de ton classeur fermé tu peux toujours tenter de récupérer cellule par cellule avec ce code:
VB:
Sub TestExtraireValeur()
    MsgBox ExtraireValeur("H:\Téléchargements", "Classeur2.xlsx", "Feuil1", "A3")
End Sub

Function ExtraireValeur(ByVal Dossier As String, ByVal Fichier As String, ByVal Feuille As String, ByVal Cellule As String) As Variant
    Dim Argument As String
   
    If Right(Dossier, 1) <> "\" Then Dossier = Dossier & "\"
    Fichier = Replace(Fichier, "'", "''")
    Argument = "'" & Dossier & "[" & Fichier & "]" & Feuille & "'!" & Range(Cellule).Address(, , xlR1C1)
    'MsgBox Argument
    ExtraireValeur = ExecuteExcel4Macro(Argument)
End Function
 

patricktoulon

XLDnaute Barbatruc
re
a oui j'oubliais si ta liste deroulante est une liste de validation
VB:
 tbl = resADO([A1:C20], fichier, nomfeuille)
   '' ActiveSheet.ComboBox1.List = tbl
    With ActiveSheet.Range("A2").Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(Application.Transpose(tbl), ",")
    End With
et pour repondre a @Dudu2
l'argument HDR ="no" prend la première occurrence comme la première et non un nom de champ
et pour les différence de données dans une meme colonnes qui peuvent générer des erreurs imex=1 permet de récupérer tout au format text
 

patricktoulon

XLDnaute Barbatruc
j'avais oublié aussi que ado et son .execute n'aime pas les lignes vides et génère une erreur
donc si il y en a
il faut donc passer par la lecture du recordset
seul petit bémol cette fois ci même si ado et en latebinding(createobject) dans le code ci dessous il faut activer quand même la librairie "microsoft Activx Data object 2.0 library"
dans l'exemple ci dessous on bouclera donc sur tout le recorset (il y en a autant que de ligne vides dans la colonnes source

allez c'est parti on récupere la colonne "A" dans base.xlsx sans les vides
hdr
est piloté par l'appel dans cet exemple
VB:
Sub test_récup_plage()
    Dim fichier$, Tbl
    fichier = ThisWorkbook.Path & "\BASE.xlsx"    'à adapter
    Tbl = GetcolumnValueOnClosedWbookskeepblank(fichier, "A1:A20", "Feuil1", False)
    'Sheets("Feuil2").[A1].Resize(UBound(Tbl)) = Tbl
      With ActiveSheet.ComboBox1: .Clear: .List = Tbl: End With
End Sub

Function GetcolumnValueOnClosedWbookskeepblank(fichier As String, RnG As String, Feuille As string, Optional headerTable As Boolean = False)
    Dim AdConn As Object, AdoComand As Object, HDR$, RsT As Object, RsTLigne&, RsTCol&, v$, Arr()
    Set AdConn = CreateObject("ADODB.Connection")
    Set AdoComand = CreateObject("ADODB.Command")
    Set RsT = CreateObject("ADODB.RecordSet")
    HDR = Array("No", "Yes")(Abs(headerTable))
    AdConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & fichier & ";Extended Properties=""Excel 12.0;HDR=" & HDR & ";IMEX=1"";"
    AdoComand.ActiveConnection = AdConn
    AdoComand.CommandText = "SELECT * from `" & Feuille & "$" & RnG & "`"
    RsT.Open AdoComand, , adOpenKeyset  ', adLockOptimistic
        RsT.MoveFirst
    Do While Not RsT.EOF
        For RsTLigne = 1 To RsT.RecordCount  'lignes
            If Not IsNull(RsT.Fields(0).Value) Then A = A + 1: ReDim Preserve Arr(1 To A): Arr(A) = RsT.Fields(0).Value
            RsT.MoveNext
        Next
    Loop
    AdConn.Close: Set RsT = Nothing: Set AdoComand = Nothing: Set AdConn = Nothing
    GetcolumnValueOnClosedWbookskeepblank = Application.Transpose(Arr)
End Function
avec ça on englobe pas mal d'erreurs qui sont souvent incompréhensible avec ADO
enjoy :)
 

Dudu2

XLDnaute Barbatruc
Ton code est vraiment très expert !
A force de mélanger les sources j'ai pu faire une fonction de récupération:
- Soit d'une plage
- Soit d'une feuille
Il y a des tas de façons proposées ici et là de faire la connexion et je n'y comprends pas grand chose. J'ai pris ta méthode avec le HDR=NO qui a réglé mon problème de 1ère ligne.
Dans le tableau Variant en retour, j'ai gardé le type des valeurs en n'utilisant pas imex=1.

Ça marche très bien pour la récupération d'une plage.
En récupération de la feuille ça marche aussi sauf quand il y a des lignes vides en haut et/ou des colonnes vides à gauches car elles ne sont pas récupérées par SQL. Faut faire avec !

Un fichier juste à titre d'essai.

Edit: Modifié le 06/12/2020 à 06h36 pour proposer 2 fonctions:
- Une fonction qui retourne les valeurs Texte issues du SQL en tableau
- Une fonction qui charge un Range à partir des valeurs Texte issues du SQL et qui donne aux cellules du Range un format (autant que possible) correspondant au type de leurs valeurs (date, nombre, % etc...)
 

Pièces jointes

  • ClasseurTestSQL.xlsx
    9.9 KB · Affichages: 3
  • VBA Lire plage ou UsedRange d'une feuillle d'un classeur fermé.xlsm
    60 KB · Affichages: 8
Dernière édition:

patricktoulon

XLDnaute Barbatruc
oui dans tout ce fouilli que tu trouve il y a deux methodes
soit l'object ado open puis .execute
soit le recordset.open(la commandtext de la command de Ado) qui permet de lire jusqu'a EOF
la méthode utilisée dépend du besoins

si tu veux copier une feuille (son usedrange) passe par la première avec .CopyFromRecordset c'est plus simple et en late binding comme ça on active pas la ref activX Data

vite fait à l'arrache comme ceci (change le chemin du fichier )
VB:
Sub msj(fichier$)
    Dim Ado As Object, texte_SQL$, AdoReQ As Object
      Set Ado = CreateObject("ADODB.Connection")    'instance d'ado
    With Ado    'Ado Connexion
         .ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fichier & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1"""
        .Open
    End With
    texte_SQL = "select * from [feuil1$]" 'adapter le non de la feuill si besoins
    'Set AdoReQ = CreateObject("ADODB.Recordset")
    Set AdoReQ = Ado.Execute(texte_SQL)
     Sheets("Feuil1").[A1].CopyFromRecordset AdoReQ  'inscrisption du return de AdoReQ a la suite dans le sheets
       Ado.Close
    Set Ado = Nothing
End Sub

Sub lance()
Dim fichier$
fichier = "C:\Users\polux\DeskTop\Base.xlsx"    'chemin du  classeur fermé servant de base de données
msj fichier
End Sub
enjoy :)
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Tu as raison, faut revenir sur terre
1607088174536.gif
.
Et donc après ta proposition, en voici une autre pour le chargement de la ComboBox.
 

Pièces jointes

  • ComboBoxValeursExternes.xlsm
    45.5 KB · Affichages: 5
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 178
Messages
2 085 984
Membres
103 079
dernier inscrit
sle