Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 VBA - Syntaxe de FileFilter en Dialog GetSaveAsFilename

  • 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 !

Dudu2

XLDnaute Barbatruc
Bonjour,
Quoi de plus compliqué que de sélectionner des extensions avec Excel VBA !?
Ça fait 1 heure que j'essaie de trouver la syntaxe infernale de FileFilter sans succès. Je n'arrive pas à integrer les CSV. Il ne prend que les *.xls*.
VB:
Sub a()
    Dim DialogReturn As Variant
 
    DialogReturn = Application.GetSaveAsFilename(InitialFileName:=ThisWorkbook.Path, _
                                                 FilterIndex:=2, _
                                                 FileFilter:="Classeurs Excel (*.xls*), xls*, (*.csv), *.csv")
    MsgBox "DialogReturn = " & DialogReturn
End Sub

Merci par avance pour toute assistance.
 
Dernière édition:
Solution
Alors, en conclusion de ces recherches, voici comment utiliser ce Dialog à la logique infernale.

Code:
FileFilter:="<Partie gauche>, <Partie droite>")
  1. Seule la partie gauche (avant la virgule) est utile
  2. La partie droite (après la virgule) ne sert à rien mais sa présence est obligatoire
  3. La partie gauche sert:
    • d'affichage dans la zone Type du Dialog (toute la partie gauche)
    • de filtre d'affichage des fichiers via des masques nom de fichier + extensions séparés par point-virgule (ce qui est dans la parenthèse)
    • de choix de l'extension si un nom de fichier est inclus dans le InitialFileName, correspondant à la 1ère extension mentionnée sans wildcards après le point si elle existe (ce qui est dans...
Salut,
on ne peut pas mettre n'importe quelle extension dans une opération de SaveAs car il faut que cela soit un format possible d'enregistrement. Si
on veut mettre n'importe quoi il faut utiliser une boîte de dialogue Open par exemple. Dans la boîte de dialogue FileDialog pour un saveAs on a
dans les filtres, tous les types de fichiers possibles en enregistrement. C'est le filterIndex qui permet de choisir le type qui va être
affiché dans la boîte de dialogue. Pour que le nom du fichier que l'on indique comme InitialFileName reste affiché dans la boîte de dialogue,
il suffit de choisir le filterIndex qui correspond à l'extension du fichier initial. Par exemple pour dudu2.csv :
VB:
Sub FileDialogSaveAs()
    Dim fd As FileDialog, x As Integer
    Set fd = Application.FileDialog(msoFileDialogSaveAs)
    With fd
        .InitialFileName = "c:\temp\dudu2.csv"
            For x = 1 To fd.Filters.Count
              If Right(.Filters(x).Extensions, 4) = Right(.InitialFileName, 4) Then Exit For
            Next x
        .FilterIndex = x
        .Title = "Sauvegarder comme"
        If .Show = -1 Then
            Debug.Print .SelectedItems(1)
        Else
            MsgBox "Sauvegarde Annuler"
        End If
    End With
End Sub
Le csv est un cas particulier car il existe plusieurs filtres avec cette extension. Pour choisir celui qui convient, il faut forcer alors
le FilterIndex (par exemple un FilterIndex à 16 pour un CSV délimité point-virgule).

Nullosse.
 
Bonjour,
il faut que cela soit un format possible d'enregistrement.
N'importe quelle extension (.toto) est valide car il n'y a pas de liste fermée d'extensions.
Les logiciels utilisent leurs propres extensions, par exemple FreeFileSync utilise LastRun.ffs_gui et c'est son choix.

Pour que le nom du fichier que l'on indique comme InitialFileName reste affiché dans la boîte de dialogue,
il suffit de choisir le filterIndex qui correspond à l'extension du fichier initial
Là encore il y a confusion pour moi. Le FilterIndex c'est pour filtrer l'affichage, pas pour l'extension qu'on veut attribuer.
L'utilisateur a le droit de voir les fichiers de plusieurs extensions et le développeur a le droit de proposer l'extension qu'il veut.

Accessoirement, le dialogue Application.FileDialog(msoFileDialogSaveAs) se termine par l'enregistrement effectif du fichier.
Ce qui n'est pas le cas de Application.GetSaveAsFilename qui ne fait que retourner le nom choisi, à charge pour le code d'effectuer l'enregistrement, ce qui me convient mieux.

Pour contourner toutes ces insupportables contraintes et prises de têtes sur ce qu'on doit ou peut indiquer en relation avec tel ou tel automatisme, j'utilise le code de la solution. Et ça fonctionne !
 
Dernière édition:
Bonjour,
Je reviens sur ce sujet dans un contexte différent car, lorsqu'on demande la fermeture d'un classeur, s'il est le dernier de l'instance, on se récupère un écran Excel vide.



VB:
Sub a()
    Call WorkbookClose(ThisWorkbook)
End Sub

'----------------
'Close a Workbook
'----------------
Private Sub WorkbookClose(Workbook As Workbook)
    With Workbook
        '--------------------------------
        'Problème de l'écran EXCEL vide !
        '--------------------------------
        If .Saved Then
            With Application
                '--------------------------
                'Le .Quit règle le problème
                '--------------------------
                If .Workbooks.Count = 1 Then .Quit Else .Close
            End With
        Else
            '-------------------------------------
            'Après le .Close, le problème persiste
            '-------------------------------------
            .Close 'Pour ouvrir le dialogue <Enregistrer / Ne pas enregistrer / Annuler>
        End If
    End With
End Sub

Pour parer ce phénomène, c'est simple si le classeur n'a pas été modifié, on fait un .Quit.
Mais s'il a été modifié, on fait un .Close, mais derrière c'est le même problème de l'écran Excel vide. Et on n'a plus la main !

Edit: je n'arrive pas à faire marcher xlDialogSaveWorkbook.
 
Dernière édition:
Toujours impossible de mettre un filtre sur:
VB:
Set fd = Application.FileDialog(msoFileDialogSaveAs)
C'est INSUPPORTABLE !

Donc retour avec ma solution du Post #5.
VB:
Sub a()
    Call WorkbookClose(ThisWorkbook)
    'Call WorkbookClose(Application.Workbooks(2))
End Sub

'----------------
'Close a Workbook
'----------------
Private Sub WorkbookClose(Workbook As Workbook)
    Dim DialogReturn As Variant
    Dim BN As Integer
   
    With Workbook
        If .Saved Then
            'OK
        Else
            BN = MsgBox("Save " & .Name & " ?", vbYesNoCancel + vbQuestion)
           
            Select Case BN
                Case vbYes
                    'New Workbook
                    If Len(.Path) = 0 Then
                        CreateObject("wscript.shell").SendKeys Workbook.Name & ".xlsx"
                        DialogReturn = Application.GetSaveAsFilename(InitialFileName:=Workbook.Path, _
                                                                     FileFilter:="All files (*.*), .*")
                        'Cancel
                        If VarType(DialogReturn) = vbBoolean Then Exit Sub
                       
                        'Full path of the file to save
                        .SaveAs DialogReturn
                   
                    'Existing Workbook
                    Else
                        .Save
                    End If
                   
                Case vbNo
                    'OK
                   
                Case vbCancel
                    Exit Sub
            End Select
        End If
    End With
       
    'Quit or Close
    With Application
        If .Workbooks.Count = 1 Then .Quit Else Workbook.Close
    End With
End Sub

Si quelqu'un a mieux...
 
re:


je ne comprends toujours pas ton problème avec ce dialog
tout du moins si ...je crois comprendre
tu pense judicieux de mettre x filtres et de mettre une extension dans le initialfilename
moi je me dis que heureusement qu' il supprime les extensions dans le initialfilename
il te simplifie la tache et toi tu veux pas ??????????????????????????????
Comment veux tu qu'il comprenne que malgré les filtres tu veux une extension ce qui est par évidence
pourquoi tu es :
pas du tout sur / pas sur /presque sur /sur mais tu sais pas / sur

en gros tu veux le choix mais tu le veux pas 🙃 🙃 🙃 🙃 🙃 🙃 🙃 🙃
 
Avec:
VB:
DialogReturn = Application.GetSaveAsFilename(InitialFileName:=Workbook.Path, _
                                                                     FileFilter:="All files (*.xlsx), .xlsx")
Comme je l'ai déjà dit, certes, il est proposé à l'utilisateur un Classeur1.xlsx et il peut changer l'extension si il veut.
Mais le filtre ne lui permet pas de voir les fichiers d'autres extensions, et s'il veut enregistrer en Classeur1.xlsm, il ne verra pas les .xlsm existants.

Le filtre c'est uniquement pour la visibilité des fichiers (*.xls*, *.csv) par exemple. On filtre la vue sur des fichiers du répertoire.
Le filtre ce n'est pas pour l'extension ou le nom du fichier proposés. Extension arbitrairement choisie quand il en trouve une sans wildcards.
Ce sont 2 choses totalement différentes confondues dans la seule notion de filtre.

En plus ce dialogue est pourri parce que c'est la 1ère partie qui fait le filtre alors que normalement ce n'est que du texte d'information.
 
re
mon classeur est un xlsm ok
testons:
VB:
Sub test()
'valide c'est normal TOUT EST COHERENT
DialogReturn = Application.GetSaveAsFilename(InitialFileName:=ThisWorkbook.Name, FileFilter:="All files (*.xlsm), *.xlsx")


'non valide c'est normal mais les xlsx aparaissent puisque le filtre est un XLSX prioritaire donc incohérent avec le type du classeur
' donc le nom est shunté
DialogReturn = Application.GetSaveAsFilename(InitialFileName:=ThisWorkbook.Name, FileFilter:="All files (*.xlsx), *.xlsm")


'ici le nom apparait et c'est normal puisque le classeur est un xlsm et que l'extension fait partie du filtre
' et les xlsx et xlsm apparaissent
DialogReturn = Application.GetSaveAsFilename(InitialFileName:=ThisWorkbook.Name, FileFilter:="All files (*.xlsx;*.xlsm), *.xlsx;*.xlsm")
End Sub

y a pas plus cohérent comme comportement
tu saisi la différence du filtre alternatif ou multiple 😉
 
Ce n'est pas cohérent.
D'abord:
VB:
FileFilter:="All files (*.xlsx;*.xlsm), *.xlsx;*.xlsm")
FileFilter:="All files (*.xlsx;*.xlsm), *.xlsx")
FileFilter:="All files (*.xlsx;*.xlsm), *.toto")
FileFilter:="All files (*.xlsx;*.xlsm), *.toto;*.titi")
FileFilter:="All files (*.xlsx;*.xlsm), MonChatGris")
C'est pareil, même affichage => donc y a des trucs à droite qui servent à rien ou on ne comprend pas à quoi ça sert (en tous cas moi).
La seule partie qui sert est supposé être du texte All files (*.xlsx;*.xlsm), elle est utilisée pour le filtre d'affichage des fichiers dont le 1er filtre non wildcards sert pour l'extension du fichier.

Ensuite:
Code:
FileFilter:="All files (*.xls*), *.xlsx")
Il est perdu car il n'affiche plus aucune extension puisque ce sont des wildcards sur la 1ère partie, la seule qui soit exploitée par la fonction.

Donc si on veut tous les fichiers de type Excel, il faut aligner TOUTES les extensions Excel possibles et mettre en premier celle qu'on veut en extension pour le fichier. Tu parles d'un système !
Déjà ça, ça plante parce qu'il y en a plus de 10 (et pourquoi 10, parce que le développeur de la fonction a 10 doigts de pied !)
Code:
Filter:="All files (*.xlsx;*.xlsm;*.xlsb;*.xltx;*.xltm;*.xls;*.xlt;*.xlm;*.xlam;*.xla;*xlw;*.xlr), *.monchatgris")
Sinon ça ça passe parce qu'il y en a 10 et ça correspond au nombre de doigts de pied du développeur qui développe avec ses pieds.
Code:
FileFilter:="All files (*.xlsx;*.xlsm;*.xlsb;*.xltx;*.xltm;*.xls;*.xlt;*.xlm;*.xlam;*.xla), *.monchatgris")
 
Dernière édition:
Alors, en conclusion de ces recherches, voici comment utiliser ce Dialog à la logique infernale.

Code:
FileFilter:="<Partie gauche>, <Partie droite>")
  1. Seule la partie gauche (avant la virgule) est utile
  2. La partie droite (après la virgule) ne sert à rien mais sa présence est obligatoire
  3. La partie gauche sert:
    • d'affichage dans la zone Type du Dialog (toute la partie gauche)
    • de filtre d'affichage des fichiers via des masques nom de fichier + extensions séparés par point-virgule (ce qui est dans la parenthèse)
    • de choix de l'extension si un nom de fichier est inclus dans le InitialFileName, correspondant à la 1ère extension mentionnée sans wildcards après le point si elle existe (ce qui est dans la parenthèse).
Exemple:
Code:
DialogReturn = Application.GetSaveAsFilename(InitialFileName:=Workbook.FullName, _
               FileFilter:="Affichage des fichiers Excel *.xls* et extension .xlsx (*.xls*;*.xlsx), Void")
 
Dernière édition:
Du coup, je peux remplacer la méthode du Post #5 par:
Code:
DialogReturn = Application.GetSaveAsFilename(InitialFileName:=Workbook.FullName, _
               FileFilter:="All files *.* (*.*;*.xlsx), Void")

Ça filtre tous les fichiers et l'extension est .xlsx est ajoutée.


Et le WorkbookClose adapté.
Code:
'----------------
'Close a Workbook
'----------------
Private Sub WorkbookClose(Workbook As Workbook)
    Dim DialogReturn As Variant
    Dim BN As Integer
  
    With Workbook
        If .Saved Then
            'OK
        Else
            BN = MsgBox("Save " & .Name & " ?", vbYesNoCancel + vbQuestion)
          
            Select Case BN
                Case vbYes
                    'New Workbook
                    If Len(.Path) = 0 Then
                        'https://excel-downloads.com/threads/vba-syntaxe-de-filefilter-en-dialog-getsaveasfilename.20087410/post-20691307
                        DialogReturn = Application.GetSaveAsFilename(InitialFileName:=Workbook.FullName, _
                                                                     FileFilter:="Excel files (*.xls*;*.xlsx), Void")
                        'Cancel
                        If VarType(DialogReturn) = vbBoolean Then Exit Sub
                      
                        'Full path of the file to save
                        .SaveAs DialogReturn
                  
                    'Existing Workbook
                    Else
                        .Save
                    End If
                  
                Case vbNo
                    'OK
                  
                Case vbCancel
                    Exit Sub
            End Select
        End If
    End With
      
    'Quit or Close
    With Application
        If .Workbooks.Count = 1 Then .Quit Else Workbook.Close
    End With
End Sub
 
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

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…