IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

VBA - Comment imbriquer plusieurs Dir ?


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Salarié
    Inscrit en
    Septembre 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Salarié

    Informations forums :
    Inscription : Septembre 2020
    Messages : 62
    Par défaut VBA - Comment imbriquer plusieurs Dir ?
    Bonjour

    Je suis bloqué avec ce code... Il me génère à chaque fois une erreur car je pense qu'il est impossible d'imbriquer plusieurs Dir mais je ne sais pas comment contourner cet obstacle...

    Code : 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
    Sub MODIFICATION()
        Dim MyFolder87, MyFolder86, MyFolder79, MyFolder17, MyFolder16 As String
        Dim MyFile87, MyFile86, MyFile79, MyFile17, MyFile16 As String
     
        MyFolder87 = "\BASE CLIENTS\87"
        MyFolder86 = "\BASE CLIENTS\86"
        MyFolder79 = "\BASE CLIENTS\79"
        MyFolder17 = "\BASE CLIENTS\17"
        MyFolder16 = "\BASE CLIENTS\16"
        MyFile87 = Dir(MyFolder87 & "\" & Range("D6").Value & "*.xlsx")
        MyFile86 = Dir(MyFolder86 & "\" & Range("D6").Value & "*.xlsx")
        MyFile79 = Dir(MyFolder79 & "\" & Range("D6").Value & "*.xlsx")
        MyFile17 = Dir(MyFolder17 & "\" & Range("D6").Value & "*.xlsx")
        MyFile16 = Dir(MyFolder16 & "\" & Range("D6").Value & "*.xlsx")
     
        If Range("D12").Value Like "87*" And MyFile87 <> "" Then
        Do While MyFile87 <> ""
        Workbooks.Open Filename:=MyFolder87 & "\" & MyFile87
        MyFile87 = Dir
        Loop
        ElseIf Range("D12").Value Like "86*" And MyFile86 <> "" Then
        Do While MyFile86 <> ""
        Workbooks.Open Filename:=MyFolder86 & "\" & MyFile86
        MyFile86 = Dir
        Loop
        ElseIf Range("D12").Value Like "79*" And MyFile79 <> "" Then
        Do While MyFile79 <> ""
        Workbooks.Open Filename:=MyFolder79 & "\" & MyFile79
        MyFile79 = Dir
        Loop
        ElseIf Range("D12").Value Like "17*" And MyFile17 <> "" Then
        Do While MyFile17 <> ""
        Workbooks.Open Filename:=MyFolder17 & "\" & MyFile17
        MyFile17 = Dir
        Loop
        ElseIf Range("D12").Value Like "16*" And MyFile16 <> "" Then
        Do While MyFile16 <> ""
        Workbooks.Open Filename:=MyFolder16 & "\" & MyFile16
        MyFile16 = Dir
        Loop
        Else
        End Sub
    End Sub
    Je dispose de plusieurs dossiers avec plusieurs fichiers Excel dans chaque dossier et j'aimerai ouvrir les fichiers avec pour nom la valeur inscrite dans la cellule D6.

    Si vous avez une idée, elle sera la bienvenue
    Merci !

  2. #2
    Expert éminent Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Par défaut
    Il y a déjà à la base une grosse erreur dans ton code.

    Lorsque tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        MyFile87 = Dir(MyFolder87 & "\" & Range("D6").Value & "*.xlsx")
    Ce n'est pas la commande "Dir" qui est placée dans la variable mais uniquement son résultat.

    Donc inutile de faire une boucle avec Do While MyFile87 <> "" puisque dans MyFile87 il y a juste le nom d'un seul fichier.

    La méthode est de faire une boucle avec un Dir et de placer tous les résultats dans une variable tableau à une dimension pour l'utiliser par la suite.

    Voici un exemple à adapter à ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        Dim MyFile87(1) As String, Cp As Long
        Cp = 1
        MyFile87(Cp)  = Dir(MyFolder87 & "\" & Range("D6").Value & "*.xlsx")
        While MyFile87(Cp) <> ""
            Cp = Cp + 1
            Redim Preserve MyFile87(Cp)
            MyFile87(Cp)  = Dir()
        Wend
    C'est du code tapé à l'arrache sur le forum, il est loin d'être optimisé et a même peut-être besoin d'être débugué.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut

    Il faut noter que Dim MyFile87(1) crée une variable tableau qui, par défaut, contient deux lignes (0 et 1) (par défaut, c'est-dire sans Option Base 1 en entête de module). La ligne 0 sera donc toujours vide

    Il faut noter également que l'on ne peut redimensionner un tableau que s'il a été déclaré avec ReDim! Le code de Menhir va donc immanquablement planter bloquer à la compilation, mais bon, il est codé "à l'arrache"...

    Enfin, on notera que MyFile87 = Dir(MyFolder87 & "\" & Range("D6").Value & "*.xlsx") et MyFile87(Cp) = Dir() ne stocke que le nom du fichier sans son chemin d'accès! D'accord (enfin, faut le dire vite), que c'est du code à l'arrache et non testé, mais comme le demandeur parle d'imbriquer des DIR (donc, à mon sens, de passer dans les niveaux d'une arborescence), ramener les noms de fichiers sans le chemin qui mène au fichier ne sert probablement pas à grand chose!


    Donc, perso, pour éviter les problèmes avec Option Base (qui est pour moi une aberration), j'utiliserais ReDim MyFile87(0 to 0) ou alors, si vraiment on veut commencer à 1: ReDim MyFile87(1 To 1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub TestDir()
      ReDim t(0 To 0)
      Dim Temp As String
     
      Temp = Dir("c:\data\temp\*.xls*")
      Do While Temp <> ""
        If IsEmpty(t(0)) Then
          t(0) = Temp
        Else
          ReDim Preserve t(0 To UBound(t) + 1)
          t(UBound(t)) = Temp
        End If
        Temp = Dir()
      Loop
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  4. #4
    Expert éminent Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Par défaut
    Citation Envoyé par Pierre Fauconnier Voir le message
    Il faut noter que Dim MyFile87(1) crée une variable tableau qui, par défaut, contient deux lignes (0 et 1) (par défaut, c'est-dire sans Option Base 1 en entête de module).
    J'oublie tout le monde n'a pas l'habitude, comme je le fais, de mettre Option Base 1 en début de tout module.

    La ligne 0 sera donc toujours vide
    D'un autre côté, je ne vois pas trop en quoi ça sera gênant...
    A part occuper inutilement une portion infinitésimale de mémoire.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par Menhir Voir le message
    [...]
    D'un autre côté, je ne vois pas trop en quoi ça sera gênant...
    A part occuper inutilement une portion infinitésimale de mémoire.
    Ce n'est pas une question de mémoire. C'est une question de rigueur dans la façon de coder.

    Si la première ligne est vide, ça veut dire que pour travailler sur les fichiers, tu dois commencer à la deuxième ligne. Une fonction qui lit les DIR en cascade a vocation à devenir générique, et il me semble inhabituel de travailler avec un tableau dont la première ligne serait systématiquement vide. Ca ne mange pas de pain de faire les choses proprement, il me semble.


    Citation Envoyé par Menhir Voir le message
    J'oublie tout le monde n'a pas l'habitude, comme je le fais, de mettre Option Base 1 en début de tout module.[...]
    Il me semble personnellement beaucoup plus "simple" de retenir que les tableaux commencent normalement à 0 (sauf dans le cas d'un transfert de plage) et de ne pas "s'amuser" à devoir mettre Option Base 1 au début de chaque module. La réutilisation de procédures "Option Base 1" dans d'autres modules n'ayant pas le Option Base 1 va être systématiquement plus ardue. Pourquoi faire simple quand on peut faire compliqué...

    Ce n'est qu'un avis personnel, mais il faudra de solides arguments techniques pour me faire changer d'opinion sur cette pratique qui ne peut qu'apporter des misères dans le code... A part "Option Explicit" qui DOIT être mis en entête de tout module, je me méfie de ces options de compilation (Option Base et Option Compare) qui rendent compliqué voire impossible la réutilisation du code dans d'autres modules. Je ne les utilise personnellement jamais.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  6. #6
    Expert éminent Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Par défaut
    Citation Envoyé par Pierre Fauconnier Voir le message
    Si la première ligne est vide, ça veut dire que pour travailler sur les fichiers, tu dois commencer à la deuxième ligne.
    Non, on commence à l'Item 1.
    Effectivement, c'est le second Item si on a la regrettable (et incompréhensible pour moi) habitude d'avoir des item 0 dans ses variables tableau mais pour l'utilisateur lambda, ça reste totalement invisible.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Non, on commence à l'Item 1.
    Si, on doit commencer à la deuxième ligne... qui est l'item 1 (d'index 1 dans le tableau).

    Et on commence à l'item 1, si on sait que l'on doit commencer à 1. Mais l'utilisateur qui ne connaît pas ta "subtilité" concernant Option Base 1 va recopier ton code dans son module puis commencer à 0. Et s'il essaie d'ouvrir le fichier repris à la ligne 0, son code plantera, forcément. Ce n'est donc pas du tout "totalement invisible" pour l'utilisateur lambda, hélas!


    C'est le problème, lorsque l'on déroge, pour de mauvaises raisons selon moi, aux fonctionnements "par défaut", et que l'on porte son code ailleurs (comme c'est le cas sur un forum) sans penser à préciser cette singularité (regrettable et incompréhensible pour moi). Si on singularise son code de cette façon, il me semble logique d'en informer les personnes avec lesquelles on le partage.


    Citation Envoyé par Menhir Voir le message
    Effectivement, c'est le second Item si on a la regrettable (et incompréhensible pour moi) habitude d'avoir des item 0 dans ses variables tableau mais pour l'utilisateur lambda, ça reste totalement invisible.
    Après, que l'on trouve cela regrettable ou pas est une appréciation personnelle. Il est incompréhensible pour moi de s'emm*** à ajouter Option Base 1 dans tous ses modules juste pour ne pas retenir qu'on commence à 0, alors que c'est habituellement le cas en informatique. Ca rend le code peu portable et peu partageable sans modifications. VBA est le seul langage que je connais qui permette de modifier la base d'un tableau par défaut. Ca oblige d'ailleurs à des contorsions lorsque l'on souhaite rendre ses codes génériques et utilisables dans plusieurs contextes (comme le Dim(0 To 0),le VBA.Array ou le for Counter = LBound(t) to UBound(t), par exemple).

    Je n'ose imaginer un travail collaboratif sur un projet si chaque programmeur commence à s'amuser avec des particularités de ce genre . Mais bon, j'ai vu tellement de code poubelle dans ma vie de programmeur que je ne me formalise plus. Par contre, je n'ai jamais vu personne d'autre généraliser le Option Base 1.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  8. #8
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Bonjour, Pierre
    Citation Envoyé par Pierre Fauconnier Voir le message
    ... Si! ReDim est une instruction de déclaration ET, en même temps, une instruction d'exécution [...] et en quelque sorte "contient" un Dim u() implicite
    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 :
    § 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.
    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.
    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.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par Patrice740 Voir le message
    [...]
    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.
    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:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Pour ma part, et notamment pour les compteurs, j'utilise souvent ceci (écriture "à la C#"):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      Dim Counter As Long
      Counter = 1
      Dim Name As String
      Dim sh As Worksheet
    ou encore comme ceci (plus souvent rencontré sur les forums et plus "puriste")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      Dim Counter As Long
      Dim Name As String
      Dim sh As Worksheet
     
      Counter = 1



    Citation Envoyé par Patrice740 Voir le message
    [...]
    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 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Sub Test()
      a = 4
      Dim a As Long
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  10. #10
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Citation Envoyé par Pierre Fauconnier Voir le message
    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 ...
    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.

    ... La ligne de déclaration ne peut pas être n'importe où.
    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ù)

  11. #11
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Bonjour Pierre,
    Citation Envoyé par Pierre Fauconnier Voir le message
    Il faut noter également que l'on ne peut redimensionner un tableau que s'il a été déclaré avec ReDim!
    Désolé, mais c'est pas tout à fait exact, EDIT ReDim n'est pas une instruction de déclaration.

    Il existe 2 types de tableaux VBA :
    - les tableaux fixes (ou statiques)
    - les tableaux dynamiques

    Les premiers sont dimensionnés lors de leur déclaration, ils ne sont pas redimensionnables :
    Dim tableau([lower To] upper [, [lower To] upper] ...) As Variant

    Les seconds ne sont pas dimensionnés lors de leur déclaration, ils sont redimensionnables :
    Dim tableau() As Variant

    L'aide VBA indique :
    L'instruction ReDim permet de dimensionner et de redimensionner un tableau dynamique ayant déjà été déclaré de manière formelle par le biais d'une instruction Private, Public ou Dim suivie de parenthèses vides (sans indices de dimension).
    EDIT : Curieusement, malgré Option Explicit, VBA accepte de redimensionner un tableau non déclaré, mais il accepte tellement de choses ...
    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.

    Pour moi, la bonne écriture serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Sub TestDir()
    Dim t()
      ReDim t(0 To 0)
      '...
    Ceci mis à part, pour éviter toutes ambigüité liée à Option Base, il suffit, comme tu l'as fait, d' utiliser systématiquement l'argument Lower dans les instructions Dim ou Redim.

  12. #12
    Membre averti
    Homme Profil pro
    Salarié
    Inscrit en
    Septembre 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Salarié

    Informations forums :
    Inscription : Septembre 2020
    Messages : 62
    Par défaut
    Bonjour

    C'est encore moi

    Est-il possible de ne pas afficher de message si le scan ne trouve aucun fichiers à ouvrir et de poursuivre la macro ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      ScanFolder T, "...", "*.xlsx", False
      For i = 0 To UBound(T)
        Workbooks.Open T(i)
      Next i
    A l'heure actuelle, un message s'affiche "Désolé... nous ne trouvons pas..." et met fin à la macro... sauf que j'aimerai que ma macro se poursuive même si aucun fichier n'a pu s'ouvrir.

    Merci !

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut JukeBox,


    Dir n'est pas nativement récursif, la spécification de l'argument réinitialise le DIR. C'est logique, puisque le DIR sans arguments a pour but de scanner en fonction du modèle passé précédemment.

    Voici une procédure qui scanne un dossier, éventuellement en cascade dans les sous-dossiers, et qui reçoit un tableau qui contiendra les noms complets des fichiers récupérés. J'y ai ajouté une procédure qui montre comment l'utiliser. Elle boucle sur les sous-dossiers si subFolders est True. Le pattern est optionnel. Par défaut, on scanne tous les fichiers. Il faut noter que cette procédure contient les limites du DIR concernant certains fichiers spéciaux.

    Code : 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
    Sub ScanFolder(Files, Root As String, Optional Pattern As String = "*.*", Optional subFolders As Boolean)
      ReDim Folders(0 To 0)
      Dim Temp As String
      Dim Counter As Long
     
      If subFolders Then
        Temp = Dir(Root & "\*.*", vbDirectory)
        Do While Temp <> vbNullString
          If (GetAttr(Root & "\" & Temp) And vbDirectory) = 16 Then
            If Temp <> "." And Temp <> ".." Then
              If IsEmpty(Folders(0)) Then
                Folders(0) = Temp
              Else
                ReDim Preserve Folders(0 To UBound(Folders) + 1)
                Folders(UBound(Folders)) = Temp
              End If
            End If
          End If
          Temp = Dir()
        Loop
      End If
     
      Temp = Dir(Root & "\" & Pattern)
      Do While Temp <> ""
        If IsEmpty(Files(0)) Then
          Files(0) = Root & "\" & Temp
        Else
          ReDim Preserve Files(0 To UBound(Files) + 1)
          Files(UBound(Files)) = Root & "\" & Temp
        End If
      Temp = Dir()
      Loop
     
      If subFolders Then
        For Counter = 0 To UBound(Folders)
          If Folders(UBound(Folders)) <> "" Then ScanFolder Files, Root & "\" & Folders(Counter), Pattern, subFolders
        Next
      End If
    End Sub
     
    Sub TestDirCascade()
      ReDim t(0 To 0)
      ScanFolder t, "c:\data\temp", "*.xls*", True
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    La procédure ScanFolders est "autonome"... Tu lui passes les arguments souhaités et elle alimente le tableau passé en premier argument avec les fichiers scannés. Elle se place donc dans n'importe quel module standard. Tu l'invoques en lui passant une variable tableau comme je l'ai illustré dans ma réponse...
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  15. #15
    Membre averti
    Homme Profil pro
    Salarié
    Inscrit en
    Septembre 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Salarié

    Informations forums :
    Inscription : Septembre 2020
    Messages : 62
    Par défaut
    Merci Pierre !

    Je vais tenter à nouveau avec ton code et je reviens te dire si j'ai réussi

    A toute à l'heure

  16. #16
    Membre averti
    Homme Profil pro
    Salarié
    Inscrit en
    Septembre 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Salarié

    Informations forums :
    Inscription : Septembre 2020
    Messages : 62
    Par défaut
    Re !

    Je tourne en bourrique....
    J'ai remplacé ta ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ScanFolder t, "c:\data\temp", "*.xls*", True
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ScanFolder t, "U:\BASE CLIENTS\87", Range("A1").Value & "*.xls*", True
    Mais je ne sais pas comment écrire le code pour que cela m'ouvre les fichiers trouvés ?

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Lister les fichiers et les ouvrir sont deux choses différentes... Si la procédure ScanFolder ouvrait également les fichiers, tu ne pourrais l'utiliser que dans le cadre précis de ton besoin actuel. Si tu voulais la réutiliser ailleurs sans ouvrir les fichiers listés, tu devrais la copier et la modifier. Or, elle a vocation d'être générique. Elle ne doit donc "faire qu'une chose", ce pourquoi elle a été écrite => scanner un dossier et éventuellement ses sous-dossiers et listés les fichiers qui s'y trouvent selon un certain "pattern" de fichier, c'est-à-dire un "modèle" de nom de fichier.

    Si tu es certain de vouloir ouvrir les fichiers récupérés par ScanFolder, tu boucles sur le tableau récupéré avec ceci...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub OpenFiles()
      ReDim T(0 To 0)
      Dim i As Long
     
      ScanFolder T, "...", "*.xlsx", False
      For i = 0 To UBound(T)
        Workbooks.Open T(i)
      Next i
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  18. #18
    Membre averti
    Homme Profil pro
    Salarié
    Inscrit en
    Septembre 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Salarié

    Informations forums :
    Inscription : Septembre 2020
    Messages : 62
    Par défaut
    Merci infiniment Pierre

    Je viens de tester ton code en rajoutant mes conditions suivant la cellule D12 et tout fonctionne parfaitement C'est magique !
    Et je trouve que ta solution soulage la macro disons qu'il y a beaucoup moins de lignes à taper c'est plus clair ^^

    Merci encore pour ta patience et ton aide Cela fait plaisir de voir encore des personnes comme toi sur la toile
    Je te souhaite une bonne continuation.


  19. #19
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Tu peux tester que t(0) est vide ou pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  20. #20
    Membre averti
    Homme Profil pro
    Salarié
    Inscrit en
    Septembre 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Salarié

    Informations forums :
    Inscription : Septembre 2020
    Messages : 62
    Par défaut
    Merci une fois de plus Pierre

    J'essaierai ton code lundi et je reviendrai faire un retour !

    Bon weekend à toutes et à tous

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/04/2007, 23h30
  2. [VBA-E] comment selectionner plusieurs lignes
    Par Annick.w dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/01/2007, 20h15
  3. Réponses: 7
    Dernier message: 15/12/2006, 16h14
  4. comment imbriquer plusieurs evenements
    Par nazimb dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 05/07/2006, 14h57
  5. excel VBA comment recopier sur plusieurs feuilles
    Par floflo2006 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 26/11/2005, 15h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo