Dure dure, la vie de programmeur
par
, 24/02/2021 à 20h27 (2204 Affichages)
Salut
Dans une discussion sur la possibilité de créer des dossiers et sous-dossiers sur base d'une "liste" dans Excel, je suis tombé sur la réponse suivante:
Code vba : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 Sub MakeFolder() 'Voici une procédure et 2 fonctions. 'La procédure crée le répertoire via 2 fonctions qui vérifient l'existence ou créent ce répertoire. 'Il faut activer la librairie "Microsoft Scripting Runtime" pour que ça marche Dim Parent As String, SousDossier As String, Chemin As String Parent = ThisWorkbook.Sheets("Sheet3").Range("A5") ' si le dossier parent se trouve en A5 SousDossier = ThisWorkbook.Sheets("Sheet3").Range("B5") ' si le sous-dossier se trouve en B5 Chemin = ThisWorkbook.path & "\" 'créer le dossier sous le même répertoire que le fichier ouvert MsgBox Chemin & Parent & "\" & SousDossier If Not FolderExists(Chemin & Parent) Then 'créer le parent s'il n'existe pas FolderCreate Chemin & Parent & "\" Else 'créer le sous-dossier s'il n'existe pas If Not FolderExists(Chemin & Parent & "\" & SousDossier) Then FolderCreate Chemin & Parent & "\" & SousDossier End If End If End Sub Function FolderCreate(ByVal path As String) As Boolean FolderCreate = True Dim fso As New FileSystemObject If fso.FolderExists(path) Then Exit Function Else On Error GoTo Avertissament fso.CreateFolder path ' source d'erreur si le nom ne convient pas !! Exit Function End If Avertissament: MsgBox "A folder could not be created for the following path: " & path & ". Check the path name and try again." FolderCreate = False Exit Function End Function Function FolderExists(ByVal path As String) As Boolean FolderExists = False Dim fso As New FileSystemObject If fso.FolderExists(path) Then FolderExists = True End Function
J'ai failli mourir, rendre mon déjeuner par en haut et par en bas, puis défaillir (oui, oui, dans cet ordre)...
Pourquoi j'aime pas!!
Qu'est-ce qui ne va pas dans ce code?
1. On utilise un brol alors que les fonctions natives de VBA permettent de réaliser cela sans soucis. Quel brol? FSO (l'objet FileSystemObject de la bibliothèque Scripting). Dir() permet de tester l'existence d'un fichier ou d'un dossier, MkDir permet de créer un dossier. Pourquoi s'encombrer d'une bibliothèque externe? De surcroît, pourquoi s'en encombrer deux fois (une fois dans chaque fonction)?
2. La fonction FolderExists est inutile, en tant que telle. Ok, grâce au fait qu'elle utilise son propre FileSystemObject, elle est indépendante de la procédure appelante. Mais il est raisonnable que quelqu'un qui utilise une fonction testant l'existence d'un dossier va probablement vouloir utiliser d'autres propriétés ou méthodes du FSO dans le code appelant, et disposera donc d'un objet FSO. Pourquoi appeler une fonction d'une seule ligne lorsque l'objet qui répond est instancié (ou devrait l'être) dans le code appelant et donne la réponse en une ligne? Ca n'a pas de sens, ce truc. Un simple Dir(FolderName, vbDirectory) répond lui aussi en une ligne.
3. Deux Exit Function dans la même fonction. Déjà un Exit Function, c'est, mais alors 2, c'est
![]()
! Dans la fonction FolderCreate, on part du principe que la création a pu avoir lieu. C'est assez étonnant mais pourquoi pas. Si le dossier existe, on sort de la avec une fonction FolderCreate en renvoyant True ( => j'ai créé le fichier, selon ma compréhension du nom de la fonction) alors que la fonction n'a rien créé du tout. Ca me laisse perplexe. Si le dossier n'existe pas, on tente de le créer, et de nouveau, on sort avec un Exit Function, mais cette fois, si on a pu créé le dossier. et on met une gestion d'erreur si la création du dossier a posé problème.
4. En cas de problème lors de la création, on affiche un msgbox pour avertir l'utilisateur. Il faudra encore souvent taper sur le clou pour faire comprendre l'architecture "trois-tiers", ou à tout le moins le fait qu'une fonction ne peut avoir qu'une seule responsabilité: soit tenter de créer un dossier, soit informer l'utilisateur du résultat de cette tentative, mais pas les deux. Ici, si on utilise cette fonction en boucle (ce qui était le cas de la demande), on va se prendre le message bloquant autant de fois qu'on n'a pas pu créé de dossiers...La fonction doit renvoyer une valeur qui informera le code appelant (pas l'utilisateur!!!) du résultat. Par exemple: 0 => ok, j'ai pu créé; 1 => Le dossier n'a pas pu être créé; 2 => Le dossier existait déjà. Ainsi, le code appelant peut travailler en boucle et traiter les cas sans emm*** l'utilisateur par des messages intempestifs.
VBA a mauvaise presse. Mais c'est bien plus par la médiocrité des solutions proposées sur différents forums que par les défauts intrinsèques du langage qui, s'ils peuvent énerver, n'arrivent pas à masquer que, dans l'ensemble, VB(A) est un langage professionnel, bien pensé, et qu'il permet, comme tout langage, de faire de la belle ouvrage... ou de la merde.