XL 2016 VBA - Trouver les feuilles d'un classeur fermé

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Solution
Bonjour @nullose
vien vu
mais attention là on garantie plus l'ordre exacte des feuilles
car j'ai testé plusieurs classeurs et certains va savoir pourquoi les <sheet name="... ne sont pas dans l'ordre dans certains fichier
c'est pour ça que j'utilise l'indexation par l'attribut "sheetId"
donc
il faut laisser le tableau se construire avec les lignes vides et les supprimer par la suite
VB:
'patricktoulon

Sub testv5()
    xlsxPath = "C:\Users\patricktoulon\Desktop\Classeur1.xlsx"
    MsgBox Join(ListfeuilleXmlTarV2(xlsxPath), vbCrLf)
    Debug.Print Join(ListfeuilleXmlTarV2(xlsxPath), vbCrLf)
End Sub


Function ListfeuilleXmlTarV2(xlsxPath)
    Dim tempFolder As String, xmlPath As String, xmlcontent As String, cmd As String...
tu es sûr que cela fonctionne si une de tes feuilles à un . ou un ! dans son nom parce que l'ADO doit peut être changer le caractère même en lecture de feuille ?
Je suis sûr que ça ne fonctionne pas.
Que je récupère les noms de feuilles avec la méthode @dysorthographie ou la méthode mix @laurent950 + @nullosse + @patricktoulon Replace ou pas ça ne marche pas !

Edit: Par contre dans les données, "!" et "." sont bien restitués sans modification.
 

Pièces jointes

Dernière édition:
Ben Alors quand tu récupères le nom des feuilles , tu sors en message d'erreur si tu vois un . ou un ! (si lecture de nom de feuilles exact) ou un # ou un _ (lecture des noms par ADO).
Si nom de feuille exacte oui, un message d'erreur, y a plus que ça ! Mais je préfèrerais un SQL qui fonctionne avec les noms exacts.
Si nom de feuille par ADO non, car # ou _ sont peut-être authentiques et pas des caractères de remplacement de . et !. On n'en sait rien !
 
Si nom de feuille exacte oui, un message d'erreur, y a plus que ça ! Mais je préfèrerais un SQL qui fonctionne avec les noms exacts.
Si nom de feuille par ADO non, car # ou _ sont peut-être authentiques et pas des caractères de remplacement de . et !. On n'en sait rien !
et pourquoi ne pas utiliser une instance excel invisible par createobject("Excel.Application") si il y a des caractères louches ? ça sera plus lent mais il n' y aura pas certainement pas beaucoup de classeurs avec des noms de feuille à caractères dangereux (. ! # _)
 
Pourquoi pas.
Comment rends-tu une instance invisible ?
voici un exemple :
VB:
Sub LireUsedRangeDansInstanceInvisible()
    Dim xlApp As Object ' Nouvelle instance Excel
    Dim wb As Object    ' Le classeur à ouvrir
    Dim ws As Object    ' La feuille active
    Dim fichier As String
    Dim plage As Object

    ' 📁 Chemin complet vers le fichier à ouvrir
    fichier = "C:\Chemin\Vers\TonFichier.xlsx"

    ' 📌 Créer une nouvelle instance d'Excel
    Set xlApp = CreateObject("Excel.Application")
    
    ' Rendre l'instance invisible
    xlApp.Visible = False

    ' Désactiver les alertes (ex : mise à jour de liens)
    xlApp.DisplayAlerts = False

    ' 📂 Ouvrir le classeur
    Set wb = xlApp.Workbooks.Open(fichier)

    ' 📄 Prendre la première feuille (ou adapte selon le nom/indice)
    Set ws = wb.Sheets(1)

    ' 🧾 Lire la plage utilisée
    Set plage = ws.UsedRange

    ' 🖨️ Exemple : afficher la plage dans la fenêtre Exécution
    Debug.Print "Adresse de UsedRange : " & plage.Address
    Debug.Print "Nombre de lignes : " & plage.Rows.Count
    Debug.Print "Nombre de colonnes : " & plage.Columns.Count
    Debug.Print "Valeur cellule A1 : " & ws.Range("A1").Value

    ' ✅ Fermer sans enregistrer
    wb.Close SaveChanges:=False

    ' 🧹 Quitter et libérer l'instance
    xlApp.Quit
    Set ws = Nothing
    Set wb = Nothing
    Set xlApp = Nothing

    MsgBox "Lecture terminée avec succès.", vbInformation
End Sub
 
voici un exemple
VB:
Sub LireFeuillesEtUsedRangeInstanceInvisible()
    Dim xlApp As Object         ' Nouvelle instance Excel
    Dim wb As Object            ' Le classeur à ouvrir
    Dim ws As Object            ' Feuille de calcul
    Dim fichier As String
    Dim plage As Object
    Dim nomFeuilles As String
    Dim i As Long
    '  Chemin du fichier Excel à ouvrir
    fichier = "C:\Chemin\Vers\TonFichier.xlsx"  
    ' Créer une instance invisible de Excel
    Set xlApp = CreateObject("Excel.Application")
    xlApp.Visible = False
    xlApp.DisplayAlerts = False
    ' Ouvrir le fichier
    Set wb = xlApp.Workbooks.Open(fichier)
    ' Lister les noms de feuilles
    For i = 1 To wb.Sheets.Count
        nomFeuilles = nomFeuilles & wb.Sheets(i).Name & vbCrLf
    Next i
    MsgBox "Feuilles trouvées :" & vbCrLf & nomFeuilles, vbInformation
    '  Lire le UsedRange de la première feuille
    Set ws = wb.Sheets(1)
    Set plage = ws.UsedRange
    '  Infos sur UsedRange
    Debug.Print "Feuille : " & ws.Name
    Debug.Print "Adresse UsedRange : " & plage.Address
    Debug.Print "Lignes utilisées : " & plage.Rows.Count
    Debug.Print "Colonnes utilisées : " & plage.Columns.Count
    '  Fermer le classeur sans enregistrer
    wb.Close SaveChanges:=False
    xlApp.Quit
    ' Libération mémoire
    Set plage = Nothing
    Set ws = Nothing
    Set wb = Nothing
    Set xlApp = Nothing

    MsgBox "Lecture terminée.", vbInformation
End Sub
Si il y a plusieurs fichiers à traiter n'ouvrir qu'une fois une instance
 
Ok. Mais je pige pas tout car en principe il n'y a aucune possibilité de communication entre 2 instances Excel.
Et là il semble que le classeur ouvert en instance #2 soit complètement accessible en instance #1. Etonnant !

Bon sur cette base je vais essayer de coder un truc pour palier cette restriction ADO.
@dysorthographie, sûr ? Pas moyen de faire tourner cette requête SQL avec un nom de feuille avec . ou ! ?
VB:
ReqSQL = "SELECT * FROM [" & WorksheetName & "$" & RangeAddress & "]"
 
Dernière édition:
Pas moyen de faire tourner cette requête SQL avec un nom de feuille avec . ou ! ?
VB:
ReqSQL = "SELECT * FROM [" & WorksheetName & "$" & RangeAddress & "]"
voici ce que répond chatgpt :

Cas : Requête SQL ADO avec noms de feuille contenant​


📌 Problème :​


  • En ADO/OLEDB, les noms de feuilles sont normalement utilisés avec un $ à la fin et entourés de crochets [NomFeuille$].
  • Mais s’il y a un point (.) ou un point d’exclamation (!), cela peut faire échouer la requête car ADO interprète ! comme un séparateur entre feuille et plage.



✅ Solution :​


Il faut entourer le nom complet de la feuille avec des crochets, et doubler les crochets si le nom est étrange.


🔁 Syntaxe échappée recommandée :​

SELECT * FROM ['Nom.Complexe!AvecCaractères$']


⚠️ Assure-toi que le nom se termine bien par $ et est entouré de ' à l’intérieur des crochets [ ].


 
Si t'on problème est de récupérer les noms des onglets alors je reconnais la difficulté de retranscrire dans excel.

Si t'on problème est de savoir si un feuille existe il n'y a aucun problème car tu connais quels sont les caractères de de convention excel-> Ado.

Si tu veux récupérer une ou plusieurs valeurs du fichier fermé tu peux requête directement avec les valeurs des listetable.

Notes que la fonction tablexist te retourne true/false mais il faut une conversation du nom des onglets end ado

Je prêche pour ma paroisse mais c'est pas moi qui l'utilsera

Il est vrai qu'ado est axé base de données et que général on préconise de ne pas utiliser ces caractères d'où le manque de précision sur les caractères de substitution.
 
Dernière édition:
Bonjour

j'ai cela aussi : Peux etre que l'on peux directement lire a l'intérieur du fichier Excel sans changer l'extension
a voir avec cela :


Voir le Poste Binaire :
Code:
Non compatible avec XLSX (Fichier Archive)

uniquement avec fichier xls.

Sub VerifSheet()
Const Wbk$ = "D:ExcelDataBaseMonClasseur.xls"
Const Sht$ = "Feuil3"
If FindSheet(Wbk, Sht) Then
MsgBox "La feuille " & Sht & " est présente dans" & vbLf & Wbk & " !", 64
End If
End Sub

Private Function FindSheet(FullPath$, Name$) As Boolean
If Dir(FullPath) = "" Then Exit Function
Dim Pos&(1 To 2), b(0 To 2048) As Byte
Dim lr&: lr = FileLen(FullPath)
Dim f&: f = FreeFile
Open FullPath For Binary Access Read As #f
Do
Pos(1) = Pos(1) + 2047
Get #f, Pos(1), b
Pos(2) = InStrB(b, ChrB(133))
Loop While Pos(2) = 0 And Pos(1) < lr
Do While Pos(2) > 0
Pos(1) = Pos(1) + Pos(2) - 1
Get #f, Pos(1), b
FindSheet = CBool(Mid(StrConv(b, vbUnicode), 13, b(10)) = Name)
If FindSheet Then Exit Do
Pos(2) = IIf(b(b(2) + 4) = 133, InStrB(4, b, ChrB(133)), 0)
Loop
Close #f
End Function

Le code ci-dessous fonctionne mais il peux etre adapter.

VB:
' https://analystcave.com/vba-xml-working-xml-files/
Sub ListSheetNames()
' Chemin :
    Dim origPath As String
    Dim origFich As String
    Dim zipPath As String
' Créer une instance de Shell.Application
    Dim shellApp As Object
' Ouvrir le fichier .zip comme un fichier ZIP
    Dim zip As Object
' Parcourir les éléments pour trouver le dossier "xl"
    Dim item As Object
' Parcourir les éléments dans "xl" pour trouver workbook.xml
    Dim subItem As Object
' Charger le document XML
    Dim XDoc As Object
    Dim xmlContent As Object
' Collecte des nom des Feuilles
    Dim sheetNames As Collection
    Dim sheetName As Variant
    Dim startPos As Long, endPos As Long
    Dim cheminFich As String
' -----------------------------------------------------------------------------

    ' Chemin du fichier XLSX
    origPath = "C:\Users\Cheminsadefinir\Downloads\"
    origFich = "LeFichier.xlsx"
    zipPath = origPath & origFich & ".zip"

    ' Renommer temporairement en .zip
    Name origPath & origFich As zipPath

    ' Créer une instance de Shell.Application
    Set shellApp = CreateObject("Shell.Application")

    ' Ouvrir le fichier .zip comme un fichier ZIP
    Set zip = shellApp.Namespace(CStr(zipPath))

    ' Vérifier si le fichier ZIP a été ouvert correctement
    If Not zip Is Nothing Then
        ' Parcourir les éléments pour trouver le dossier "xl"
        For Each item In zip.Items
            If item.Name = "xl" Then
                ' Parcourir les éléments dans "xl" pour trouver workbook.xml
                For Each subItem In item.GetFolder.Items
                    If InStr(subItem.Name, "workbook.xml") > 0 Then
                        ' Lire le contenu XML
                            Set XDoc = CreateObject("MSXML2.DOMDocument")
                                XDoc.async = False: XDoc.validateOnParse = False
                                'XDoc.Load (ThisWorkbook.Path & "\workbook.xml")
                                XDoc.Load (origPath & CStr(subItem.Name))
                        'Get Document Elements
                            Set xmlContent = XDoc.DocumentElement
                                MsgBox xmlContent.XML
                        Exit For
                    End If
                Next subItem
                Exit For
            End If
        Next item
    End If

    ' Extraire les noms des feuilles
    Set sheetNames = New Collection
    If Len(xmlContent.XML) > 0 Then
        startPos = InStr(1, xmlContent.XML, "<sheet name=""")
        Do While startPos > 0
            startPos = startPos + Len("<sheet name=""")
            endPos = InStr(startPos, xmlContent.XML, """")
            sheetName = Mid(xmlContent.XML, startPos, endPos - startPos)
            sheetNames.Add sheetName
            startPos = InStr(endPos, xmlContent.XML, "<sheet name=""")
        Loop
    End If

    ' Afficher les noms des feuilles
    For Each sheetName In sheetNames
        Debug.Print sheetName
        Affichage = Affichage & (i + 1) & " - " & sheetName & vbCrLf
    Next sheetName

    ' Remettre le fichier à son nom d'origine
    Name zipPath As origPath & origFich
    
    ' Resultat
    MsgBox Affichage
End Sub
 
Il faut être pragmatique, soit tu sais ce que tu cherches et dans ce cas tu connais la substitution à appliquer de Excel -> Ado.

Soit tu ne sais pas et alors tu appliques ADONameToExcel qui te retournera un Nom d'onglets valide même si il n'est pas exactement identique. C'est ce que fait Access pour importer un fichier excel en table Access.
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

  • Question Question
Microsoft 365 Excel et Insee
Réponses
6
Affichages
556
Réponses
4
Affichages
229
  • Résolu(e)
Microsoft 365 transposer
Réponses
6
Affichages
146
Réponses
4
Affichages
178
Retour