Creating Nested Directories
This page describes code that you can use to create nested directories with a single line of code.
It is not an uncommon need to create a directory structure that is several levels deep. For example,
your application may need to create a directory like C:\MyApplication\Settings\Templates\VB.
While VBA does have a command named MkDir that creates a directory, it will not
create any intermediate directories. Refering the directory above, you would need 4 separate calls to
MkDir:
MkDir "C:\MyApplication"
MkDir "C:\MyApplication\Settings"
MkDir "C:\MyApplication\Settings\Templates"
MkDir "C:\MyApplication\Settings\Templates\VB"
This is cumbersome and aesthically displeasing. The Scripting.FileSystemObject, which
we will see below, suffers this same limitation. It would be much cleaner to create all of the intermediate
directory with one line of code. This page describes a procedure named MakeMultiStepDirectory
that does just this.
You can call MakeMultiStepDirectory passing it the entire directory path and
it will automatically create all the required intermediate directories:
MakeMultiStepDirectory C:\MyApplication\Settings\Templates\VB
The MakeMultiStepDirectory function can create directories on both the local
machine (C:\MyApplication\Settings\Templates\VB), a mapped drive, or a
UNC network share (\\BlackCow\MainShare\MyApplication\Settings\Templates\VB). Note
that the function cannot create a share; the share must already exist and, of course, you must have permissions
to create directories on that share. For example, with the paths above, \\BlackCow\MainShare
must already exist and you must have permission on that share to create directories.
The MakeMultiStepDirectory function makes use of the
Scripting.FileSystemObject, so your project will need a reference to the
Microsoft Scripting Runtime Library. In VBA with your project open, go to the Tools
menu, choose References and scroll down until you find Microsoft Scripting Runtime Library.
Check the box next to this entry.
The MakeMultiStepDirectory function returns values that are listed in an
Enum named EMakeDirStatus, which is defined in the
downloadable bas module file. This Enum is as follows:
Public Enum EMakeDirStatus
ErrSuccess = 0
ErrRelativePath
ErrInvalidPathSpecification
ErrDirectoryCreateError
ErrSpecIsFileName
ErrInvalidCharactersInPath
End Enum
where
- ErrSuccess indicates the operation was successful.
- ErrRelativePath indicates that a relative path was passed to the function. You
must pass an absolute path (begining with either a drive letter or a UNC share name.
- ErrInvalidPathSpecification indicates that the path is badly formed.
- ErrDirectoryCreateError indicates that there was an error creating the directory. Most
often, this is a security/permission issue.
- ErrSpecIsFileName indicates the input parameter was a file name not a folder name.
- ErrInvalidCharactersInPath indicates that there were invalid characters in the folder name.
The code for MakeMultiStepDirectory is shown below.
Private Declare Function PathIsRelative Lib "Shlwapi" _
Alias "PathIsRelativeA" (ByVal Path As String) As Long
Public Enum EMakeDirStatus
ErrSuccess = 0
ErrRelativePath
ErrInvalidPathSpecification
ErrDirectoryCreateError
ErrSpecIsFileName
ErrInvalidCharactersInPath
End Enum
Const MAX_PATH = 260
Function MakeMultiStepDirectory(ByVal PathSpec As String) As EMakeDirStatus
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' MakeMultiStepDirectory
' This function creates a series of nested directories. The parent of
' every directory is create before a subdirectory is created, allowing a
' folder path specification of any number of directories (as long as the
' total length is less than MAX_PATH.
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim FSO As Scripting.FileSystemObject
Dim DD As Scripting.Drive
Dim B As Boolean
Dim Root As String
Dim DirSpec As String
Dim N As Long
Dim M As Long
Dim S As String
Dim Directories() As String
Set FSO = New Scripting.FileSystemObject
On Error Resume Next
Err.Clear
S = Dir(PathSpec, vbNormal)
If Err.Number <> 0 Then
MakeMultiStepDirectory = ErrInvalidCharactersInPath
Exit Function
End If
On Error GoTo 0
B = CBool(PathIsRelative(PathSpec))
If B = True Then
MakeMultiStepDirectory = ErrRelativePath
Exit Function
End If
If FSO.FolderExists(PathSpec) = True Then
MakeMultiStepDirectory = ErrSuccess
Exit Function
End If
If Right(PathSpec, 1) = "\" Then
PathSpec = Left(PathSpec, Len(PathSpec) - 1)
End If
N = InStrRev(PathSpec, "\")
M = InStrRev(PathSpec, ".")
If (N > 0) And (M > 0) Then
If M > N Then
' period found after last slash
MakeMultiStepDirectory = ErrSpecIsFileName
Exit Function
End If
End If
If Left(PathSpec, 2) = "\\" Then
N = InStr(3, PathSpec, "\")
N = InStr(N + 1, PathSpec, "\")
Root = Left(PathSpec, N - 1)
DirSpec = Mid(PathSpec, N + 1)
Else
N = InStr(1, PathSpec, ":", vbBinaryCompare)
If N = 0 Then
MakeMultiStepDirectory = ErrInvalidPathSpecification
Exit Function
End If
Root = Left(PathSpec, N)
DirSpec = Mid(PathSpec, N + 2)
End If
Set DD = FSO.GetDrive(Root)
Directories = Split(DirSpec, "\")
DirSpec = DD.Path
For N = LBound(Directories) To UBound(Directories)
DirSpec = DirSpec & "\" & Directories(N)
If FSO.FolderExists(DirSpec) = False Then
On Error Resume Next
Err.Clear
FSO.CreateFolder (DirSpec)
If Err.Number <> 0 Then
MakeMultiStepDirectory = ErrDirectoryCreateError
Exit Function
End If
End If
Next N
MakeMultiStepDirectory = ErrSuccess
End Function
You can then call this code from your own code as follows:
Sub AAA()
Dim Result As EMakeDirStatus
Result = MakeMultiStepDirectory("C:\One\Two\Three\Four")
If Result = ErrSuccess Then
Debug.Print "Success"
Else
Debug.Print "Error"
End If
End Sub
|
This page last updated: 12-Feb-2010. |