creating a list of folders in excel - excel

I'm trying to create a list of folders, based off row data in Excel.
Obviously I've copied this common code from elsewhere.
It worked the first time I used it, but when I went to create another run of folders, it spit out this error: "run time error 76: path not found"
I've saved the file into its own new folder, so the only thing that exists in the folder is the excel workbook.
If Len(Dir(ActiveWorkbook.Path & "\" & Rng(r, c), vbDirectory)) = 0 Then _
MkDir (ActiveWorkbook.Path & "\" & Rng(r, c))
Thanks

I've tried your code and it creates the folders as expected.
Here's what I executed:
Sub MakeFolders()
Dim Rng As Range
Dim maxRows As Integer, maxCols As Integer, r As Integer, c As Integer
Set Rng = Selection
maxRows = Rng.Rows.Count
maxCols = Rng.Columns.Count
For c = 1 To maxCols
r = 1
Do While r <= maxRows
If Len(Dir(ActiveWorkbook.Path & "\" & Rng(r, c), vbDirectory)) = 0 Then
MkDir (ActiveWorkbook.Path & "\" & Rng(r, c))
On Error Resume Next
End If
r = r + 1
Loop
Next c
End Sub
Note that I adjusted your second Dim statement to include the data type for each variable as that seemed your intent. Without including "as Integer" for each variable, all but the last variable in the list was being declared as "variant" instead of "integer".
You definitely want to remove the "on error resume next" statement. Once that line executes, it is suppressing any error message that you would otherwise see to help you find the issue.
My best guess is that you have illegal characters in the data you are using to create the folders. Be sure that none of your folder names include the following characters as they are all disallowed in folder names
< (less than)
> (greater than)
: (colon)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
I've provided a simplified version of your code in case it is of use.
Sub MakeFolders2()
Dim cell As Range
For Each cell In Selection
If Len(Dir(ActiveWorkbook.Path & "\" & cell.value, vbDirectory)) = 0 Then
MkDir (ActiveWorkbook.Path & "\" & cell.value)
End If
Next
End Sub

Related

Remove empty lines in txt export from [excel] [vba]

Not the best at VBA but I will give some context to help explain this probably stupid question.
The place I work for has a terrible system so we tend to do things our own way and use the system as little as possible.
We wanted to be able to take direct debits from customers as and when we need to and to do this we needed to create a 'BACS Standard 18' file to upload to the bank in order to collect the direct debits. The file requires there to be specific information about the transaction and it has to be displayed in a very specific way in notepad(txt).
I managed to create an Excel file that our finance team can use in order to create the file but when the file is created the typing cursor is always found to be a couple of lines under the exported text.
I need the text to be exported and the typing cursor to be at the end of the last line of the text, or a least not underneath. If it is under it, the bank will see that as a blank line and not accept the file. The number of lines in the file will always be different as well.
I have attached an example of the file in a screenshot. The highlighted part is what the file should include but as you can see the typing cursor is two lines lower.
Can someone please help with this and explain where I have gone wrong.
Thank you.
exportedfile
Below is the [vba] used to build the file and export the data from excel to notepad:
Sub Build_BACS()
LastRow = (Worksheets("Input").Range("Q2"))
'Header
ActiveSheet.Range("A1").Value = "=""VOL1""&Home!D5&"" ""&Home!D2&"" ""&""1"""
ActiveSheet.Range("A2").Value = "=""HDR1A""&Home!D2&""S""&"" ""&Home!D5&""00010001 ""&Home!D8&"" ""&Home!E8&"" 000000 """
ActiveSheet.Range("A3").Value = "=""HDR2F02000""&Home!B11&"" 00 """
ActiveSheet.Range("A4").Value = "=""UHL1 ""&Home!D8&""999999 000000001 DAILY 001 """
'Middle
ActiveSheet.Range("A5").Value = "=CONCAT(Input!C2,Input!D2,Input!K2,Input!G2,Input!H2,"" "",Input!L2,Input!M2,"" "",Input!N2,Input!O2)"
On Error Resume Next
Range("A5").AutoFill Destination:=Range("A5:A" & LastRow + 4), Type:=xlFillDefault
'Footer
If Sheets("Home").Range("A2").Value = "TMR" Or Sheets("Home").Range("A2").Value = "TMRF" Or Sheets("Home").Range("A2").Value = "TMREA" Then
Sheets("Output").Range("A" & LastRow + 5).Value = "=TEXT(Home!C2,""000000"")&TEXT(Home!B2,""00000000"")&""099""&TEXT(Home!C2,""000000"")&TEXT(Home!B2,""00000000"")&"" ""&TEXT(Input!P2,""00000000000"")&""The Mailing Room CONTRA TMR """
ElseIf Sheets("Home").Range("A2").Value = "DPS" Then
Sheets("Output").Range("A" & LastRow + 5).Value = "=TEXT(Home!C2,""000000"")&TEXT(Home!B2,""00000000"")&""099""&TEXT(Home!C2,""000000"")&TEXT(Home!B2,""00000000"")&"" ""&TEXT(Input!P2,""00000000000"")&""DPS CONTRA TMR """
End If
ActiveSheet.Range("A" & LastRow + 6).Value = "=""EOF1""&MID(A2,5,76)"
ActiveSheet.Range("A" & LastRow + 7).Value = "=""EOF2""&MID(A3,5,76)"
ActiveSheet.Range("A" & LastRow + 8).Value = "=""UTL1""&TEXT(Input!P2,""0000000000000"")&TEXT(Input!P2,""0000000000000"")&""0000001""&TEXT(Input!Q2,""0000000"")&"" """
'Export
Dim c As Range
Dim r As Range
Dim output As String
For Each r In Range("A1:A" & LastRow + 8).Rows
For Each c In r.Cells
output = output & c.Value
Next c
output = output & vbNewLine
Next r
Open ThisWorkbook.Path & "\" & ([Indirect("Home!B13")]) & ".txt" For Output As #1
Print #1, output
Close
InputBox "Noice." & Chr(13) & "Your file is just in here", "File Path", "Z:\My Documents\Orrin Lesiw\Direct Debit\Convert File"
End Sub
Adding ; to Print suppressed the vbNewLine. However output = output & vbNewLine will always add a newline so either add to front for lines 2 onwards like
Sub out2()
Dim c As Range
Dim r As Range
Dim output As String
For Each r In Range("A1:A" & LastRow + 8).Rows
If r.Row > 1 Then output = output & vbNewLine
For Each c In r.Cells
output = output & c.Value
Next c
Next r
Open ThisWorkbook.Path & "\" & ([Indirect("Home!B13")]) & ".txt" For Output As #1
Print #1, output;
Close
End Sub
or transpose the range into an array and use Join
' Export
Dim ar
ar = Application.Transpose(Range("A1:A" & LastRow + 8))
Open ThisWorkbook.Path & "\" & ([Indirect("Home!B13")]) & ".txt" For Output As #1
Print #1, Join(ar, vbNewLine);
Close

Create separate files based on 2 variables

I'm trying to figure out how to rewrite my macro (that I use already to create files containing records based on a date) so that it continues to create separate files but based on an additional variable, e.g. on date and type.
Some additional input:
the date is selected by the user through a userForm containing 'Selected Date'; this value is passed on to the macro;
the type (as is the date), is part of the data record
Here's are the columns in the entire record:
Date
Type
Product
Currency
Id
20210401
1
A
EUR
1548
20210401
2
A
EUR
1579
20210401
1
A
EUR
1589
Using the table above, I would like to create separate files called FILE_20210401_1.txt and FILE_20210401_2.txt file creation is controlled by a) the date, and b) the type. This means my first file would contain 2 records, the latter only 1.
All goes fine with regard to file names and storing the files.
The content, however, is the bottleneck, as the macro now includes all records in both files. I have tried many things using a loop and a double loop, but I guess I'm missing something to tell the macro i want to have a file grouped per date and type. This is what I have so far in the macro:
Sub
Dim sRange As Range
Dim i As Long
Dim m As Long
Dim SelectedDate As String
Dim TDate As String
Dim Type As Variant
SelectedDate = Range("AA2").Value 'Selected Date entered on the userForm
Set sRange = Range("A2:E4").Cells(1, 1).CurrentRegion
If TDate = SelectedDate Then
For i = 2 To sRange.Rows.Count
'set date column
TDate = sRange.Range("A" & i) 'TDate is in column A of the range
For m = 2 To sRange.Rows.Count
Type = sRange.Range("B" & m) 'Type is in column B of the range
'define directories and file location
If Len(Dir(MyFolder1, vbDirectory)) <> 0 Then
If Len(Dir(MyFolder2, vbDirectory)) <> 0 Then
If Len(Dir(MyFolder3, vbDirectory)) <> 0 Then
filename = MyFolderFull & "\FILE_" & SelectedDate & "_" & Type & ".txt"
Else: MkDir MyFolder3
filename = MyFolderFull & "\FILE_" & SelectedDate & "_" & Type & ".txt"
End If
Else: MkDir MyFolder2
MkDir MyFolder3
filename = MyFolderFull & "\FILE_" & SelectedDate & "_" & Type & ".txt"
End If
Else: MkDir MyFolder1
MkDir MyFolder2
MkDir MyFolder3
filename = MyFolderFull & "\FILE_" & SelectedDate & "_" & Type & ".txt"
End If
Open filename For Output As #1
Print #1
Close #1
Next m
Next i
End if
MsgBox "Files created!"
End Sub
Any ideas as to what I am forgetting here?
Your code contains:
Open filename For Output As #1
It should be:
filename = "FILE_" & CStr(TDATE) & "_" & CStr(i)
Open filename For Output As #1
(Something like that, I didn't test it)

How can I change my variant referencing to an input box?

I'm trying to simplify a file_split script to a point of self-service in my dept. No one really has any understanding of the language, so I was checking to see if any of this could be further simplified so coworkers don't have to update the code from the editor pane.
for instance, I have things like Basepath to designate where the files will be saved off. How can I change
Dim Basepath As String
Basepath = "C:\Users\File Cuts\"
directory as string
to something like this where a user can select a folder pathway?
Dim Basepath as filedialog
with basepath
.title = "Select save location"
.directory = .selecteditems(1)
end with
and then instances where I have specific columns to reference (target value columns for each new file, naming convention columns, etc...)
as in:
Dim Manager_Name, Login_ID, Leader
Manager_Name = SourceData(i,4)
Login_ID = SourceData(i,5)
Leader = SourceData(i,9)
to be inputted by an input box for column letter like:
Dim column_selection as variant
column_selection = InputBox("Enter Column Letter")
Manager_Name = SourceData(i,column_selection)
There are quite a few references that I'd like to see if I could change so that edits could be made without actually touching the code (the column ranges where variants like name, and login ID will be changing a lot)
rest of code:
Option Explicit
Sub File_Splits()
Dim Wb As Workbook
Dim SourceData, Mgr_Name, Login_Id
Dim i As Long, j As Long, k As Long, a As Long
Dim Destination_Cell As Range
Dim Basepath As String, strNewpath As String, strLeader As String
Basepath = "C:\File Cuts\" '1. paste in file save pathway, keep last \
Set Wb = Workbooks.Open("C:\File_Split_Mgr_Template.xlsx") '2. paste template ws address here
Set Destination_Cell = Wb.Worksheets("Manager Data").Range("A2") '3. Update worksheet name and target cell
With ThisWorkbook.Worksheets("Roster")
SourceData = .Range("I10", .Range("A" & Rows.Count).End(xlUp)) '4. change I10 to your last column letter, dont change the number(keep the 10)
End With
Wb.Activate
Call Speed_Up_Code(True)
For i = 1 To UBound(SourceData)
If SourceData(i, 5) <> Login_Id Then '5. change the 1 to login column #
If i > 9 Then
Destination_Cell.Select
strNewpath = Basepath & strLeader & "\" 'comment this out if folders aren't needed
If Len(Dir(strNewpathD, vbDirectory)) = 0 Then 'comment this out if folders aren't needed
MkDir strNewpath 'comment this out if folders aren't needed
End If 'comment this out if folders aren't needed
Wb.SaveCopyAs strNewpath & _
ValidFileName(Login_Id & "_" & Mgr_Name & "_File Name.xlsx") '6. update file name
End If
With Wb.Worksheets("Manager Data") '7. change to template sheet
.Rows(2 & ":" & .Rows.Count).ClearContents '8. change 2 to row after header(s)--if header isn't in row 1
End With
Mgr_Name = SourceData(i, 4) '9. change 1 to mgr name column
Login_Id = SourceData(i, 5) '10. change 2 to login ID column
strLeader = SourceData(i, 9) '11. change 5 to lvl 3 mgr column
j = 0
End If
a = 0
For k = 1 To UBound(SourceData, 2)
Destination_Cell.Offset(j, a) = SourceData(i, k)
a = a + 1
Next
j = j + 1
Next
If Len(Dir(strNewpath, vbDirectory)) = 0 Then
MkDir strNewpath
End If
SaveCopy Wb, strNewpath, Login_Id, Mgr_Name
Call Speed_Up_Code(False)
End Sub
Public Sub SaveCopy(Wb As Workbook, strNewpath As String, Login_Id, Mgr_Name)
Wb.SaveCopyAs strNewpath & _
ValidFileName(Login_Id & "_" & Mgr_Name & "_File Name.xlsx") '12. update file name
End Sub
Have you considered having a sheet called something like "Configuration" where users write to and your script can read from. Hidden or protected if necessary
For example, list all your configuration description in col A, and the user fills in the value next to in col B, So if A1 contains the text "Manager Name Column [A-Z] =" the user enters the value "D" or 4 in cell B1. The script become Mgr_Name = SourceData(i, wsConfig.range("B1")). I guess you could add validation to their entries.
Layout the sheet like a form in logical groups and highlight where the entry cells are. In a case like entering column names I would put them horizontal with the descripting above and entry cell below, that seems more natural. Protect all the cells except the highlighted ones.

How do I replace strings with ID's using VBA?

I searched for an answer to this question, but it seems like the only ways that people have answered it are using Excel functions. I have a file in Excel that I load in to a text file, but new data comes out every week. I need to replace the Market names in this first column with their respective tickers, which are in this separate worksheet, but in the same Excel file.
For example, I want all 'CANADIAN DOLLAR - CHICAGO MERCANTILE EXCHANGE' cells to be replaced with 'CAD', all 'SWISS FRANC - CHICAGO MERCANTILE EXCHANGE' cells to be replaced with 'SWF', etc.
I would prefer if the names remained the same in the Excel file and were only changed when I transferred them to the text file. However, that's not essential if it's harder to do.
For reference, here's the code I'm using to write to the text file:
Sub getData1()
On Error GoTo ErrHandler:
''Finding Row Information
Dim Ticker As String
Dim rCount As Integer, i As Integer, j As Integer, rcCount As Integer, rowStr As String
rCount = Application.CountA([RDRows])
rcCount = Application.CountA([RDCols])
Myfile = "H:\wkoorbusch\Desktop\" & "CFTC_Fin_Data.txt"
Dim fnum As Integer
fnum = FreeFile
Open Myfile For Output As fnum
For i = 1 To rCount
For j = 1 To rcCount
rowStr = [Start].Offset(i, 0).Value & "," & [Start].Offset(0, j).Value _
& "," & Format([Start].Offset(i, 2).Value, _
"mm/dd/yyyy") & "," & [Start].Offset(i, j).Value
Print #fnum, rowStr
Next j
Next i
Close fnum
Exit Sub
ErrHandler:
Close fnum
End Sub
Thanks in advance for any and all help.
Place the Text and its replacement in 2 colums of your spreadsheet, then use
On Error Resume Next
Application.WorksheetFunction.VLookup(MyText,range("Sheet1!A1:B300"),2,False)
If Err.Number=1004 then msgbox "Value " & MyText & " not found"
to return the replacement text.
A trappable err.Number of 1004 is returned when the lookup value is not found.
(functionally equivalent to VLOOKUP as a spreadsheet formula)

Grab formulas from closed Excel file (not just values)

I'm able to grab values from a closed workbook with the widely found GetValues function; it works great.
But sometimes I need to grab the formula of a cell from the closed workbook. I tried modifying GetValues to grab the cells formula but I'm getting errors.
How to get a formula (not simple value) of cells from a closed excel file?
With Sheets
For r = 2 To NewRowQty ' from second row to last row
For c = 1 To ThisColumnEnd ' out to EndColumn (from import dialogue box)
ThisCell = Cells(r, c).Address
ThisValue = GetValue(ThisPath, ThisFile, ThisSheet, ThisCell)
If ThisValue <> "0" Then
If c = 3 And r > 2 Then
Cells(r, c).Formula = GetFormula(ThisPath, ThisFile, ThisSheet, ThisCell)
Else
Cells(r, c) = ThisValue
End If
End If
Next c
Next r
End With
Calls these two functions, GetValue works fine, GetFormula won't grab the formula.
Private Function GetValue(p, f, s, c)
'p: path: The drive and path to the closed file (e.g., "d:\files")
'f: file: The workbook name (e.g., "budget.xls")
's: sheet: The worksheet name (e.g., "Sheet1")
'c: cell: The cell reference (e.g., "C4")
'Retrieves a value from a closed workbook
Dim arg As String
'Make sure the file exists
If Right(p, 1) <> "\" Then p = p & "\"
If Dir(p & f) = "" Then
GetValue = "File Not Found"
Exit Function
End If
'Create the argument
arg = "'" & p & "[" & f & "]" & s & "'!" & _
Range(c).Range("A1").Address(, , xlR1C1)
'Execute an XLM macro
GetValue = ExecuteExcel4Macro(arg)
End Function
Private Function GetFormula(p, f, s, c)
'p: path: The drive and path to the closed file (e.g., "d:\files")
'f: file: The workbook name (e.g., "budget.xls")
's: sheet: The worksheet name (e.g., "Sheet1")
'c: cell: The cell reference (e.g., "C4")
'Retrieves a value from a closed workbook
Dim arg As String
'Make sure the file exists
If Right(p, 1) <> "\" Then p = p & "\"
If Dir(p & f) = "" Then
GetFormula = "File Not Found"
Exit Function
End If
'Create the argument
arg = "'" & p & "[" & f & "]" & s & "'!" & _
Range(c).Range("A1").Address(, , xlR1C1).Formula
'Execute an XLM macro
GetFormula = ExecuteExcel4Macro(arg)
End Function
Update: Joel's first code post was the basis of what I ended up using so I marked that correct. Here's my actual implementation using a copy paste of entire row formulas. This is best because I don't know how many columns out may contains values or formulas, could be C or ZZ.
' silent opening of old file:
Application.EnableEvents = False
Set o = GetObject(FileTextBox.Text)
With Sheets
For r = 2 To NewRowQty ' from second row to last row
ThisCell = "A" & r
o.Worksheets(ThisRate).Range(ThisCell).EntireRow.Copy
Sheets(ThisRate).Range(ThisCell).PasteSpecial xlFormulas
Next r
End With
' Close external workbook, don't leave open for extended periods
Set o = Nothing
Application.EnableEvents = True
Why such convoluted code? The code you are using, for some reason, is invoking the Excel 4.0 backwards compatibility mode macro processor. I can't imagine why you would do that.
Here's a simple way to get the formula from cell Sheet1!A1 of c:\tmp\book.xlsx:
Dim o As Excel.Workbook
Set o = GetObject("c:\tmp\Book.xlsx")
MsgBox o.Worksheets("Sheet1").Cells(1, 1).Formula
Set o = Nothing ' this ensures that the workbook is closed immediately
If you insist on running Excel 4 - style macros (obsolete in 1994!) you need to use the XLM function GET.FORMULA to retrieve the formula instead of the value as follows:
arg = "GET.FORMULA('" & p & "[" & f & "]" & s & "'!" & _
Range(c).Range("A1").Address(, , xlR1C1) & ")"
Note that the result will have formulas using R1C1 notation instead of A1 notation.
Converting back to A1 notation (if you really want to do that) is left as an exercise to the reader.

Resources