|
|
![]() |
|
||
|
|
|||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| Visual Basic File Routines CreateDirectory: Creating Nested Folders |
||
| Posted: | Saturday September 19, 1998 | |
| Updated: | Monday December 26, 2011 | |
| Applies to: | VB4-32, VB5, VB6 | |
| Developed with: | VB5, Windows 98 | |
| OS restrictions: | None | |
| Author: | VBnet - Randy Birch | |
| Prerequisites |
| None. |
|
|
Applications
often need to create a nested hierarchy of folders outside of Shell's move and copy routines. Typically, for the VB developer, this has
entailed a convoluted combination of ChDir, MkDir and error trapping. Fortunately, as with most things, the WinAPI can come through to reduce
this to a painless task using the CreateDirectory API.
One of the major benefits of this API is that it can be called to create the folders where they already exist, without incident. The return value of the call can be used to determine the success or failure of the call, but when strings are properly formatted before passing to the API, calling CreateDirectory when the specified directory exists simply returns a value indicating its existence. It is unnecessary to check for the presence of the folder before attempting to create it, as well as being unnecessary to change directories in order to create a new subdirectory. Calling CreateDirectory overtop existing folders will not harm any files inside them. The methods here demo two ways of creating the nested folders. The first shows how when passing a fully-qualified path, for example buff = "c:\Demo\Sub1\Sub2\Sub3\Sub4\Sub5\Sub6\Sub7\Sub8" The second method demonstrates using an array of folder names to create the nested levels - x(0)="c:\Demo", x(1)="sub1", x(2) = "sub2" etc.). With both methods, the principle is the same; starting with the first folder, it is created (and if it contains a drive letter, that drive is used, otherwise the application drive is assumed). Subsequent calls to CreateDirectory simply append the next subfolder name to the previously-created folder name. This is repeated until all parts of the full path (or the array) has been appended and created. call 1: "c:\Demo" The code below contains two routines .. CreateNestedFoldersByPath and CreateNestedFoldersByArray. As much of the code below is made up of comments, glancing at the page may give an inaccurate perspective of just how simple (and effective!) a method this really is. Note: This code was developed prior to VB6 and the introduction of the Split() function, which VB6 users can implement to reduce the code in the CreateNestedFoldersByPath routine significantly. |
| BAS Module Code |
| None. |
|
|
| Form Code |
|
|
| Add two lists (List1, List2) a Label (Label1) and two command buttons (Command1 and Command2) to a form. Add the following: |
|
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Const INVALID_HANDLE_VALUE As Long= -1
Private Const MAX_PATH As Long= 260
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Declare Function CreateDirectory Lib "kernel32" _
Alias "CreateDirectoryA" _
(ByVal lpPathName As String, _
lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long
Private Sub Command1_Click()
Dim nMade As Long
Dim buff As String
'the absolute path to create
buff = "c:\DemoByPath\Sub1\Sub2\Sub3\Sub4\Sub5\Sub6\Sub7\Sub8"
'pass ByVal in case the full path is needed
'again. The routine splits up the string when
'passed ByRef (the default).
nMade = CreateNestedFoldersByPath(buff)
'show success
MsgBox buff & vbCrLf & vbCrLf & _
nMade & " subfolders created.", _
vbInformation, "Nested Demo"
End Sub
Private Sub Command2_Click()
Dim nMade As Long
Dim sfolders(0 To 8) As String
'the drive, main folder and subfolders
sfolders(0) = "c:\DemoByArray"
sfolders(1) = "Sub1"
sfolders(2) = "Sub2"
sfolders(3) = "Sub3"
sfolders(4) = "Sub4"
sfolders(5) = "Sub5"
sfolders(6) = "Sub6"
sfolders(7) = "Sub7"
sfolders(8) = "Sub8"
nMade = CreateNestedFoldersByArray(sfolders)
'show success
MsgBox nMade & " subfolders created.", _
vbInformation, "Nested Demo"
End Sub
Private Function CreateNestedFoldersByPath(ByVal completeDirectory As String) As Long
'creates nested directories on the drive
'included in the path by parsing the final
'directory string into a directory array,
'and looping through each to create the final path.
'The path could be passed to this method as a
'pre-filled array, reducing the code.
Dim r As Long
Dim SA As SECURITY_ATTRIBUTES
Dim drivePart As String
Dim newDirectory As String
Dim item As String
Dim sfolders() As String
Dim pos As Long
Dim x As Long
'show the path to create
Label1.Caption = "created " & completeDirectory
'must have a trailing slash for
'the GetPart routine below
If Right$(completeDirectory, 1) <> "\" Then
completeDirectory = completeDirectory & "\"
End If
'if there is a drive in the string, get it
'else, just use nothing - assumes current drive
pos = InStr(completeDirectory, ":")
If pos Then
drivePart = GetPart(completeDirectory, "\")
Else: drivePart = ""
End If
'now get the rest of the items that
'make up the string
Do Until completeDirectory = ""
'strip off one item (i.e. "Files\")
item = GetPart(completeDirectory, "\")
'add it to an array for later use, and
'if this is the first item (x=0),
'append the drivepart
ReDim Preserve sfolders(0 To x) As String
If x = 0 Then item = drivePart & item
sfolders(x) = item
'debug only
List1.AddItem item
'increment the array counter
x = x + 1
Loop
'Now create the directories.
'Because the first directory is
'0 in the array, reinitialize x to -1
x = -1
Do
x = x + 1
'just keep appending the folders in the
'array to newDirectory. When x=0 ,
'newDirectory is "", so the
'newDirectory gets assigned drive:\firstfolder.
'Subsequent loops adds the next member of the
'array to the path, forming a fully qualified
'path to the new directory.
newDirectory = newDirectory & sfolders(x)
'the only member of the SA type needed (on
'a win95/98 system at least)
SA.nLength = LenB(SA)
Call CreateDirectory(newDirectory, SA)
'debug only
List2.AddItem newDirectory
Loop Until x = UBound(sfolders)
'done. Return x, but add 1 for the 0-based array.
CreateNestedFoldersByPath = x + 1
End Function
Private Function CreateNestedFoldersByArray(sfolders() As String) As Long
Dim SA As SECURITY_ATTRIBUTES
Dim newDirectory As String
Dim x As Long
'initialize x to -1
x = -1
Do
x = x + 1
'add a trailing slash if needed
If Right$(sfolders(x), 1) <> "\" Then
sfolders(x) = sfolders(x) & "\"
End If
newDirectory = newDirectory & sfolders(x)
SA.nLength = LenB(SA)
Call CreateDirectory(newDirectory, SA)
'debug only
List1.AddItem sfolders(x)
List2.AddItem newDirectory
Loop Until x = UBound(sfolders)
CreateNestedFoldersByArray = x + 1
End Function
Function GetPart(startStrg As String, delimiter As String) As String
'takes a string separated by "delimiter",
'splits off 1 item, and shortens the string
'so that the next item is ready for removal.
Dim c As Integer
Dim item As String
c = 1
Do
If Mid$(startStrg, c, 1) = delimiter Then
item = Mid$(startStrg, 1, c)
startStrg = Mid$(startStrg, c + 1, Len(startStrg))
GetPart = item
Exit Function
End If
c = c + 1
Loop
End Function
|
| Comments |
| Run the app, and open Explorer to check the results. the results messagebox returns the number of folders created. Alternatively, you could assign a variable to the CreateDirectory call; a return value of 0 indicates the call did not complete (most likely because the directory already exists), and a return of 1 indicates success. |
|
|
|
|
|
|||||
|
|||||
|
|
|||||
|
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |
![]() |