Utiliser la fonction "recherche" d'un classeur fermé sur un autre classeur

Bonjour Pierre,

J'ai testé la version 2020, interface très propre, avec des filtres et tris intéressants. Il manque juste une incrémentation automatique lors de la créations de nouveaux éléments et l'ajout en reprenant des caractéristiques de la liste mais ça je le gère déjà.

Pour la version 2021 (celle qui m'intéresse), j'ai un problème lorsque je lance le userform ici :

Function Combo_T(Ttk As Variant, col As Integer) As Variant
Dim idx As Long, i As Long, j As Long
Dim T() As Variant, present As Boolean

    idx = 1
    ReDim T(idx)
    For i = LBound(Ttk, 1) To UBound(Ttk, 1)
        present = False
        For j = 0 To UBound(T)
            If Ttk(i, col) = T(j) Then '''''''''''''''''''''''''''''''''''''''ici''''''''''''''''''''''''''''''''''''''''''
                present = True
                Exit For
            End If
        Next j
        If Not present And Not Ttk(i, col) = "" Then
            ReDim Preserve T(idx)
            T(idx) = Ttk(i, col)
            idx = idx + 1
        End If
    Next i
    T = TriListe(T)
    T(0) = "Tous"
    Combo_T = T
End Function

Je me plonge dans ton code SQL en attendant,

Merci d'avance.

En effet, l'exemple proposé est totalement foireux ...

Pierre

Edit de 10h06 : voici la correction, comme un con j'avais effacé trop de choses ... ici les entêtes sont utiles ... (quel gland!)

Toujours un problème de compilation, c'est peut-être moi cette fois.

Aucune ligne à changer sur l'emplacement du fichier BDD par hasard?

Merci d'avance

C'est tout bon finalement, je n'avais pas encore ouvert la BDD et activé le contenu.

Le mode lecture marche très bien, je vais pouvoir y ajouter l'extraction et ce serra top.

Cependant l'ajout via le doc filtreSQL sur le doc BDD ne marche pas! As-tu une version ou celui-ci est fonctionnel?

Merci d'avance.

Bonjour à tous,

Merci pour ta réponse Pierre !

J'ai regardé tes fichiers (bravo ! ) mais c'est tellement fourni que je me perds un peu... Ce que je ne comprends pas, c'est comment faire : il faut créer un objet ADOBD ? Comment connaitre les requêtes, les termes précis ? C'est cette petite base qui pourrait m'aider car sur un exemple, on a jamais la certitude de la reproductibilité. Mais peut-être que ces réponses sont sur les liens que tu as postés, je vais regarder, j'y verrai peut-être plus clair.

Merci encore !

Cdlt,

c'est tellement fourni que je me perds un peu...

Alors voici une démo très-très-très simplifiée qui sera probablement plus parlante. Ici un onglet requête sur un autre.

Pierre

21demo-xls.xlsm (29.68 Ko)

Merci Pierre !

Je décèle une petite erreur : la ville de Brest sur ton exemple. En bon morbihannais, tu aurais dû mettre une ville comme Auray ou Pontivy à la place !

Bon, ce qui te semble trivial n'est pas super évident pour moi...

Public Cnx As Object, Rst As Object

Sub Connect_Xls(Ndf As String)
    Set Cnx = CreateObject("ADODB.Connection") 'objet permettant la connexion ? nécessite pas l'ajout d'une référence ?
    Cnx.Provider = "MSDASQL" '???
    Cnx.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" & _
             "DBQ=" & Ndf & "; ReadOnly=False;" '??? Driver ? Comment connaitre les valeurs possibles ? DBQ ? Ndf est le chemin ?
    Set Rst = CreateObject("ADODB.Recordset") 'objet permettant d'agir ?
End Sub

Sub Close_Cnx(Optional x As Byte)
    On Error Resume Next
    If x > 0 Then Rst.Close
    Cnx.Close
    Set Cnx = Nothing
    Set Rst = Nothing
End Sub

Function Select_Db(Req As String, Optional Head As Byte = 1) As Variant
Dim T As Variant, Rcd As Variant
Dim lig As Long, col As Long, i As Long, j As Long

    On Error GoTo errhdlr
    ReDim Rcd(1 To 1, 1 To 1)
    Rst.Open Req, Cnx, 3
    lig = Rst.RecordCount
    If lig > 0 Then
        Rst.MoveFirst
        T = Rst.GetRows
        col = Rst.Fields.Count
        ReDim Rcd(1 To lig + Head, 1 To col)

        For j = 0 To col - 1
            Rcd(1, j + 1) = Rst.Fields(j).Name
            For i = 0 To lig - 1
                Rcd(i + 1 + Head, j + 1) = IIf(IsNull(T(j, i)), "", T(j, i))
            Next i
        Next j
    End If
    Select_Db = Rcd
    Exit Function

errhdlr:
    Rcd(1, 1) = "Erreur n°" & Err.Number & vbCrLf & Err.Description
    Select_Db = Rcd
End Function

Sub Exemple_requete()
Dim Req As String, T As Variant

    Req = "SELECT O.`Opérateur`, O.`Ville`, A.`Id_A`, A.`Action`, A.`Date`" & _
          " FROM [Data$A:C] AS O" & _
          " LEFT JOIN [Data$E:H] AS A On O.Id_O=A.Id_O" '<<<< ??? SELECT ? FROM ? Que signifient les O. et les A. ?

    Connect_Xls ThisWorkbook.Path & "\" & ThisWorkbook.Name
    T = Select_Db(Req)
    Close_Cnx

    Sheets("Bilan").Range("A1:F2000").ClearContents
    Sheets("Bilan").Range("A1").Resize(UBound(T, 1), UBound(T, 2)) = T
End Sub

J'ai commenté ce que je ne trouve pas facilement déchiffrable. Si tu pouvais m'expliquer, ce serait super. Sinon, je comprendrais, j'irai me renseigner de toute façon.

Merci beaucoup pour le partage !

Cdlt,

Originaire de BREST-Même!! ... Mais je suis expat du côté de Vannes

L'objet "ADODB.Recordset" va être utile pour stocker les info lues par la suite dans 'Select_Db', cf Rst.Open, Rst.Movefirt, Rst.GetRows, Rst.Fields utilisés par la suite

'<<<< ??? SELECT ? FROM ? Que signifient les O. et les A. ?

Ça c'est du Sql => https://sql.sh/cours/select, O. et A. sont des alias => https://sql.sh/cours/alias

Pierre

Ah, d'accord ! Donc un vrai breton mais un faux morbihannais ! Je ne connais pas Brest mais je connais la presqu'ile pas loin de Vannes, ça valait sûrement le coup de "s'expatrier".

Merci beaucoup pour ces liens ! J'ai plus qu'à m'y mettre maintenant.

J'espère que j'arriverai à comprendre (sinon, je sais où te trouver^^).

A bientôt,

Je ne voudrais pas vous déranger mais je réitère mon interrogation :

"Le mode lecture marche très bien, je vais pouvoir y ajouter l'extraction et ce serra top.

Cependant l'ajout via le doc filtreSQL sur le doc BDD ne marche pas! As-tu une version ou celui-ci est fonctionnel?"

Merci d'avance.

Désolé pour les hors sujets précédents!

Le fichier de ce matin n'était qu'une démo de lecture d'un xl externe (le reste n'est pas fonctionnel)

Pour des ajouts d'enregistrements (INSERT) ou modif (UPDATE) voici une autre démo la plus simple possible.

Ici les données de l'onglet "Feuil1" sont ajoutées ou modifiées dans "Feuil2".

Pour ces 2 opérations les formats de données sont importants, d’où les fonctions de formatage utilisées.

A noter également la spécificité d'xl : pour le stockage des données il n'y a pas de définition formelle de format.

Et en fait excel lit les 8 premières lignes des données pour se dire "ici c'est du texte ou là c'est du numérique"

S'il n'y a aucune donnée à lire, il traite en tant que texte.

Pour forcer un format précis (texte, numérique, date), il convient donc de créer une ligne "zéro" avec de données correctement calibrées

Ce fichier reste une démo qui-ne-sert-à-rien-d'autre

Et pour externaliser les données il suffit de modifier la ligne => Connect_xls ThisWorkbook.Path & "\" & ThisWorkbook.Name

Souhaitant que ça soit utile

Pierre

Je n'ai pas tout compris le code.

J'aurais espérer un exemple complet.

Cordialement

Des exemples complets et pleinement fonctionnels, il y en a par exemple ici =>

Mais je doute que ça soit aidant d'où les petits exemples simplex.

Maintenant pour comprendre le code de la démo-insert-update, il faut avoir une notion d'une requête Sql

Pour un ajout de données => https://sql.sh/cours/insert-into la syntaxe est :

INSERT INTO table VALUES ('valeur 1', 'valeur 2', ...)

Pour une modif de données => https://sql.sh/cours/update la syntaxe est :

UPDATE table SET nom_colonne_1 = 'nouvelle valeur' WHERE condition

Sauf que ces lignes sont interprétées par le 'moteur' Sql. Il est donc nécessaire de les 'traduire en Vba' en utilisant des données de la feuille excel, d'où les codes utilisés dans cette démo =>

Req = "INSERT INTO [" & Table & "] VALUES(" & _
      .Cells(i, "A").Value & "," & _
      Esc(.Cells(i, "B").Value) & "," & _
      Esc_num(.Cells(i, "C").Value) & "," & _
      CDbl(CDate(.Cells(i, "D").Value)) & _

ou

Req = "UPDATE [" & Table & "] SET " & _
      " `du texte`=" & Esc(.Cells(i, "B").Value) & "," & _
      " `un nombre`=" & Esc_num(.Cells(i, "C").Value) & "," & _
      " `une date`=" & CDbl(CDate(.Cells(i, "D").Value)) & _
      " WHERE `Id`=" & .Cells(i, "A").Value

Ce qui donne un truc du genre => INSERT INTO [Feuil2$A:D] VALUES(1,'azerty',42.5,44260)

ou UPDATE [Feuil2$A:D] SET `du texte`='azertyuiop', `un nombre`=142.5, `une date`=44261 WHERE `Id`=1

lignes 'compréhensibles' par le moteur Sql, conforme à la syntaxe Sql, qu'on peut exécuter en écrivant simplement Cnx.Execute Req

Est-ce que ça aide ?? (j'en suis pas sûr ...)

Salut Pierre,

Encore merci pour tes multiples retour, je ne vais cependant plus avoir de temps pour travailler sur l'ajout et la modif.

J'ai donc repris ton document de décembre 2020 et j'y ai implanter mon tableau, j'ai bien sur changer les plages de donnée, bien nommé le tableau mais rien y fait ça plante. (j'ai du manquer une modification mais je ne vois pas ou c'est)

Encore merci pour toutes ces connaissances.

Cordialement.

Bonjour,

Heum, il faut aussi revoir les requêtes ...

A minima comme ceci, mais après il faut déterminer quoi afficher, quoi filtrer, quoi modifier, ....

Encore une fois ce n'était qu'une démo simplette

Bref en l'état c'est loin d'être du cousu-main et moi non plus je ne vais pas avoir le temps pour les adaptations nécessaires.

Pierre

Rechercher des sujets similaires à "utiliser fonction recherche classeur ferme"