Home
Home

---Soumis par Ken Getz---

VBA Developer's Handbook - Code de remplacement pour certaines fonctions du chapitre 12.

Dans VBA Developer's Handbook, au chapitre 12, la procédure dhDelTree possède un sérieux problème si vous lui fournissez le chemin d'un disque autre que le disque actuel. Dans un tel cas, la procédure efface les fichiers du disque courant, non du disque spécifié. Cela peut entraîner de sérieuse perte de données. 

La fonction de replacement suivante effectue le changement de disque et de répertoire à ceux spécifiés, de sorte que l'effacement s'effectue correctement. N'utilisez  pas la fonction  dhDelTree publiée dans le bouquin -- assurez vous de remplacer toutes les copies par cette nouvelle version, pour éviter de perdre des données.

Aucune fonction ne fonctionnera proprement si vous ne possédez pas les autres procédures du chapitre 12, il est donc inutile de télécharger ces correctifs si vous ne possédez pas le bouquin.

'************ Code Start **************
' Add this at the top of the module.
Private Declare Function SetCurrentDirectory _
 Lib "kernel32" Alias "SetCurrentDirectoryA" _
 (ByVal lpPathName As String) As Long

Function dhDelTree(ByVal Directory As String, _
 Optional RemoveRoot As Boolean = True, _
 Optional ByVal Level As Integer = 1) As Boolean

    ' Deletes an entire directory tree (including all
    ' files and subdirectories). Calls itself recursively.

    ' From "VBA Developer's Handbook"
    ' by Ken Getz and Mike Gilbert
    ' Copyright 1997; Sybex, Inc. All rights reserved.

    ' In:
    '   Directory
    '       Directory to delete.
    '   RemoveRoot
    '       True if you want to remove the top-level folder.
    '       False if you want to remove contents, but leave
    '         the top-level folder intact.
    '   Level
    '       Used by the procedure. Do not specify a value.
    
    ' Out:
    '   Return Value:
    '       True if successful, False if not.
    ' Example:
    '   Call dhDelTree("C:\")   ' Ha! Ha! Just kidding
    '   Call dhDelTree("C:\DATA\MYDIR")

    On Error GoTo HandleErrors

    Dim strFilename As String
    Dim strDirectory As String

    strDirectory = dhFixPath(Directory)
    
    ' Check to make sure the directory actually exists.
    ' If not, we don't have to do a thing.
    If Len(Dir(strDirectory, vbDirectory)) = 0 Then
        GoTo ExitHere
    End If
    
    If dhFixPath(CurDir) = strDirectory Then
        MsgBox "Unable to delete the current directory. " & _
         "Move to a different directory, and try again."
        GoTo ExitHere
    End If
    
    ' Delete all the files in the current directory
    strFilename = Dir(strDirectory & "*.*")
    Do Until strFilename = ""
        Kill strDirectory & strFilename
        strFilename = Dir
    Loop
    
    ' Now build a list of subdirectories
    Do
        strFilename = Dir(strDirectory & "*.*", vbDirectory)
        
        ' Skip "." and ".."
        Do While strFilename = "." Or strFilename = ".."
            strFilename = Dir
        Loop
    
        ' If there are no more files, exit the loop.
        ' Otherwise call dhDelTree again to wipe
        ' out the subdirectory.
        If strFilename = "" Then
            Exit Do
        Else
            ' Call dhDelTree recursively. Pass True for RemoveRoot,
            ' because you'll always want to remove subfolders.
            ' Indicate the level by passing Level + 1. 
            If Not dhDelTree(strDirectory & strFilename, True, Level + 1) Then
                GoTo ExitHere
            End If
        End If
    Loop
    
    ' Finally, remove the target directory
    ' The following expression returns True unless
    ' the first factor is True and the
    ' second factor is False -- that is,
    ' it always removes the folder unless
    ' you're at level 1 (the root level) and you've
    ' been told not to remove the root.
    If Level = 1 Imp RemoveRoot Then
        RmDir strDirectory
    End If
    
    dhDelTree = True
    
ExitHere:
    Exit Function
    
HandleErrors:
    Select Case Err.Number
        Case 75 ' Path or file access
            ' If a file or folder can't be deleted,
            ' just keep going.
            Resume Next
        Case Else
            dhDelTree = False
            MsgBox Err.Description, vbExclamation, _
             "Error " & Err.Number & " in dhDelTree"
            Resume ExitHere
    End Select
End Function
'************ Code End  **************

Dans VBA Developer's Handbook, au  chapitre 12, si vous utilisez la fonction dhDir pour parcourir les dossiers, la fonction ne libère pas correctement une ressource référant à ce dossier et vous ne serez pas capable d'effacer ce dossier à moins de quitter VBA (en quittant l'application hôtesse). La fonction de remplacement qui suit résoudra ce problème.

'************ Code Start  **************
Function dhDir(Optional ByVal strPath As String = "", _
 Optional lngAttributes As Long = vbNormal, _
 Optional fExclusive As Boolean = True) As String

    ' Replacement for the VBA Dir function which lets you
    ' specify file attributes for a restrictive search.

    ' From "VBA Developer's Handbook"
    ' by Ken Getz and Mike Gilbert
    ' Copyright 1997; Sybex, Inc. All rights reserved.

    ' In:
    '   strPath (Optional, default = "")
    '       Path and/or file specification to search.
    '   lngAttributes (Optional, default = vbNormal)
    '       File attributes.
    '   fExclusive (Optional, default = True)
    '       If True, only those files with the matching
    '       file attributes are returned.
    ' Out:
    '   Return Value:
    '       If called with a file specification, the first
    '       matching filename is returned. If called without
    '       a file specification, the next matching filename
    '       is returned. When no additional matching filenames
    '       are found, an empty string is returned.
    ' Example:
    '   Dim strDir As String
    '
    '   strDir = dhDir("C:\", vbDirectory)
    '   Do Until strDir = ""
    '       Debug.Print strDir
    '       strDir = dhDir()
    '   Loop 
      
    Dim fd As WIN32_FIND_DATA
    Static hFind As Long
    Static lngAttr As Long
    Static fEx As Boolean
    Dim strOut As String
    
    ' If no path was passed, try to find the next file
    If strPath = "" Then
        If hFind > 0 Then
            If CBool(FindNextFile(hFind, fd)) Then
                strOut = dhFindByAttr(hFind, fd, lngAttr, fEx)
            End If
        End If
        
    ' Otherwise, start a new search
    Else
        ' Store the attributes and exclusive settings
        lngAttr = lngAttributes
        fEx = fExclusive
        
        ' If the path ends in a backslash, assume
        ' all files and append "*.*"
        If Right(strPath, 1) = "\" Then
            strPath = strPath & "*.*"
        End If
        
        ' Find the first file
        hFind = FindFirstFile(strPath, fd)
        If hFind > 0 Then
            strOut = dhFindByAttr(hFind, fd, lngAttr, fEx)
        End If
    End If
    
    ' If the search failed, close the Find handle.
    If Len(strOut) = 0 Then
        If hFind > 0 Then
            Call FindClose(hFind)
        End If
    End If
    dhDir = strOut
End Function
'************ Code End  **************