SÉLECTEUR DE FICHIERS EN VBA, AVEC OBJET STANDARD OFFICE (FILEDIALOGS)

guillaume_00 Messages postés 18 Date d'inscription dimanche 19 septembre 2004 Statut Membre Dernière intervention 19 mars 2009 - 10 oct. 2008 à 22:17
cs_inforom Messages postés 36 Date d'inscription mercredi 8 octobre 2008 Statut Membre Dernière intervention 12 avril 2017 - 25 oct. 2008 à 09:29
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/48152-selecteur-de-fichiers-en-vba-avec-objet-standard-office-filedialogs

cs_inforom Messages postés 36 Date d'inscription mercredi 8 octobre 2008 Statut Membre Dernière intervention 12 avril 2017
25 oct. 2008 à 09:29
Bien.. bonjour à vous tous....
Je rentre de déplacement et tombe sur cette critique... Je ne vais pas en rajouter, mais je réponds quand même, bien que cela me paraisse un peu déplacé ici. Il vaudrait mmieux des messages personnels plutôt que d'emcombrer les commentaires qui doivent éclairer les lecteurs sur le contenu plutot que sur les auteurs...

L'utilisation des paramètres optionnels, la recherche des chemins par défaut de l'environnement, me paraissent des ajouts intéressants pour les lecteurs à la recherche de solutions efficaces...

Quant à la forme et à l'écriture... chacun a ses petites manies: en ce qui me concerne je déclare explicitement les variables qui ont une signification et une durée de vie définie dans le code. Le With.. End With ne sert qu'à gagner du temps pour l'écriture.. ne change rien à la performance. Le fait de répéter FD me paraît plus lisible. On pourrait aussi ne pas avoir de FD et écrire:
With Application.FileDialogs(...
...
End With
mais à mon avis cela n'améliorerait pas la lecture.

Bon la principale question à mon avis c'est celle qui concerne le niveau annoncé.

Je ne suis sur le site que depuis peu, et c'est ma première contribution. J'ai choisi le niveau 'initié' en m'inspirant des sources que j'ai vus, et en pensant plus au niveau de ceux qui se posent la question qu' au niveau de sophistication du code.

A savoir: un débutant, à mon avis, cherche d'abord à exploiter les fonctions du langage lui-même et celles qui sont documentées dans les bouquins de VB. Son expérimentation s'attache surtout à la manière dont on écrit ceci ou cela, alors que dans le cas présent il ne s'agit pas de ça: il faut envisager l'utilisation d'objets qui sont au niveau de l'application et ne se trouvent pas dans le document auquel est attaché le code.

Ceci dit j'accepte volontiers tes excuses, BigFish, et j'essaierai d'être plus rigoureux à l'avenir dans les sources proposés, ne serait-ce que pour ne pas provoquer ce type de réaction.

Je termine malgré tout en rajoutant mes remerciements envers EREN, qui a pris ma défense, et en rajoutant pour information que malgré les imperfections soulevées je me considère en fait comme un 'professionnel', puisque c'est mon métier depuis 1972 et que je continue à laisser des logiciels en exploitation dans des entreprises...

A mon avis cela n'a pas d'importance. Ce qui m'intéresse sur ce site c'est justement qu'il essaie de rassembler les idées et les expériences dans un esprit de partage et de collaboration, et non pas de compétition...
cs_eren Messages postés 38 Date d'inscription vendredi 3 janvier 2003 Statut Membre Dernière intervention 27 novembre 2008
24 oct. 2008 à 07:33
Bonjour,
Message pour BigFish_le vrai

Tu réponds au message d'Eren (le mien) en me parlant comme si j'étais l'auteur du programme que tu as commenté 23/10/2008 21:51:16.
Pas du tout, j'ai simplement été intéressé par ce programme et je me suis abonnée aux commentaires.
Par mes propos, j'ai simplement voulu prendre la défense de l'auteur de ce programme et c'est tout.
Salutations
Eric
bigfish_le vrai Messages postés 1835 Date d'inscription vendredi 13 mai 2005 Statut Membre Dernière intervention 20 novembre 2013 15
24 oct. 2008 à 00:51
Je ne pensais pas avoir ete aussi dur avec toi... mise a par peut etre avec cette remarque:

Je ne vois pas pourquoi cette source est d'un niveau initié !?!

ou peut etre est-ce l'ensemble en tout cas, apparemment, j'ai ete trop loin avec ces remarques. Je les pensais objectives et pas blessantes mais aux vues de ton message ca n’a pas l'air d'etre le cas et j'en suis desole. Crois bien que ce n'etait pas mon intention. Blesser ou de rabaisser quelqu'un ne m'apporte aucune satisfaction personnel bien au contraire.

Il est vrai que j'ai ete surpris par le contenu de ta source alors que je m'attendais a quelque chose de plus strict du fait du niveau annonce, ce qui effectivement ma amené a écrire ces remarques que je n'aurais pas faites si tu avais annoncé un niveau debutant.

Rester humble serte mais cela vaut aussi pour celles et ceux qui choisissent le niveau au moment de la publication de la source. Publier une source c'est prendre le risque de recevoir des remarques deplaisantes. Et c'est bien pour cela qu'il est important de faire attention a ce que l'on ecrit et aux options que l'on choisis sous peine de deception voir de colere comme cela a l'air d'etre le cas pour toi.

Je n’ai pas la pretention d'etre au niveau initie meme si j'essais de l'atteindre sans en faire un objectif en sois.
Il est vrai que j'ai commencé la programmation il y a longtemps (22ans deja sur un C64) et de fait j'ai peut etre tendance a chercher la perfection. Malgre tout je ne suis pas programmeur et ne travail pas dans ce domaine ni meme dans un domaine qui touche de pres ou de loin l'informatique et tout ce qui en decoule. Je ne suis qu’un amateur passione tu l’es surement

Encore une fois je suis desolé et espere que tu ne puniras pas ce site, qui n'y ai pour rien, par ton absence.

Cordialement

Philippe

Ps mon pseudo est BigFish_le vrai
cs_eren Messages postés 38 Date d'inscription vendredi 3 janvier 2003 Statut Membre Dernière intervention 27 novembre 2008
23 oct. 2008 à 23:24
Bonjour,
Message à BigFisk_LeVrai
Je n'apprécie pas les gens comme toi qui se prennent pour des cadors et qui prennent de haut ceux qui proposent du code même s'il y a des imperfections (les amateurs ça existent encore).
Avec des gens comme toi BigFisk_LeVrai tu décourages des amateurs comme moi à qui il est arrivé de publier du code avec certainement des imperfections (voire beaucoup).
J'ai 60 ans et auto-didacte et je respecte ceux qui mettent aux services des autres leurs connaissances ou code même s'il y a des imperfections.
Tu n'as pas la manière d'apporter des remarques et même si tu es (peut-être) un très bon programmeur, il faut être humble et penses à ceux que tu peux vexer et éloigner de ce forum très intéressant.
C'est un lieu où tout le monde doit s'exprimer en toute liberté et ne pas subir la vindinct de programmeurs (peut-être chevronnés) qui veulent faire apporter leurs remarques (parfois utiles) mais qui n'en n'ont pas la manière de le faire.
bigfish_le vrai Messages postés 1835 Date d'inscription vendredi 13 mai 2005 Statut Membre Dernière intervention 20 novembre 2013 15
23 oct. 2008 à 21:51
Salut,

Je ne vois pas pourquoi cette source est d'un niveau initié !?!

- l'utilisation d'un with dans la fonction aurait ete plus propre.
- l'utilisation d'option explicit en debut de module serait plus serieux et montrerait l'exemple. Ce qui t'aurais evite d'oublier de declarer les variables i et p
- ta fonction est sensee renvoyer un string elle pourrait etre elle aussi dimensionnée pour optimiser la memoire.
- Enfin pour etre une bonne fonction a mon avis cette fonction devrait proposer tout les parametres en option.

Option Explicit
Public Function ListeFichiers(Optional Chemin As String, Optional Titre As String, Optional Filtre As String, Optional Multi As Boolean) As String
Dim tf As Variant ' tf est la variable dans laquelle on va créer le tableau des filtres demandés
Dim nflt As Integer ' nombre de filtres
Dim res As String ' chaine à retourner
Dim i As Long, p As String, TestDir As String

' cette fonction ouvre un sélecteur de fichiers et retourne le résultat dans une liste
' (chaine constituée par les noms de fichiers séparés par des tabulations)

' Chemin est le chemin de départ de l'exploration (si c'est une fichier, il est positionné par défaut
' Titre est le titre de la fenêtre
' Filtre est le filtre pour les noms ou extensions (on peut en définir plusieurs)
' Multi indique si on veut une sélection MULTIPLE


' déclare un objet pour la boite de dialogue que l'on va manipuler
' Une fois créée la boite de dialogue, on la paramètre par ses différentes propriétés
' puis on l'active (avec la méthode show)
' on récupère ensuite le résultat dans la collection SelectedItems() (en cas de séections multiples)

Dim FD As FileDialog

' Création de la boite. L'argument indique qu'il s'agit d'une sélecteur de fichiers
' on pourrait aussi avoir: ouverture, SaveAs, sélecteur de répertoires
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
' paramètres
TestDir = Dir(Chemin, vbDirectory)
If Not TestDir = "" Then
.InitialFileName = Chemin
Else
'on recupere le chemin du dossier "mes documents" Windows XP
Chemin = MyRegGetValue("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Persona")
.InitialFileName = Chemin
End If If Not Titre "" Then .Title Titre If Multi True Then .AllowMultiSelect True

' Filtres
' La méthode normale consiste à créer une instance de DialogFilter pour chaque filtre
' Un filtre contient:
' une description: texte affiché dans la liste
' une ou plusieurs extensions, séparées par des point-virgules
' l'argument d'appel est une chaine contenant la liste des filtres, séparés par des CHR(13)
' chaque filtre étant composé de deux chaines (description + TAB + extensions)
' si la chaine est vide on aura les types de fichiers par défaut

nflt = 0
If Filtre <> "" Then
tf = Split(Filtre, Chr(13))
nflt = UBound(tf) + 1 ' split crée un tableau base 0
' effacement des filtres par défaut
.Filters.Clear
End If

For i = 1 To nflt
' découpage du filtre sur TAB
p = InStr(tf(i - 1), Chr(9))
If p > 0 Then
' création du filtre
.Filters.Add Description:=Left(tf(i - 1), p), Extensions:=Mid(tf(i - 1), p + 1)
Else
' le filtre est mal paramétré (pas de tabulation trouvée)
End If
Next

' ouverture du sélecteur
' *****************************
' la méthode Show retourne une valeur indiquant l'action de l'utilisateur, que l'on peut tester,
' mais nous nous contentons de voir si des résultats sont donnés
.Show

' on obtient les noms des fichiers sélectionnés dans la collection SelectedItems
' et on construit la chaine retournée (noms de fichiers séparés par des tabulations)
res = ""
For i = 1 To .SelectedItems.Count
If res <> "" Then res = res & Chr(9)
res = res + .SelectedItems(i)
Next
End With
Set FD = Nothing
ListeFichiers = res

End Function
Function MyRegGetValue(MaCle As String) As String 'permet de recuperer le contenu d'une cle de registre
Dim WshShell As Object
Set WshShell = CreateObject("WScript.Shell")
On Local Error Resume Next
MyRegGetValue = WshShell.RegRead(MaCle) If Not Err 0 Then MyRegGetValue ""
Set WshShell = Nothing
End Function

Voila maintenant ta fonction peut etre utilisee sans parametre comme ceci:

MesFichiers = ListeFichiers()

A+ :)
guillaume_00 Messages postés 18 Date d'inscription dimanche 19 septembre 2004 Statut Membre Dernière intervention 19 mars 2009
14 oct. 2008 à 09:29
Bonjour,
De toute façon ce qui compte c'est le résultat : afficher une boite de dialogue pour sélectionner un ou plusieurs fichier :o). Il y a souvent plusieurs moyens d'arriver au même résultat. Il est vrai qu'en VBA il est plus simple d'utiliser les boites de dialogue de Word/Excel (car on peut utiliser les proprietés de l'objet tout ca tout ca ;o) ). Je te donnais juste cette info pour info (la culture perso tout ca tout ca :o) ).
Voila

Bonne journée à tous
cs_eren Messages postés 38 Date d'inscription vendredi 3 janvier 2003 Statut Membre Dernière intervention 27 novembre 2008
13 oct. 2008 à 22:06
Bonjour Inforom,
Allez on est sympa, faute avouée, faute pardonnée.
C'est vrai que je n'avais trop compris pour l'API mais
l'essentiel c'est que ton programme soit par le Userform ou par l'appel de la fonction, fonctionne parfaitement.
Encore merci

A+
cs_inforom Messages postés 36 Date d'inscription mercredi 8 octobre 2008 Statut Membre Dernière intervention 12 avril 2017
13 oct. 2008 à 19:12
OOOOUUUUPPS! et en plus dans la réponse à EREN, j'ai parlé des API alors qu'il n'en n'est pas du tout question dans ce propos...

Putaing! il faut pas négliger de se relire, ou alors rester à jeun !!!
cs_inforom Messages postés 36 Date d'inscription mercredi 8 octobre 2008 Statut Membre Dernière intervention 12 avril 2017
13 oct. 2008 à 19:09
Juste pour confirmer, à l'attention de GUILLAUME_00..

Effectivement, en recherchant dans l'aidse en ligne, je vois que GetOpenFileName comporte les arguments permettant de spécifier tout ce qu'il faut... Dont Acte...
Je ne sais pas ce qui m'avait fait penser le contraire... y a des fois où on est mal réveillé...

Ceci dit c'est la lecture d'un billet présentant une procédure entièrement programmée qui m'a donné envie d'écrire ce source présentant l'utilisation des FileDialogs. Par ailleurs, la convention de GetOpenFileName ne permet pas d'inclure virgules ou point-virgules dans les descriptions...

J'aime bien utiliser les TAB et RC.. un reste de WINDEV, certainement...
cs_eren Messages postés 38 Date d'inscription vendredi 3 janvier 2003 Statut Membre Dernière intervention 27 novembre 2008
13 oct. 2008 à 13:49
Bonjour,

J'avais réussi à trouver avec une seule extensiosn (en faisant du pas à pas sous VBA)mais avec ton exemple j'ai pu adapter avec 2 extensions.
Merci
cs_inforom Messages postés 36 Date d'inscription mercredi 8 octobre 2008 Statut Membre Dernière intervention 12 avril 2017
13 oct. 2008 à 13:01
Bonjour,
A priori j'ai écrit fonction pour montrer comment effectuer l'appel de l'API, et non pas pour fournir un exécutable... dans un cas pratique, tu aurais plutot intérêt à écrire toi même le code:
Dim FD As FileDialog
Set FD = Application.FileDialog(msoFileDialogFilePicker)
FD.InitialFileName = "C:\Excel"
FD.Title = "Ouverture"
FD.AllowMultiSelect = True
FD.Filters.Add Description:="Fichiers Excel", Extensions:="*.xls"
FD.show...

Mais, si tu veux utiliser la fonction, il faut passer en argument une suite de filtres de la forme description & CHAR(9) & extensions [ & chr(13) & ...]

FileOpen=Listefichiers("C:\Excel","Ouverture","Fichiers Excel" & chr(9) & "*.xls" , True)..

ou, si tu utilises mon UserForm, saisir dans l'extension: '*.xls'...

J'espère avoir répondu ...


FD.show
cs_eren Messages postés 38 Date d'inscription vendredi 3 janvier 2003 Statut Membre Dernière intervention 27 novembre 2008
13 oct. 2008 à 09:13
Bonjour,

Je passe le paramètre de la manière suivante
FileOpen = ListeFichiers("c:\excel", "Ouverture", "Fichiers Excel (*.xls)", True)
et ce paramètre n'est pas reconnu.
Quelle est la syntaxe exacte ,
guillaume_00 Messages postés 18 Date d'inscription dimanche 19 septembre 2004 Statut Membre Dernière intervention 19 mars 2009
10 oct. 2008 à 22:17
Juste pour information: il est tout a fais possible filtrer et de définir un fichier par défaut avec GetOpenFileName (cf MSDN :o) ).
++
Rejoignez-nous