J'ai essayé de créer une classe pour rechercher des fichiers avec la méthode Glob de Python dans VBA

Objectif

Lors de la recherche de dossiers et de fichiers avec VBA, le processus de recherche dans les sous-dossiers devient compliqué, donc J'ai créé un module de classe en référence à Glob de Python.

Code source

Cas d'utilisation VBA

Module1.bas


Sub GlobTest()
    Dim item As Variant
    With New Glob
        .SetType = Dictionary 'Facultatif Pour spécifier le format de sortie
        For Each item In .iGlob("**\*.cls")
            Debug.Print item
        Next
    End With
End Sub

Méthode

Nom Valeur de retour
iGlob(chemin) Résultats de la recherche de dossier / fichier(Format de sortie variable)
Glob(chemin) Résultats de la recherche de dossier / fichier(Format du dictionnaire)
GlobFolder(chemin) Résultats de recherche de dossier uniquement(Format du dictionnaire)

Propriété

Nom valeur
SetType Format de sortie
GetType Format de sortie
GetCount Nombre de correspondances dans la recherche
GetItems Identique à la valeur de retour d'iGlob

Type de format de sortie

Nom format
Dictionary String()
Collection File(),Folder()
ArrayList String()
StringArray String()

Conditions de recherche

La description Résultat de sortie
\*\ Énumérer les dossiers dans le même chemin
\* Énumérer les fichiers dans le même chemin
\*.cls Énumérer les fichiers avec l'extension cls dans le même chemin
\*\* Énumérer les fichiers dans les sous-dossiers
\{*}\* Énumérer les fichiers dans le même chemin et sous-dossiers
\**\* Rechercher récursivement pour lister les fichiers dans toutes les hiérarchies

Exemple de code de référence Python

import glob
for x in glob.glob('**/*.cls', recursive=True):
    print x

Corps du module de classe

Glob.cls


Private DefPath As String
Private Items As Variant
Private FSO As Object

Enum GlobDataType
    None = 0
    StringArray = 1
    ArrayList = 2
    dictionary = 3
    Collection = 4
End Enum

Private Sub Class_Initialize()
    Set FSO = CreateObject("Scripting.FileSystemObject")
    With CreateObject("WScript.Shell")
        .CurrentDirectory = ThisWorkbook.path & "\"
    End With
    Me.Clear
End Sub

Private Sub Class_Terminate()
    Set Items = Nothing
    Set FSO = Nothing
End Sub

Public Sub Clear()

    DefPath = ThisWorkbook.path & "\"
    count = 0
    Select Case Me.GetType
    Case GlobDataType.dictionary
        Me.SetType = dictionary
    Case GlobDataType.Collection
        Me.SetType = Collection
    Case GlobDataType.StringArray
        Me.SetType = StringArray
    Case GlobDataType.ArrayList
        Me.SetType = ArrayList
    Case Else
        Me.SetType = Collection
    End Select

End Sub

Public Function GetItems() As Variant
    Select Case Me.GetType
    Case GlobDataType.dictionary, GlobDataType.Collection, GlobDataType.ArrayList
        Set GetItems = Items
    Case GlobDataType.StringArray
        GetItems = Split(Items, "||")
    Case Else
        GetItems = Array()
    End Select
End Function

Public Function GetCount() As Long
    Select Case Me.GetType
    Case GlobDataType.dictionary, GlobDataType.Collection, GlobDataType.ArrayList
        GetCount = Items.count
    Case GlobDataType.StringArray
        If Items = "" Then
            GetCount = 0
        Else
            GetCount = UBound(Split(Items, "||")) + 1
        End If
    Case Else
        GetCount = -1
    End Select
End Function

Public Sub AddItem(ByVal name As String, ByVal v As Variant)
    Select Case Me.GetType
    Case GlobDataType.dictionary
        Items.Add name, v
    Case GlobDataType.Collection
        Items.Add v, name
    Case GlobDataType.ArrayList
        Items.Add v
    Case GlobDataType.StringArray
        If Items <> "" Then Items = Items & "||"
        Items = Items & v
    End Select
End Sub

Public Property Get GetType() As GlobDataType
    Select Case Me.GetTypeName
    Case "Collection"
        GetType = GlobDataType.Collection
    Case "Dictionary"
        GetType = GlobDataType.dictionary
    Case "String"
        GetType = GlobDataType.StringArray
    Case "ArrayList"
        GetType = GlobDataType.ArrayList
    Case Else
        GetType = GlobDataType.None
    End Select
End Property

Public Property Let SetType(ByVal TypeName As GlobDataType)
    Select Case TypeName
    Case GlobDataType.Collection
        Set Items = Nothing
        Set Items = New Collection
    Case GlobDataType.dictionary
        Set Items = Nothing
        Set Items = CreateObject("scripting.dictionary")
    Case GlobDataType.StringArray
        Items = ""
    Case GlobDataType.ArrayList
        Set Items = Nothing
        Set Items = CreateObject("System.Collections.ArrayList")
    Case Else
        Set Items = Nothing
        Set Items = CreateObject("scripting.dictionary")
    End Select
End Property

Public Function GetTypeName() As String
    GetTypeName = TypeName(Items)
End Function


Private Function base(ByRef url As String, Optional ByRef key As String = "") As String
    Dim baseUrl As String
    Dim min As Long
    Dim keystr As String
    
    If Left$(url, 2) <> "\\" And Left$(url, 1) = "\" Then url = Mid$(url, 2, Len(url) - 1)
    
    If url <> "" Then
        min = 2000
        If InStr(url, "?") And min > InStr(url, "?") Then min = InStr(url, "?")
        If InStr(url, "*") And min > InStr(url, "*") Then min = InStr(url, "*")
        If InStr(url, "[") And min > InStr(url, "[") Then min = InStr(url, "[")
        If InStr(url, "{") And min > InStr(url, "{") Then min = InStr(url, "{")
        If InStr(url, "]") And min > InStr(url, "]") Then min = InStr(url, "]")
        If InStr(url, "}") And min > InStr(url, "}") Then min = InStr(url, "}")
        If min < 2000 Then
            keystr = Left$(Left$(url, min - 1), InStrRev(Left$(url, min - 1), "\"))
            baseUrl = FSO.GetAbsolutePathName(keystr)
            key = Replace$(url, keystr, "")
        Else
            baseUrl = FSO.GetAbsolutePathName(url)
            key = ""
        End If
        If FSO.FolderExists(baseUrl) = True Then
            url = baseUrl
            base = baseUrl
        Else
            url = ""
            base = ""
        End If
    Else
        url = ""
        key = ""
        base = ""
    End If
End Function

Public Function iGlob(Optional ByVal url As String = "") As Variant

    Dim key As String
    key = ""
    Call base(url, key)
    Me.Clear
    Call subSearch(url, key, 0)
    If IsObject(Me.GetItems) = True Then
        Set iGlob = Me.GetItems
    Else
        iGlob = Me.GetItems
    End If

End Function

Public Function Glob(Optional ByVal url As String = "") As Object

    With New Glob
        .SetType = dictionary
        Set Glob = .iGlob(url)
    End With

End Function

Public Function GlobFolder(Optional ByVal url As String = "") As Object

    Dim item As Variant
    Dim List As Object
    Set List = CreateObject("scripting.dictionary")
    With New Glob
        .SetType = Collection
        For Each item In Me.iGlob(url)
            If TypeName(item) = "File" Then
                If List.Exists(item.ParentFolder) = False Then
                    List.Add item.ParentFolder, item.ParentFolder
                End If
            Else
                If List.Exists(item.path) = False Then
                    List.Add item.path, item.path
                End If
            End If
        Next
    End With
    Set GlobFolder = List
    Set List = Nothing

End Function

Private Function subSearch(ByVal baseUrl As String, ByVal key As String, Optional ByVal level As Long = 0) As String

    Dim keyArr As Variant
    Dim folder As Variant
    Dim File As Variant
    
    keyArr = Split(key, "\")
    
    If UBound(keyArr) > level Then
    
        If keyArr(level) = "**" Then
            Call recursive(baseUrl, key, level + 1)
        ElseIf keyArr(level) Like "{*}" Then
        
            For Each folder In FSO.GetFolder(baseUrl).SubFolders
                If folder.name Like keyArr(level) Then
                    Call subSearch(baseUrl & "\" & folder.name, key, level + 1)
                End If
            Next
            Call subSearch(baseUrl, key, level + 1)
        
        Else
        
            For Each folder In FSO.GetFolder(baseUrl).SubFolders
                If folder.name Like keyArr(level) Then
                    Call subSearch(baseUrl & "\" & folder.name, key, level + 1)
                End If
            Next
        
        End If
    
    Else

        If keyArr(level) = "" Then
        
            If FSO.FolderExists(baseUrl) = True Then
                Me.AddItem baseUrl, FSO.GetFolder(baseUrl)
            End If
        
        Else

            For Each File In FSO.GetFolder(baseUrl).Files
                If File.name Like keyArr(level) Then
                    Me.AddItem File, File
                End If
            Next
        
        End If
    
    End If
    
    

End Function

Private Function recursive(ByVal baseUrl As String, ByVal key As String, Optional ByVal level As Long = 0) As String
    
    Dim folder As Variant
    Dim keyArr As Variant
    Dim File As Variant
    
    keyArr = Split(key, "\")
    
    If UBound(keyArr) > level Then
    
        For Each folder In FSO.GetFolder(baseUrl).SubFolders
            If folder.name Like keyArr(level) Then
                Call subSearch(baseUrl & "\" & folder.name, key, level + 1)
            ElseIf "{" & folder.name & "}" Like keyArr(level) Then
                Call subSearch(baseUrl, key, level)
            Else
                Call recursive(baseUrl & "\" & folder.name, key, level)
            End If
        Next

    Else
        For Each folder In FSO.GetFolder(baseUrl).SubFolders
            Call recursive(baseUrl & "\" & folder.name, key, level)
        Next
        For Each File In FSO.GetFolder(baseUrl).Files
            If File.name Like keyArr(level) Then
                Me.AddItem File, File
            End If
        Next
    End If
    
End Function

Tâches futures

À tous ceux qui utilisent

Site de référence

Caractère générique

lettre La description
? N'importe quel personnage
* 0 caractères ou plus
# Nombre demi-largeur de 0 à 9
[charlist] Un caractère pleine largeur ou demi-largeur inclus dans la charlist
[!charlist] Un caractère pleine largeur ou demi-largeur non inclus dans la charlist

Recommended Posts

J'ai essayé de créer une classe pour rechercher des fichiers avec la méthode Glob de Python dans VBA
J'ai essayé de créer une classe qui peut facilement sérialiser Json en Python
J'ai essayé de créer automatiquement un rapport avec la chaîne de Markov
J'ai essayé "Comment obtenir une méthode décorée en Python"
J'ai essayé de commencer avec Hy ・ Définir une classe
J'ai essayé de créer un article dans Wiki.js avec SQL Alchemy
J'ai essayé de créer une liste de nombres premiers avec python
J'ai essayé de créer des taureaux et des vaches avec un programme shell
J'ai essayé de créer un linebot (implémentation)
J'ai essayé de créer un linebot (préparation)
Dois-je l'utiliser pour faire référence à ma classe dans une méthode statique comme @classmethod en Python dans ES2015?
J'ai essayé de créer un programme qui convertit les nombres hexadécimaux en nombres décimaux avec python
J'ai essayé de créer un plug-in avec HULFT IoT Edge Streaming [Execution] (3/3)
J'ai essayé de créer un plug-in avec HULFT IoT Edge Streaming [Setup] (1/3)
J'ai essayé de créer une méthode de super résolution / ESPCN
J'ai essayé de créer une méthode de super résolution / SRCNN ①
Je veux créer une fenêtre avec Python
J'ai essayé d'intégrer Keras dans TFv1.1
J'ai essayé de créer une méthode de super résolution / SRCNN ③
J'ai essayé de créer une méthode de super résolution / SRCNN ②
Quand j'ai essayé de créer un environnement virtuel avec Python, cela n'a pas fonctionné
J'ai créé une API de recherche de château avec Elasticsearch + Sudachi + Go + echo
J'ai essayé de créer facilement un système de présence entièrement automatique avec Selenium + Python
[Azure] J'ai essayé de créer une machine virtuelle Linux avec Azure de Microsoft Learn
J'ai essayé de créer un bouton pour Slack avec Raspeye + Tact Switch
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
Je voulais connaître le nombre de lignes dans plusieurs fichiers et j'ai essayé de l'obtenir avec une commande
Je veux faire la transition avec un bouton sur le ballon
Je veux travailler avec un robot en python.
Je souhaite créer manuellement une légende avec matplotlib
J'ai essayé de créer un environnement avec WSL + Ubuntu + VS Code dans un environnement Windows
J'ai essayé de créer un environnement d'apprentissage amélioré pour Othello avec Open AI gym
J'ai essayé de créer un cadre de données pandas en grattant les informations de rappel d'aliments avec Python
J'ai essayé de créer facilement une image 3D de haute précision avec une seule photo [1]. (La profondeur peut maintenant être modifiée en PNG.)
J'ai essayé d'implémenter une ligne moyenne mobile de volume avec Quantx
J'ai essayé d'implémenter un automate cellulaire unidimensionnel en Python
Comment utiliser la méthode __call__ dans la classe Python
J'ai essayé de résoudre le problème d'optimisation des combinaisons avec Qiskit
J'ai essayé de trier une colonne FizzBuzz aléatoire avec un tri à bulles.
J'ai essayé de créer un bot pour annoncer un événement Wiire
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai essayé d'écrire dans un modèle de langage profondément appris
J'ai créé une classe pour obtenir le résultat de l'analyse par MeCab dans ndarray avec python
Ce à quoi j'étais accro en traitant d'énormes fichiers dans un environnement Linux 32 bits
[Note] Une histoire sur la tentative de remplacer une méthode de classe avec deux barres inférieures dans la série Python 3.
J'ai aussi essayé d'imiter la fonction monade et la monade d'état avec le générateur en Python
J'ai écrit un doctest dans "J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python"
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer un environnement serveur qui fonctionne sous Windows 10
J'ai essayé de décrire le trafic en temps réel avec WebSocket
J'ai créé une bibliothèque qui lit facilement les fichiers de configuration avec Python
J'ai essayé de créer l'API Quip
J'ai essayé de créer un pointage de crédit simple avec régression logistique.
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
Un mémorandum lors de l'acquisition automatique avec du sélénium
[Python] Un mémo que j'ai essayé de démarrer avec asyncio
J'ai essayé de traiter l'image en "style croquis" avec OpenCV