Excel VBA Macro Run time 53 file not found - excel

I created a macro to rename files, but received this error:
Run-time error 53 File not found
But if I keep my cursor, it picks my location path correctly
"Name folder & Curname As folder & Newname"
Sub getname()
Dim folder As String
mfolder = Sheets("Sheet1").Cells(1, 2).Value
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
i = 3
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(mfolder)
For Each objFile In objFolder.Files
Sheets("Sheet1").Cells(i, 1).Value = objFile.Name
i = i + 1
Next objFile
End Sub
Sub reName()
Dim mfolder As String
Dim CurName As String
Dim NewName As String
Dim i As Integer
i = 3
mfolder = Sheets("Sheet1").Cells(1, 2).Value
Do While Sheets("Sheet1").Cells(i, 1).Text <> "" And Sheets("Sheet1").Cells(i, 2).Text <> ""
CurName = Sheets("Sheet1").Cells(i, 1).Text
NewName = Sheets("Sheet1").Cells(i, 2).Text
Name mfolder & CurName As mfolder & NewName
i = i + 1
Loop
MsgBox ("Complete")
End Sub

As a rule of thumb I would always use early binding of Microsoft scripting runtime. This gives you access to intellisense and other benefits when using external references.
Tools >> references
Once added you import the object reference as follows.
dim fso as filesystemobject
set fso = new filesystemobject
this allows you to do things like this.
dim fldr as fldr
set fldr = fso.getfolder("c:\test_folder")
and iterating through files
dim fl as file
for each fl in fldr.files
do something
next fl
It always helps me personally to see what options are available when using a new reference in VBA .
(when using late binding like you are you don't have this luxury)
and mainly renaming files
fldr.move("C:\test_folder2")
In my opinion you should store the path of the file
objFile.path not objFile.Name
this would store something like C:\test\test.text
so fix with getting the list of files
Function list_files():
' log all files
Dim fso As filesystemobject
Set fso = New filesystemobject
Dim fldr As fldr
Set fldr = fso.getfolder("c:\test_folder")
Dim fl as file
Dim ws As Worksheet
Set ws = Worksheets("sheet1")
Dim i As Integer
i = 2
For Each fl In fldr.Files
ws.Cells(i, 1) = fl.Path
Next fl
End Function
and renaming
Function rename_files():
' log all files
Dim fso As filesystemobject
Set fso = New filesystemobject
Dim fl As file
Dim ws As Worksheet
Set ws = Worksheets("sheet1")
Dim lr As Integer
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row
For x = 2 To lr
If ws.Cells(x, 2) <> "" Then
Set fl = fso.getfile(ws.Cells(x, 1))
fl.Move (ws.Cells(x, 2))
End If
Next x
End Function
Something else to note is that when iterating through cells its always best practice to use something along the lines of this.
dim ws as worksheet
set ws = worksheets("Sheet1") ' get the worksheet
dim lr as integer ' create lr interger reference
lr = ws.cells(rows.count,1).end(xlup).row
for x = 2 to lr
'do something
next x
lets break down whats happening here.
ws.cells(rows.count,1).end(xlup).row
ws in the worksheet
cells in the cells
rows.count get the last row
1 in column one
so....
ws.cells(rows.count,1) is referencing ALL cells in column 1
then....
.end(xlup) goes upwards to where the data starts (or the blank lines end)
row logs the row number
Then when you do your for loop you are not checking for the empty cells as you already know where it is.
for x = 2 to lr 'the last row in the data with data in it.
if ws.cells(x,2) <> "" then
'do something because column 1 and 2 both have no value in the cell
end if
next x
hope this helps somewhat

Related

Import Multiple Text with pre-defined header in worksheet

Below script works perfect for importing multiple text files without duplicate header. But, requirement is paste the data in second row of worksheet. In first row, there is Import button for calling macro. But, as soon as execution completes first row is vanished and data is pasted.
Sub ReadFilesIntoActiveSheet()
Dim fso As FileSystemObject
Dim folder As folder
Dim file As file
Dim FileText As TextStream
Dim TextLine As String
Dim Items() As String
Dim i As Long
Dim cl As Range
Dim sFolder As String, vDB, Ws As Worksheet
Dim rngT As Range
' Get a FileSystem object
Set fso = New FileSystemObject
' get the directory you want
sFolder = "G:\Team Learning\vbapractice\Dunning\Import\"
Set folder = fso.GetFolder(sFolder)
' set the starting point to write the data to
'Worksheets("Sheet1").Activate
'Set Ws = ActiveSheet
Set Ws = Sheets("Data")
'Set cl = ActiveSheet.Cells(1, 1)
Ws.Cells.Clear
' Loop thru all files in the folder
For Each file In folder.Files
i = i + 1
Workbooks.Open Filename:=sFolder & file.Name, Format:=1
With ActiveWorkbook.ActiveSheet
If i = 1 Then
vDB = .UsedRange
Else
vDB = .UsedRange.Offset(1)
End If
End With
ActiveWorkbook.Close
Set rngT = Ws.Range("a" & Rows.Count).End(xlUp)(2) ' it's lastrow +1
rngT.Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
Next file
Ws.Range("a1").EntireRow.Delete
Set FileText = Nothing
Set file = Nothing
Set folder = Nothing
Set fso = Nothing
End Sub

How to adapt this to work with another worksheet?

How do I adapt this to work with another worksheet rather than the worksheet I have visible.
If (IsEmpty(Cells(RowNum, ColumnNum).Value)) Then
GoTo nextloop:
End If
I have moved parenthesis, tried including workbook name but I think I'm just not getting the syntax. I'm not very good with excel.
What I'm trying to achieve. Take all contents of a column, push the data into a bat file. Script will be launched from a button on another worksheet.
UPDATED Full Code: (Tried Ryan's answer, was getting error. Fixed it but then the script did nothing.)
Sub Send2Bat()
Dim ColumnNum: ColumnNum = 26 ' Column Z - I have the I J and K Columns concatenated there.
Dim RowNum: RowNum = 0
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("C:\Test\Convert.bat") 'Output Path
aFile = "C:\Test\Convert.bat"
Dim OutputString: OutputString = ""
Dim LastRow: LastRow = Application.ActiveSheet.Cells(Application.ActiveSheet.Rows.Count, ColumnNum).End(xlUp).Row
Do
nextloop:
RowNum = RowNum + 1
If (IsEmpty(Cells(RowNum, ColumnNum).Value)) Then
GoTo nextloop:
End If
OutputString = OutputString & Replace(Cells(RowNum, ColumnNum).Value, Chr(10), vbNewLine) & vbNewLine
Loop Until RowNum = LastRow
objFile.Write (OutputString)
Set objFile = Nothing
Set objFSO = Nothing
End Sub
I made an excel workbook and put some data in column z for Sheet 1 and Sheet 2.
And I tweaked your code to read as follows:
Sub Send2Bat()
Dim ColumnNum: ColumnNum = 26 ' Column Z - I have the I J and K Columns concatenated there.
Dim RowNum: RowNum = 0
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("C:\Test\Convert.bat") 'Output Path
aFile = "C:\Test\Convert.bat"
Dim OutputString: OutputString = ""
Dim targetSheet As Worksheet
Set targetSheet = Application.Worksheets("Sheet1")
Dim LastRow: LastRow = targetSheet.Cells(targetSheet.Rows.Count, ColumnNum).End(xlUp).Row
Do
RowNum = RowNum + 1
If Not (IsEmpty(targetSheet.Cells(RowNum, ColumnNum).Value)) Then
OutputString = OutputString & Replace(targetSheet.Cells(RowNum, ColumnNum).Value, Chr(10), vbNewLine) & vbNewLine
End If
Loop Until RowNum = LastRow
objFile.Write (OutputString)
Set objFile = Nothing
Set objFSO = Nothing
End Sub
And it produced the following file:
So then I updated the targetSheet name to "Sheet2"
Set targetSheet = Application.Worksheets("Sheet2")
and executed again. The file updated to this:
So, the code is good at least in its basic form. Do you have anything else updating the sheets or moving things around while this is happening?

How to copy/paste only certain files from all folders and all sub-folders?

I am trying to come up with a routine that copies only certain files out of a directory, and all sub-directories, and pastes each copied file into a destination directory. I came up with the code below, which copies all files, in a filtered list, into a destination folder, but I can't figure out how to do a recursive loop through the hierarchy. Any guidance on this would be greatly appreciated.
Sub CopyFilteredFiles()
Dim rng As Range, cell As Range
Dim sht As Worksheet
Dim LastRow As Long
Dim FSO As Object
Dim FromPath As String
Dim ToPath As String
Dim lastChar As Integer
Dim fileName As String
DestinationFolder = "C:\Users\ryans\OneDrive\Desktop\AllYAML\"
Set sht = ActiveSheet
LastRow = sht.Cells(sht.Rows.Count, "D").End(xlUp).Row
Set rng = Range("D14:D" & LastRow)
Set FSO = CreateObject("scripting.filesystemobject")
For Each cell In rng.SpecialCells(xlCellTypeVisible)
If cell.Value <> "" Then
CopyFile = cell.Value
Debug.Print cell.Value
lastChar = InStrRev(CopyFile, "\")
fileName = Mid(CopyFile, lastChar + 1, 199)
On Error Resume Next
FSO.CopyFile Source:=CopyFile, Destination:=DestinationFolder & fileName
End If
Next cell
End Sub

Concatenate index name in the Workbooks Object

I am trying to create For Each loop for a several workbooks; however I am not able to set the workbook name in the array and thus resulted into this. I'm stuck in trying to concatenate the workbook name.
Here's my code:
'Open all .csv file in folder location
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(ThisWorkbook.Path)
For Each objFile In objFolder.Files
If InStr(objFile, ".csv") Then
Workbooks.Open (objFile)
End If
Next
' Declare variables
Dim WrkBkPrm As Workbook
Dim WrkBkSrc As Workbook
Dim WrkShtPrm As Worksheet
Dim WrkShtSrc As Worksheet
Dim TextSrc(4) As String
Dim SrcRng As Range
Dim DRng As Range
' Assign values to TextSrc() Array
TextSrc(0) = Cable
TextSrc(1) = Care
TextSrc(2) = MSD
TextSrc(3) = Business
'Set WrkBkPrm and WrkShtPrm values
Set WrkBkPrm = Workbooks("MasterFile" & ".xlsm")
Set WrkShtPrm = WrkBkPrm.Worksheets("Canvas")
'Activate Canvas Sheet
WrkBkPrm.Activate
WrkShtPrm.Select
Application.ScreenUpdating = False
'Start For Each Loop
For Each Src In TextSrc()
Set WrkBkSrc = Workbooks(Src & ".csv")
Set WrkShtSrc = WrkBkSrc.Worksheets(Src)
'Copy loop for 1st section
For i = 2 To 49
For j = 7 To 25
Set SrcRng = WrkShtSrc.Cells(i, j)
Set DRng = WrkShtPrm.Cells(i, j)
If SrcRng <> "" Then
DRng.Value = SrcRng.Value
End If
Next j
Next i
Next Src
Application.ScreenUpdating = True
I'd suggest you work on the file as soon as you get hold of the relevant info you need.
Something like:
Dim wb As Workbook
For Each objFile In objFolder.Files
If InStr(objFile.Name, ".csv") <> 0 Then
Set wb = Workbooks.Open(Thisworkbook.Path & "\" & objFile.Name)
'~~> Do your cool stuff with the opened CSV File
wb.Close False '~~> Close without saving
Set wb = Nothing '~~> Clean up although most of the time not necessary
End If
Next
As for the route you took, for you to use For Each Loop on TxtSrc, you need to declare it as variant.
Something like:
Dim TxtSrc As Variant, Src As Variant
TxtSrc = Array("Cable", "Care", "MSD", "Business")
For Each Src In TxtSrc
Set wb = Workbooks.Open(Thisworkbook.Path & "\" & Src & ".csv")
'~~> More cool stuff here
wb.Close False
Set wb = Nothing
Next
It is important that provide the correct argument for the Workbook Open Method.
You should always include the complete path in string format. HTH.

Loop code keeps copying from the same excel spreadsheet in a folder

So I was trying to create a list of excel files in a folder (file name and path) and then use a For loop to copy and paste a specified worksheet for all of the files listed into a specified worksheet in the excel workbook that contains the macro. So far everything works except for the fact that the same file keeps getting copied and pasted over instead of all the files. The macro loops for the correct number of times, but it's not using all the excel files.
Here's the code:
First part for listing the files in the folder
Private Sub btn_LeaveReport()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder("D:\Administration\Time Sheets")
i = 2
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
Cells(i + 1, 2) = objFile.Name
'print file path
Cells(i + 1, 3) = objFile.Path
i = i + 1
Next objFile
End Sub
and this is the part for the loop
Private Sub btn_PullData()
'Declared Variables
Dim wbk As Workbook
Dim i As Integer
Dim StartAt As Integer
Dim EndAt As Integer
Dim CopyPath As String
Dim CopyPathRow As Integer
Dim iRow As Integer
'Ranges
StartAt = 1
EndAt = Val(ThisWorkbook.Worksheets("LeaveReport").Range("A1"))
CopyPathRow = 3
CopyPath = ThisWorkbook.Worksheets("LeaveReport").Range("C" & CopyPathRow)
iRow = 3
'Loop de loop
For i = StartAt To EndAt
Application.ScreenUpdating = False
Set wbk = Workbooks.Open(CopyPath)
Sheets("TIMESHEET").Select
Range("C12:S34").Select
Selection.Copy
ThisWorkbook.Activate
Sheets("Pastebin").Select
Range("a" & iRow).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
iRow = iRow + 39
CopyPathRow = CopyPathRow + 1
wbk.Close True
Next i
Sheets("Pastebin").Select
Range("A:A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Application.ScreenUpdating = True
MsgBox "Timesheet Data Imported"
End Sub
Based on the source of the error, i.e. same file being used, I'm guessing the issue lies with the part that has this:
CopyPath = ThisWorkbook.Worksheets("LeaveReport").Range("C" & CopyPathRow)
and is "supposed" to update in the For loop via this:
CopyPathRow = CopyPathRow + 1
Move the line
CopyPath = ThisWorkbook.Worksheets("LeaveReport").Range("C" & CopyPathRow)
Inside the loop, that value of CopyPath is never being changed, but the value of CopyPathRow is.
Edit: I wouldn't call this recursion either.

Resources