Good Day, mazan
There are, I believe, many ways to check for and Create Folders and Sub Folders.
This may help get you started: ( The code is not too efficient, as there are lots of extra and unnecessary steps and variable usage, but this should aid you to understand better what is going on as well as aid in later modification to meet your exact requirements )
1- macro
This will work , for example, on this data_....
Using Excel 2007 32 bit
_....in the First Worksheet of the File in which the Code is, and it will make you two Folders with the names XYT and XTC in the same Folder in which The File in which the code is in, or it will evoke a message box to tell you if the Folders already exist
1-macro:
Note
Line 80 This sets the string of the Full Path up to your main Folders. You will need to adjust this to suit where you want to store the main Folders
Sub mazan1_macro() ' Post #2 ' http://www.excelforum.com/excel-programming-vba-macros/1154519-macro-to-create-folder-and-subfolder-and-file-inside-subfolder-each-one-with-specific-name.html
10 Rem 1 Workbooks, Worksheets info. some Variable declarations
20 '1a ) File Info, Paths, File names
30 Dim WB As Workbook ' Dim: ' Preparing a "Pointer" to an Initial "Blue Print" in Memory of the Object ( Pigeon Hole with a bit of paper or code lines on that can be filled in to refer to a specific Objec of this type ) . This also us to get easily at the Methods and Properties throught the applying of a period ( .Dot) ( intellisense ) '
40 Set WB = ThisWorkbook ' Set now (to This Workbook - the one this code is in), so that we carefull allways referrence this so as not to go astray through Excel Guessing inplicitly not the one we want... Set: Values are filled at the memory locations and the directions there are specified in the variable "Blue Print "Pointer". In this case a Filled in Blue Print is passed. http://www.excelforum.com/excel-programming-vba-macros/1138804-help-understanding-class-instancing-cant-set-ws-new-worksheet-intellisense-offers-it-4.html#post4387191Set ws = ActiveSheet ' Alternative to last line, make code apply to the current active sheet, - That being "looked at" when running this code '
50 Dim Ws1 As Worksheet: Set Ws1 = WB.Worksheets.Item(1) ' 'The Worksheets Collection Object of WB is used referrencing by Item number which is a consecutive count starting at 1 from the left and increasing by 1 as you count to the right. This Worksheet has the .Name Property applied to return the String Tab Name
60 Dim FolderName As String ' Prepares "Pointer" to a "Blue Print" (or Form, Questionnaire not yet filled in, a template etc.)"Pigeon Hole" in Memory, sufficient in construction to house a piece of Paper with code text giving the relevant information for the particular Variable Type. VBA is sent to it when it passes it. In a Routine it may be given a particular “Value”, or (“Values” for Objects). There instructions say then how to do that and handle(store) that(those). At Dim the created Paper is like a Blue Print that has some empty spaces not yet filled in. A String is a a bit tricky. The Blue Print code line Paper in the Pigeon Hole will allow to note the string Length and an Initial start memory Location. This Location well have to change frequently as strings of different length are assigned. Instructiions will tell how to do this. Theoretically a specilal value vbNullString is set to aid in quich checks.. But... http://www.mrexcel.com/forum/excel-questions/361246-vbnullstring-2.html#post44116
70 Dim strDefpath As String 'String variables for the relavent parts of Folder Path
80 Let strDefpath = WB.Path & "\" 'Default Path as That of where this code is. CHANGE TO SUIT
90 '1b ) Input Data Info
100 Dim Lr1 As Long, Lr5 As Long ' variables for last rows ' ' Long is very simple to handle, - final memory "size" type is known (123.456 and 000.001 have same "size" computer memory ) , and so a Address suggestion can be given for the next line when the variable is filled in. '( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) If you need some sort of validation the value should only be within the range of a Byte/Integer otherwise there's no point using anything but Long.--upon/after 32-bit, Integers (Short) need converted internally anyways, so a Long is actually faster. )
110 Let Lr1 = Ws1.Cells(Rows.Count, 1).End(xlUp).Row ' ' The Range Object ( cell ) that is the last cell in the column of interest (CHOOSE a column typically that will always have a last Entry in any Data) ,( Row Number given by .Count Property applied to ( any Worksheet would do, so leaving unqualified is OK here, ) Spreadsheet Range Columns Property) has the Property .End ( argument "Looking back up" ) appled to it. This Returns a new Range ( cell ) object which is that of the first Range ( cell ) with something in it "looking back up" in the XL spreadsheet from that last Cell. Then the .Row Property is applied to return a long number equal to the Column number of that cell: 3. Rows.Count is the very last row number in your sheet. It is different for earlier versions of Excel. The End(xlUp) is the same as pressing a Ctrl+UpArrow key combination. The final ".Row" returns the row where the cursor stops after moving up.
120 'Let Lr1 = Ws1.Cells(Rows.Count, 5).End(xlUp).Row
130 Dim arrCapture() As Variant 'This Array is to be used generally to make a single code line "capture" of a spreadsheet range available to us through the .Value, which returns us a field of Variant Types, hence we must Dimension appropriately
140 Let arrCapture() = Ws1.Range("A1:A" & Lr1 & "").Value2 ' .Value Property Returning Field of our Folder names in Column A. This will return a 1 "column" 2 Dimensional Array
150 Dim arrFolderNames() As String: ReDim arrFolderNames(1 To Lr1) 'Array of string types to hold our Folder Names. ( We know the Types so can Declare appropriately. We also know the size, but are using ReDim as Dim ing an Array to size can only be done with numbers, like Dim arr(1 To 2) as String. The syntax of ReDim allows variables as well as nu8mbers to be used
160 Dim Cnt As Long 'Loop Bound variable count
170 For Cnt = 1 To Lr1
180 Let arrFolderNames(Cnt) = arrCapture(Cnt, 1) ' Effectively transposing our 1 "column" 2 Dimensional Array of variant types (housing Strings) to a 1 Dimensional "pseudo horizontal" Array of String types. This extra somewhat unecerssary step is acceptable in my opinion as the transposing loop works very quickly in 1 Dimension and there are often efficiency advantages later in using 1 Dimensional Arrays in VBA Strings Collection Funktions
190 Next Cnt
200 Rem 2 ) Produce Folders or inform ot their existance
210 Dim Stear As Variant 'For use in a For Next Loop the controling Variable must be of varint or Object type
220 For Each Stear In arrFolderNames() ' could also For Cnt = 1 To Lr1 --
230 Let FolderName = Stear
240 If Len(Dir("" & (strDefpath & FolderName) & "", vbDirectory)) = 0 Then 'If the Directory ( Folder ) does not exist then...
250 MkDir (strDefpath & FolderName) '...make it
260 Else 'The Directory is presumably already there so do not make it again!
270 MsgBox prompt:="Folder """ & FolderName & """ exists already at " & strDefpath & ""
280 End If
290 Next Stear ' could also Next Cnt --
End Sub
_...........................................
2-macro is in discussed in next post.
Bookmarks