Tu peux tester que t(0) est vide ou pas...
Code:
1
2
3
4
5
6
7
8
9
10 Sub Test() ReDim t(0 To 0) ScanFolder t, "c:\data", "*.mdf", True If Not IsEmpty(t(0)) Then ' Ton code Else ' On continue la macro sans ouvrir de fichier End If End Sub
Version imprimable
Tu peux tester que t(0) est vide ou pas...
Code:
1
2
3
4
5
6
7
8
9
10 Sub Test() ReDim t(0 To 0) ScanFolder t, "c:\data", "*.mdf", True If Not IsEmpty(t(0)) Then ' Ton code Else ' On continue la macro sans ouvrir de fichier End If End Sub
Merci une fois de plus Pierre :)
J'essaierai ton code lundi et je reviendrai faire un retour !
Bon weekend à toutes et à tous ;)
Bonjour Patrice,
Je suis d'accord avec la première partie de ta réponse, mais pas avec la seconde.
Ce n'est pas tout à fait exact: Tu as raison, on peut utiliser Redim sur un Dim, mais uniquement à la condition que le Dim concerne un tableau sans dimension, éventuellement typé, ou un variant.
Code:
1
2
3
4
5
6 Sub Test() Dim t ' Dim u() ReDim t(5) ReDim u(5) End Sub
ReDim n'est pas une instruction de déclaration: Si! ReDim est une instruction de déclaration ET, en même temps, une instruction d'exécution. Si l'on observe l'image suivante, on verra que les variables t et u existent dès l'entrée dans la fonction et sont déclarées de manière identique comme des tableaux de variant, alors même que dim u() est inexistant. C'est la preuve que Redim u(5) a bien déclaré la variable et en quelque sorte "contient" un Dim u() implicite. Redim est donc bien une instruction de déclaration.
Pièce jointe 580148
Elle est, en plus, une instruction d'exécution qui modifiera les dimensions de u au moment de l'exécution de la ligne Redim...
Pièce jointe 580149
On notera également que, si l'on peut redimensionner un tableau sans le retyper (il garde le type du dim de départ), on ne peut pas modifier le type du tableau lors du redimensionnement lorsqu'il est déclaré comme un tableau par un Dim ( par exemple, Dim t() ).
Pièce jointe 580158
Pièce jointe 580159
Pour pouvoir modifier à volonté le type du tableau lors du redimensionnement, il faut qu'il ait été déclaré comme Variant
Pièce jointe 580160
Bonjour, Pierre
Mea Culpa, tu as effectivement raison pour être précis :
A l'intérieur d'un procédure ou d'une fonction, Redim sert aussi de déclaration d'une variable tableau redimensionnable (tableau dynamique) de portée locale quand cette variable n'a pas été déclarée préalablement.
C'est confirmé par les Spécifications du langage VBA : [MS-VBAL] ReDim :
Pour ma ma part, je préfère déclarer et typer les variables dans la zone de déclaration plutôt que dans la zone d'exécution.Citation:
§ If the name has no matches, then the <redim-statement> is instead interpreted as a <local-variable-declaration> with a <variable-declaration-list> declaring a resizable array with the specified name and the following rules do not apply.
§ Otherwise, if the name has a match, this match is the redimensioned variable.
Je place toujours les déclarations avant l'exécution puisque, comme tu le démontre, quelle que soit la position de la déclaration dans les lignes de code, les variables sont toutes déclarées dès le début de l'exécution de la procédure, avant d'exécuter la première instruction d'exécution.
Je comprends bien ce que tu veux dire, mais techniquement, il n'y a pas de zone de déclaration et de zone d'exécution. C'est une convention de codage qui fait que généralement, on déclare les variables en début de procédure, mais ce n'est nullement une obligation. D'autres langages, comme le C# par exemple, permettent de déclarer les variables au moment de leur première utilisation, et cela permet un code plus concis et néanmoins très lisible. On pourrait donc, techniquement, avoir le code suivant, qui montre bien que déclaration et exécution se mêlent et que les notions "zone de déclaration" et "zone d'exécution" sont des vues de l'esprit, même si je trouve que ce n'est pas très lisible de coder ainsi:
Pour ma part, et notamment pour les compteurs, j'utilise souvent ceci (écriture "à la C#"):Code:
1
2
3
4
5
6
7
8
9 Sub Test() Dim a As String a = InputBox("Votre prénom svp") Dim b As String b = InputBox("votre nom svp") Dim c As String c = a & " " & b MsgBox "Vous vous appelez " & c End Sub
Ce qui revient à mélanger les lignes de déclaration et d'éxécution et pourrait s'écrire comme ceci (perso, je n'aime pas):Code:
1
2
3
4
5
6
7
8
9
10
11
12 Sub Test() Dim Counter As Long: Counter = 1 Dim Name As String Dim sh As Worksheet Name = "shParameters" Do While Counter <= ActiveWorkbook.Worksheets.Count And sh Is Nothing If ActiveWorkbook.Worksheets(Counter).CodeName = Name Then Set sh = ActiveWorkbook.Worksheets(Counter) Counter = Counter + 1 Loop Debug.Print sh.Name End Sub
ou encore comme ceci (plus souvent rencontré sur les forums et plus "puriste")Code:
1
2
3
4 Dim Counter As Long Counter = 1 Dim Name As String Dim sh As Worksheet
Code:
1
2
3
4
5 Dim Counter As Long Dim Name As String Dim sh As Worksheet Counter = 1
Je n'ai pas dit ça (ce qui est en gras) ;). Dans le cas du Redim utilisé seul, la ligne de déclaration implicite Dim t() précède la ligne d'exécution Redim, comme le montre l'illustration dans ma réponse précédente. La ligne de déclaration ne peut pas être n'importe où. Elle doit obligatoirement précéder la ligne d'exécution qui utilise la variable. Ainsi, le code suivant plantera dès la compilation car la variable est déclarée après son utilisation:
Code:
1
2
3
4 Sub Test() a = 4 Dim a As Long End Sub
Bien sûr, mais à la différence d'autres langages, le compilateur VBA effectue toutes les déclarations avant la première exécution, ce qui revient à placer toutes les déclarations avant la première exécution.
Souvent certains écrivent des codes comme ton premier exemple en pensant économiser la mémoire utilisée par la déclaration.
Je n'ai pas dit ça ;). Tes codes, dont je parle, sont compilés, ils ne présentent pas d'erreur de compilation. (quelle que soit la position, ne veux pas dire n'importe où)Citation:
... La ligne de déclaration ne peut pas être n'importe où.
Bonjour,
Je reviens sur ce sujet car j'ai un petit problème avec la fonction de Pierre Fauconnier, je l'utilise dans une macro sur plusieurs valeurs mais lorsque ça passe sur le deuxième nom j'ai un message d'erreur comme quoi le classeur n'existe pas car en effet il garde en mémoire la première valeur pour le nom du fichier...
Je pense que c'est histoire de réinitialisation de variable ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 ReDim T(0 To 0) Dim I as Long Dim Y as Long For Y = 1 To 10 ScanFolder T, "C:\TEST", Workbooks("TEST").Sheets("TEST").Cells(Y, 8).Value & " " & "*.xls*", False If Not IsEmpty(T(0)) Then For I = 0 To UBound(T) Workbooks.Open T(I) nomclasseur = ActiveWorkbook.Name Classeur = Application.ActiveWorkbook.FullName ActiveWorkbook.Close Kill Classeur Next I End If Next Y
Merci du coup de main ^^
Salut JukeBox,
es-tu sûr de ton Pattern au niveau des variables de la subTu devrait mettre un point d'arrêt (Touche F9) sur la ligne 9 et voir ce que contient T(I) tu sélectionnes T(I) et ensuite touche Shift + F9.Code:ScanFolder T, "C:\TEST", Workbooks("TEST").Sheets("TEST").Cells(Y, 8).Value & " " & "*.xls*", False