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...
bon j'ai ChatGPt qui confirme ce que j'ai écrit plus haut :
Merci pour le code ! Tu utilises apparemment une classe personnalisée cBenchmark pour mesurer le temps, ce qui est une bonne approche pour garder ton code clair et modulaire.


Cependant, dans ton code actuel :
Code:
bm.TrackByName "debut ListfeuilleXmlTarV1"
xlsxPath = fichier
bm.TrackByName "fin ListfeuilleXmlTarV1"
MsgBox Join(ListfeuilleXmlTarV1(xlsxPath), vbCrLf)


Le mesurage du temps se fait avant et après l’affectation de la variable xlsxPath, mais pas autour de l'appel de la fonction ListfeuilleXmlTarV1, qui est pourtant ce que tu veux mesurer.
La fonction est appelée après la mesure, dans MsgBox Join(...), donc le temps mesuré ne reflète pas son exécution.




✅ Version corrigée​


Voici comment structurer correctement ton test pour mesurer le temps d’exécution de ListfeuilleXmlTarV1 :

VB:
Sub testv2()
    Dim bm As New cBenchmark
    Dim xlsxPath As String
    Dim result As Variant

    Debug.Print "Test de : ListfeuilleXmlTarV1 avec Tar+ split "

    xlsxPath = fichier ' Assure-toi que "fichier" est bien défini quelque part avant

    bm.TrackByName "début ListfeuilleXmlTarV1"
    result = ListfeuilleXmlTarV1(xlsxPath)
    bm.TrackByName "fin ListfeuilleXmlTarV1"

    MsgBox Join(result, vbCrLf)
End Sub
 
Comment dit plus haut ado converti les caractères pouvant être interprétée comme des caractères de syntaxe par exemple le point [.]

En général ça me pose pas de problème vu que si j'utilise Ado je fais tout en ado.

Donc table.champ#1 en remplacement de table.champ.1 ne me pose pas de problème alors que je sais qui faut effectuer un replace de point.

Au même titre qu'il faut encadrer par de [crochets] le champ possédant des espaces.
[Ma Table].[Mon Champ]
 
Dernière édition:
re:
a ça je sais pas @Dudu2 c'est toi qui vois c'est toi le maitre de ton topic
on est plusieurs a avoir proposé toi tu dispose maintenant en tenant compte de tes contraintes personnelles d'utilisateurs ou celles des

@nullosse tu avais raison sur une (un copier coller malheureux )
mais tu aurais montrer ca j'aurais vu tout de suite
chez moi les deux tar+ split restent les plus rapides on est certes dans les ms
 
re:
je pourrais aussi préciser que j'ai le patch LLA qui augmente la mémoire allouée a excel 32 bits de 2 giga à 3.86 (proche des 4 pour les 64 bits)
ce patch fait que je suis plus rapide sur de grands tableaux ça se verifie a chaque coups
par contre moins performant sur des petits tableaux ici encore toujours dans l'ordre de quelques ms
 
A noter aussi que dès que je m'amuse a mettre des points des virgule ou des points d'exclamations dans les noms de feuille les deux seules qui fonctionnent bien c'est les tar + split , même la shell.automation n'y résiste pas
moyennant le replace pour son exploitation bien entendu
conclusion oui @Dudu2
les tar + split c'est mon dernier mot (jean-Pierre)
 
@patricktoulon, ta dernière version Clipboard n'aime pas les caractères spéciaux dans le nom des feuilles.

1757419370448.png
 
@dysorthographie,
Concrètement, dans ce code, que faut-il changer ?
VB:
'-------------------------------------------------------
'Returns a table of Worksheet names of a closed Workbook
'Method @dysothographie
'-------------------------------------------------------
Private Function GetClosedWorkbookWorksheetNames(WorkbookFullName As String) As String()
    Dim ConnectionString As String
    Dim Connection As Object
    Dim TabWorksheets() As String
    Dim NbWorksheets As Integer
    Dim Table As Variant
    '
    Const ExtraWorksheetName = "_xlnm#_FilterDatabase"
    
    ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                      "Data Source=" & WorkbookFullName & ";Extended Properties=""Excel 12.0;HDR=NO;IMEX=1"";"
    Set Connection = CreateObject("ADODB.Connection")
    Connection.Open ConnectionString
    
    With CreateObject("ADOX.Catalog")
        .ActiveConnection = ConnectionString
        
        For Each Table In .Tables
            If Not Right(Table.Name, Len(ExtraWorksheetName)) = ExtraWorksheetName Then
                NbWorksheets = NbWorksheets + 1
                ReDim Preserve TabWorksheets(1 To NbWorksheets)
                TabWorksheets(NbWorksheets) = Table.Name
                TabWorksheets(NbWorksheets) = Replace(TabWorksheets(NbWorksheets), "$", "")
                TabWorksheets(NbWorksheets) = Replace(TabWorksheets(NbWorksheets), "'", "")
            End If
        Next Table
    End With
    
    Connection.Close
    Set Connection = Nothing
    
    'Return value
    GetClosedWorkbookWorksheetNames = TabWorksheets
End Function
 
Bon alors vous en voulez une
sans fichier xml intermediaire ?
sans clipboard?

et bien
on passe par le .exec du wscrpt.shell et donc a dispo son stdout.readall
par contre le readall renvoie le utf-8 comme Ansi du coup si je converti en utf-8 ce n'est pas bon car c'est deja converti
on a deux solutions
  1. un bypass avec deux object stream
  2. un passe avec un object xmlwriter (comme dans mon creator ribbonX pour les customUi.xml)
on va au plus simple avec deux object stream (tu me tiens tu me tien par la barbichette heu....) 🙃 🙃 🤪 🤣
pour le reste on prend les même et on recommence
alors ce sera pas le plus rapide sauf que la les caractres préhistoriques seront déja convertis
a voir si il faut en ajouter d'autre dans la boucle mais les principaux sont reconvertis dans le bypass streamer
VB:
Sub testv7()
    Dim bm As New cBenchmark
    Debug.Print "Test de : ListfeuilleXmlTarV5 avec Tar+ split stdout.readal + Ansi to utf-8"
    xlsxPath = "C:\Users\patricktoulon\Desktop\Classeur1.xlsx"
    bm.TrackByName "debut ListfeuilleXmlTarV5 avec Tar+ split stdout.readal + Ansi to utf-8"
    x = ListfeuilleXmlTarV5(xlsxPath)
    bm.TrackByName "fin ListfeuilleXmlTarV5 avec Tar+ split stdout.readal + Ansi to utf-8"
    
    MsgBox Join(x, vbCrLf)
End Sub

Function ListfeuilleXmlTarV5(xlsxPath)
    Dim cmd As String, codxml As String
    Dim streamAnsi As Object, streamUtf8 As Object
    
    ' Commande tar pour extraire le XML directement vers StdOut
    cmd = "cmd /c tar -xOf """ & xlsxPath & """ xl/workbook.xml"
    
    'execution de la ligne de commande avec wscrip.shell mais cette fois si avec exec et non run
    'car il nous faut le stdout.readall directe sans passer par l'object clipboard
    With CreateObject("WScript.Shell")
        codxml = .exec(cmd).StdOut.ReadAll
    End With
    'les caractères echapés
    codxml = Replace(codxml, "&amp;", "&")
    codxml = Replace(codxml, "&lt;", "<")
    codxml = Replace(codxml, "&gt;", ">")
    codxml = Replace(codxml, "&quot;", """")
    codxml = Replace(codxml, "&apos;", "'")
    'ajouter des eventuels replace que je n'ai pas vu ou testé
    'codxml = Replace(codxml,"blablabla","trucbidule")
 
    'format Ansi on l'ecrit comme il est même si c'est pas bon en Ansi
    'car extraction par le redall est en Ansi
    Set streamAnsi = CreateObject("ADODB.Stream")
    With streamAnsi
        .Type = 2: .Charset = "windows-1252": .Open: .WriteText codxml: .Position = 0: .Type = 1
    End With
    
    'format UTF-8
    'on copie le streamAnsi dans le streamUTF8 mais on l'encode avec utf-8
    Set streamUtf8 = CreateObject("ADODB.Stream")
    With streamUtf8
        .Type = 1: .Open: streamAnsi.CopyTo streamUtf8: .Position = 0: .Type = 2: .Charset = "utf-8"
        xmlContent = .ReadText
    End With
    'fermeture des streamer
    streamAnsi.Close: streamUtf8.Close
    
    'on prend les même et on recommence
    t = Split(xmlContent, "<sheet name=""") 'on coupe le texte par les ouvertures de balise "sheet"
    ReDim tx(1 To UBound(t) + 1) 'on dimentionne un tablkeau de même taile que le split EN BASE 1!!!!!
    For i = 1 To UBound(t)
        tx(i) = Split(t(i), """")(0) 'on prends que la partie qui nous interesse donc ni plus ni moins que l'attribut name
          Next
    ListfeuilleXmlTarV5 = tx 'le return c'est le tableau tx
    
End Function

les virgules les points les points d'exclamation les pointsvirgules etc....
yein afout!!!!!

1757424057159.png

Patrick
 

Pièces jointes

  • 1757419683593.png
    1757419683593.png
    111.6 KB · Affichages: 1
Dernière édition:
je sais il y a deux versions et une qui déconne il y a deux endroit dans github ou tu la trouve

remplacer.txt par .cls et importe la dans ton projet

c'est l'originale tel qu'elle est dans github

et non on est un peu plus long avec la dernière tar + split avec le stdout.readall du wscript.chell ,mais on a tout converti
il n'y a rien a faire (sauf si des trucs m'ont échappés )

93 ms
c'est quasiment pareil que ado sans la conversion des caractères hiéroglyphes

a voir combien de temps dure ado avec tout les caractères convertis j'essaie même pas moi
 

Pièces jointes

a ben si tu met pas la ref "scripting.runtime " effectivement ca risque pas de marcher
1757435062219.png
et en latebinding tu a essayé
Private discStampName as object

et dans ta sub
set DiscstampName=createobject("scripting.dictionary")

on le perds le dudu je vous le dit on le perd 🤪 🤪 🤣 🤣
 
Dernière édition:
Ah oui, je l'ai oublié celle-là !
Je me perds tout seul, parce que je m'énerve sur des trucs qui fonctionnent pas et que c'est pas bon pour la concentration ! 😡

D'ailleurs pour faire fonctionner les Dictionary il faut toujours cette référence ? Je suis étonné, pensais que c'était standard.
 
- 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
145
Réponses
4
Affichages
166
Retour