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...
avec tar et redirection vers un fichier en le laissant encodé en utf-8

xlsxPath="chemin du fichier excel.xlsx"

tempFolder = ThisWorkbook.Path

xmlPath = tempFolder & "\workbook.xml"

' Extraire directement le contenu du fichier sans créer l'arborescence
cmd = "cmd /c tar -xOf """ & xlsxPath & """ xl/workbook.xml > """ & xmlPath & """"

Set objShell = CreateObject("WScript.Shell")
result = objShell.Run(cmd, 0, True)

'on obtient le fichier xml
 
@nullosse,
et pourquoi par SQL ? elle est compliquée la requête ?
Non elle n'est pas complexe, voir le fichier en Post #151.
VB:
ReqSQL = "SELECT * FROM [" & WorksheetName & "$" & RangeAddress & "]"
Mais à partir du moment où dans le nom de la feuille (WorksheetName) il y a les 2 caractères à problème, le SQL part en sucette.
Même si ces caractères sont remplacés par leurs équivalents ADO. Ce n'est pas cohérent.
 
Mais à partir du moment où dans le nom de la feuille (WorksheetName) il y a les 2 caractères à problème, le SQL part en sucette.
Même si ces caractères sont remplacés par leurs équivalents ADO. Ce n'est pas cohérent.
Si tu converti les points [.] En [#] et les [!] En [_] je vois pourquoi ça ne fonctionnerait pas. Je vois pas de cohérence c'est comme ça.
 
Si tu converti les points [.] En [#] et les [!] En [_] je vois pourquoi ça ne fonctionnerait pas.
Tu penses bien que c'est la 1ère chose que j'ai faite.

1757524023798.png
1757524186618.png


Essaie avec le fichier joint pour t'en convaincre.

Edit: je l'avais déjà indiqué dans les Post #151 (Replace ou pas).
Ça ne m'étonne qu'à moitié car il doit chercher la feuille avec caractères remplacés et évidemment il ne la trouve pas !
L'incohérence c'est d'un coté je te refile un nom de feuille modifié, de l'autre je sais pas la retrouver avec le nom que je t'ai donné.
 

Pièces jointes

Dernière édition:
Bonsoir,
Avis uniquement personnel
Une solution tellement simple a été apportée
Le fil fait maintenant 13 pages et 184 réponses (aucune solution VBA fiable 100%) Edit : ou alors, pourquoi donc continuer?????
Mais ça continue, encore et encore, comme dirait Francis Cabrel... 🙂
Bonne continuation (et que le feuilleton dure le plus longtemps possible, ça donne de la lecture)
 
Dernière édition:
En effet, pour ceux qui ont suivi, la V5 est une solution VBA 100% fonctionnelle. Voir le post marqué en tant que solution.

La discussion a maintenant évolué non plus sur la récupération des noms des feuilles mais sur la récupération de leur contenu à partir de leurs noms ce qui est le point commun de l'affaire et qui pose le même genre de problème. Mais visiblement pour ça, il n'y a pas de solution 100% fonctionnelle ADO ou pas. Il va falloir faire une usine à gaz pour y parvenir et je vais m'appliquer à la coder sur la base des infos de @nullosse.
 
Plusieurs questions me turlupinent :
1 - Pourquoi aller chercher des données par sql alors que l'on peut faire autrement ?
2 - Pourquoi aller chercher le nom des feuilles et faire une requête SQL ensuite sur une de ses feuilles ? Comment sait-t-on la feuille qu'il faut utiliser ? on connaît déjà son nom ?
 
Bonjour @nullosse ,
1 - Pourquoi aller chercher des données par sql alors que l'on peut faire autrement ?
Si tu as une autre méthode, tu peux la donner STP ?
S'il s'agit d'ouvrir le classeur dans une instance cachée (ce que je prévois de faire pour les cas où les noms de feuille contiennent "." ou "!", ce n'est pas judicieux car la méthode SQL sera 10x (100x ?) plus rapide.

2 - Pourquoi aller chercher le nom des feuilles et faire une requête SQL ensuite sur une de ses feuilles ? Comment sait-t-on la feuille qu'il faut utiliser ? on connaît déjà son nom ?
Dans mon cas précis, je dois analyser le contenu de toutes les feuilles dont je ne connais pas le nom. C'est le but de ce sujet.
Mais si on connait par avance le nom d'une feuille dont il faut récupérer le contenu, alors évidemment, point n'est besoin de la V5.
 
Salut,
en résumé, il ne semble pas possible d'utiliser ADoDb ACE pour obtenir des données d'une feuille dont le nom comporte un . ou un !. Il existe
d'autres drivers (CData, Devart) mais ils sont payants et je ne sais pas si ils gèrent le cas qui coince
Dans ce cas comme solution, utiliser une instance invisible en récupérant les données autrement que par sql, comme ceci par exemple :
VB:
Data = wb.Sheets("-_,.;!(){}@#$%^&+=éèàôüç…").Range("A1:C3").Value
Bien sûr c'est plus lent qu'avec ADO (~500ms pour créer nouvelle instance, ~120 ms pour ouvrir un classeur). Mais une fois que le classeur est ouvert on peut aller chercher toutes les feuilles.
Dans d'autres langages avec des bibliothèques appropriées on peut lire les données des fichiers xlsx (ex : openpyxl pour python et xlsx pour javascript.
En javascript avec les bibliothèques xlsx (lire et écrire fichier xlsx) et Alasql (gestion SQL) on peut faire l'équivalent des requêtes ADODB ACE
il n'y a pas la limitation des noms de feuille et c'est plus rapide :
xlsxJavascript.gif

Les bibliothèques sont chargées au début des scripts javascript du html à partir d'un dépôt gratuit sur le net. Elles restent dans le
cache du navigateur assez longtemps (jusqu'à un an) et ne sont donc pas rechargées à chaque fois.
Le fichier html utilisé pour la démo fait 4Ko.

Nullosse
 
Les bibliothèques sont chargées au début des scripts javascript du html à partir d'un dépôt gratuit sur le net. Elles restent dans le
cache du navigateur assez longtemps (jusqu'à un an) et ne sont donc pas rechargées à chaque fois.
Je sais pas manipuler ces trucs là. Si j'ai bien compris, ce sont des bibliothèques externes et donc le code VBA n'est pas autonome et a besoin qu'elles soient installées dans un environnement "étranger". Ça complique la mise en œuvre.
 
Voici le code qui utilise soit SQL pour les noms de feuilles sans "." et "!" et une instance Excel cachée pour ouverture du classeur sinon.
Pour la partie Instance Excel invisible je te conseille ceci :
VB:
    If Not InStr(WorksheetName, ".") = 0 _
    Or Not InStr(WorksheetName, ".") = 0 Then
        On Error GoTo CleanUp
        Set ExcelApplication = CreateObject("Excel.Application")
        ExcelApplication.Visible = False: ExcelApplication.ScreenUpdating = False
        ExcelApplication.DisplayAlerts = False: ExcelApplication.EnableEvents = False
        ' Ouvrir le fichier
        Set Workbook = ExcelApplication.Workbooks.Open( _
        Filename:=WorkbookFullName, _
        ReadOnly:=True, _
        UpdateLinks:=0, _
        IgnoreReadOnlyRecommended:=True)
        If Len(RangeAddress) = 0 Then
            TabVal = Workbook.Worksheets(WorksheetName).UsedRange.Value
        Else
            TabVal = Workbook.Worksheets(WorksheetName).Range(RangeAddress).Value
        End If
        Workbook.Close SaveChanges:=False
CleanUp:
        ExcelApplication.Quit
        Set ExcelApplication = Nothing

Si il y a une erreur on ferme l'instance, sinon on risque de se retrouver avec des processus Excel fantômes en arrière-plan
et ne pas faire de pas à pas en arrêtant le code avant la fermeture d'instance, sinon l'instance reste en mémoire.
A noter qu'avec l'instance invisible , on peut balayer toutes les feuilles sans connaître leurs noms.
 
J'ai adapté le fichier du Post #192.
Alors je sais que la manip instance est faite au niveau de la feuille alors qu'elle devrait être faite au niveau du programme, mais la fonction est au niveau feuille et il faudrait sortir la création et la suppression de l'instance ou passer un flag de dernière feuille à traiter pour supprimer l'instance. Je ne l'ai pas fait en considérant qu'un nom de feuille avec "." ou "!" est un cas exceptionnel.

Edit:
A noter qu'avec l'instance invisible , on peut balayer toutes les feuilles sans connaître leurs noms.
Oui mais on n'a besoin de l'instance précisément quand on a "." ou "!" dans un nom de feuille, et donc il faut au préalable connaître ce nom de feuille. Après évidemment, on peut ne pas s'intéresser aux noms des feuilles et les adresser par leur Index via l'instance, ce que ADO SQL ne permet pas (à ma connaissance) et c'est dommage.
 
Dernière édition:
- 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
566
Réponses
4
Affichages
245
  • Résolu(e)
Microsoft 365 transposer
Réponses
6
Affichages
165
Réponses
4
Affichages
341
Retour