I learnt how to copy multiple files from a single folder to multiple folders depending on file name in Excel sheet.
Sub MoveSelectedfiles()
Dim FSO As Scripting.FileSystemObject
Dim fl As Scripting.File
Dim sourcefldr As Scripting.Folder
Dim destinationFldr As Scripting.Folder
Dim index As Integer
Dim lastrow As Integer
Set FSO = New FileSystemObject
Set sourcefldr = FSO.GetFolder("E:\Testing\Source")
Set destinationFldr = FSO.GetFolder("E:\Testing\Destination")
lastrow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
For index = 2 To 10
If (FSO.FileExists(sourcefldr.Path & "\" & Sheet1.Range("A" & index).Value)) Then
FSO.MoveFile sourcefldr.Path & "\" & Sheet1.Range("A" & index).Value, destinationFldr.Path & "\"
End If
Next index
End Sub
I have to define the exact file name. I would like to write even half/incomplete file name.
E.g. If a file name is "Excel training makes easy" and in the Excel sheet I write "Excel training".
Move Files From a List of Partial File Names
You can use the Dir function with wild characters (* and ?) to test if a file exists, e.g.:
Begins with
sFileName = Dir(sFolderPath & sPartialFileName & "*")
Contains
sFileName = Dir(sFolderPath & "*" & sPartialFileName & "*")
Then you can continue with:
if len(sFileName) > 0 Then ' source file found
Partial File Names
Sub MoveFilesFromListPartial()
Const sPath As String = "E:\Testing\Source"
Const dPath As String = "E:\Testing\Destination"
Const fRow As Long = 2
Const Col As String = "A"
' Reference the worksheet.
Dim ws As Worksheet: Set ws = Sheet1
' Calculate the last row,
' i.e. the row containing the last non-empty cell in the column.
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, Col).End(xlUp).Row
' Validate the last row.
If lRow < fRow Then
MsgBox "No data in column range.", vbCritical
Exit Sub
End If
' Early Binding - needs a reference
' to 'Tools > References > Microsoft Scripting Runtime' (has intelli-sense)
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
' Late Binding - needs no reference (no intelli-sense)
'Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
' Validate the source folder path.
Dim sFolderPath As String: sFolderPath = sPath
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Not fso.FolderExists(sFolderPath) Then
MsgBox "The source folder path '" & sFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
' Validate the destination folder path.
Dim dFolderPath As String: dFolderPath = dPath
If Right(dFolderPath, 1) <> "\" Then dFolderPath = dFolderPath & "\"
If Not fso.FolderExists(dFolderPath) Then
MsgBox "The destination folder path '" & dFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
Dim r As Long ' current row in worksheet column
Dim sFilePath As String
Dim sPartialFileName As String
Dim sFileName As String
Dim dFilePath As String
Dim sYesCount As Long ' source file moved
Dim sNoCount As Long ' source file not found
Dim dYesCount As Long ' source file exists in destination folder
Dim BlanksCount As Long ' blank cell
For r = fRow To lRow
sPartialFileName = CStr(ws.Cells(r, Col).Value)
If Len(sPartialFileName) > 0 Then ' the cell is not blank
' 'Begins with' sPartialFileName
sFileName = Dir(sFolderPath & sPartialFileName & "*")
' or instead, 'Contains' sPartialFileName
'sFileName = Dir(sFolderPath & "*" & sPartialFileName & "*")
If Len(sFileName) > 0 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.MoveFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
Else ' the cell is blank
BlanksCount = BlanksCount + 1
End If
Next r
MsgBox "Stats" & vbLf _
& "Source files moved: " & sYesCount & vbLf _
& "Source files not found: " & sNoCount & vbLf _
& "Source files existed in destination: " & dYesCount & vbLf _
& "Number of blank cells: " & BlanksCount & vbLf _
& "Number of cells processed: " & lRow - fRow + 1, _
vbInformation
End Sub
Full File Names
Sub MoveFilesFromList()
Const sPath As String = "E:\Testing\Source"
Const dPath As String = "E:\Testing\Destination"
Const fRow As Long = 2
Const Col As String = "A"
' Reference the worksheet.
Dim ws As Worksheet: Set ws = Sheet1
' Calculate the last row,
' i.e. the row containing the last non-empty cell in the column.
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, Col).End(xlUp).Row
' Validate the last row.
If lRow < fRow Then
MsgBox "No data in column range.", vbCritical
Exit Sub
End If
' Early Binding - needs a reference
' to 'Tools > References > Microsoft Scripting Runtime' (has intelli-sense)
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
' Late Binding - needs no reference (no intelli-sense)
'Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
' Validate the source folder path.
Dim sFolderPath As String: sFolderPath = sPath
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Not fso.FolderExists(sFolderPath) Then
MsgBox "The source folder path '" & sFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
' Validate the destination folder path.
Dim dFolderPath As String: dFolderPath = dPath
If Right(dFolderPath, 1) <> "\" Then dFolderPath = dFolderPath & "\"
If Not fso.FolderExists(dFolderPath) Then
MsgBox "The destination folder path '" & dFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
Dim r As Long ' current row in worksheet column
Dim sFilePath As String
Dim sFileName As String
Dim dFilePath As String
Dim sYesCount As Long ' source file moved
Dim sNoCount As Long ' source file doesn't exist
Dim dYesCount As Long ' source file exists in destination folder
Dim BlanksCount As Long ' blank cell
For r = fRow To lRow
sFileName = CStr(ws.Cells(r, Col).Value)
If Len(sFileName) > 0 Then ' the cell is not blank
sFilePath = sFolderPath & sFileName
If fso.FileExists(sFilePath) Then ' the source file exists
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.MoveFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination folder
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
Else ' the cell is blank
BlanksCount = BlanksCount + 1
End If
Next r
MsgBox "Stats" & vbLf _
& "Source files moved: " & sYesCount & vbLf _
& "Source files don't exist: " & sNoCount & vbLf _
& "Source files existed in destination: " & dYesCount & vbLf _
& "Number of blank cells: " & BlanksCount & vbLf _
& "Number of cells processed: " & lRow - fRow + 1, _
vbInformation
End Sub
Related
I wanted to import or copy and paste data from an external file into the current Excel file using VBA. However, the external file contain a date of the previous month in it. For example, the external file name is Report_20221128. Every month, this external file date maybe different and not necessary be 28 of the month.
Here is what I have done so far.
Sub Report_Run()
Dim wb As Workbook
Dim file As Variant
Dim wbrow As Long, wbrow2 As Long, wbrow3 As Long
Day = Application.WorksheetFunction.EoMonth(Now(), "-1")
Set wb = Workbooks("Run Report " & VBA.Format(LDay, "ddmmyyyy") & ".xlsb")
wb.Worksheets("DD").Activate
wbrow3 = Cells(Rows.Count, "A").End(xlUp).Row
file = Dir(Environ("userprofile") & "\Desktop\Reports\Report_" & Format(Date, "yyyymmdd") & ".xlsx")
End Sub
However, the code unable to read on this line
file = Dir(Environ("userprofile") & "\Desktop\Reports\Report_" & Format(Date, "yyyymmdd") & ".xlsx")
Therefore, how should I set the code so that it can read this external file that contain any date of the previous month in it?
Import Worksheet From File Matching a Pattern
Sub ImportLastMonth()
' Constants
Const SRC_PATH_RIGHT As String = "\Desktop\Reports\"
Const SRC_FILE_LEFT As String = "Report_"
Const SRC_FILE_RIGHT As String = ".xlsx"
Const SRC_WORKSHEET_ID As Variant = "Sheet1" ' adjust! Name or Index
' Source Path
Dim sPathLeft As String: sPathLeft = Environ("USERPROFILE")
Dim sPath As String: sPath = sPathLeft & SRC_PATH_RIGHT
Dim sFolderName As String: sFolderName = Dir(sPath, vbDirectory)
If Len(sFolderName) = 0 Then
MsgBox "The path '" & sPath & "' was not found.", vbCritical
Exit Sub
End If
' Source File
Dim sPatternLeft As String: sPatternLeft = SRC_FILE_LEFT _
& Format(CDate(Application.EoMonth(Now, "-1")), "yyyymm")
Dim sPattern As String: sPattern = sPatternLeft & "*" & SRC_FILE_RIGHT
Dim sFileName As String: sFileName = Dir(sPath & sPattern)
If Len(sFileName) = 0 Then
MsgBox "No files matching the pattern '" & sPattern & "' in '" _
& sPath & "' found.", vbCritical
Exit Sub
End If
' Day
Dim DayStart As Long: DayStart = Len(sPatternLeft) + 1
Dim DayNumString As String, DayNum As Long, NewDayNum As Long
Do While Len(sFileName) > 0
DayNumString = Mid(sFileName, DayStart, 2)
If IsNumeric(DayNumString) Then
NewDayNum = CLng(DayNumString)
If NewDayNum > DayNum Then DayNum = NewDayNum
End If
Debug.Print sFileName, DayNumString, NewDayNum, DayNum
sFileName = Dir
Loop
If DayNum = 0 Then
MsgBox "No file found.", vbCritical
Exit Sub
End If
Application.ScreenUpdating = False
' Source
Dim sFilePath As String
sFilePath = sPath & sPatternLeft & Format(DayNum, "0#") & SRC_FILE_RIGHT
Dim swb As Workbook: Set swb = Workbooks.Open(sFilePath, True, True)
Dim sws As Worksheet: Set sws = swb.Sheets(SRC_WORKSHEET_ID)
' Destination
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
' Copy
sws.Copy After:=dwb.Sheets(dwb.Sheets.Count) ' last
swb.Close SaveChanges:=False
Application.ScreenUpdating = True
' Inform.
MsgBox "Last month's final report imported.", vbInformation
End Sub
Using FileSystemObject and Like
Option Explicit
Sub Report_Run()
Dim wb As Workbook, TargetWB As Workbook
Dim DT As Date
Dim wbrow As Long, wbrow2 As Long, wbrow3 As Long
Dim FSO As Object, oFolder As Object, oFile As Object
Set FSO = CreateObject("scripting.filesystemobject")
' > This needs to be the folder you expect to contain your report
Set oFolder = FSO.getfolder("C:\Users\cameron\Documents\")
' > Date is already a VBA function, you have to use a different variable
DT = Application.WorksheetFunction.EoMonth(Date, "-1")
' > I have this set to "ThisWorkbook" as it's fewer things to worry about, but feel free to change this. _
What is LDay? \|/ you don't have this variable declared
Set wb = ThisWorkbook 'workbooks("Run Report " & VBA.Format(LDay, "ddmmyyyy") & ".xlsb")
' > Avoid using activate
wbrow3 = wb.Worksheets("DD").Cells(Rows.Count, "A").End(xlUp).Row
' > Check each file to see if they're from last month
For Each oFile In oFolder.Files
If oFile.Name Like "Report_" & Format(DT, "yyyymm") & "*" & ".xlsb" Then 'Report name with wildcard for day
Set TargetWB = Workbooks.Open(oFile.Path)
Exit For
End If
Next oFile
' > You now have the report book from last month open and saved to "TargetWB"
End Sub
Below mentioned code successfully copies the file based on source names mentioned in excel sheet using moveFilesFromListPartial, it works perfectly well. i just need one change in the code.
e.g. in excel sheet a source name is written as "Robert Anderson" However if a file with incorrect spelling like "Robert Andersonn" or "Robertt Anderson" comes into source folder, these file with incorrect spelling should get copy in another folder (e.g. Error Folder). In other words files whose exact source name is not in excel sheet should get copy to another folder rather than the destination folder. This way at the end of day we can identify which file names have spelling mistakes and we can simply correct them without reviewing all the files.
currently these kind of files remain stuck in source folder and because of incorrect file name they do not get copy, and i have added another macro which after some times moved the file from Source folder to Archive folder.
Sub moveFilesFromListPartial()
Const sPath As String = "E:\Uploading\Source"
Const dPath As String = "E:\Uploading\Destination"
Const fRow As Long = 2
Const Col As String = "B", colExt As String = "C"
' Reference the worksheet.
Dim ws As Worksheet: Set ws = Sheet2
' Calculate the last row,
' i.e. the row containing the last non-empty cell in the column.
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, Col).End(xlUp).Row
' Validate the last row.
If lRow < fRow Then
MsgBox "No data in column range.", vbCritical
Exit Sub
End If
' Early Binding - needs a reference
' to 'Tools > References > Microsoft Scripting Runtime' (has intelli-sense)
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
' Late Binding - needs no reference (no intelli-sense)
'Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
' Validate the source folder path.
Dim sFolderPath As String: sFolderPath = sPath
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Not fso.FolderExists(sFolderPath) Then
MsgBox "The source folder path '" & sFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
' Validate the destination folder path.
Dim dFolderPath As String: dFolderPath = dPath
If Right(dFolderPath, 1) <> "\" Then dFolderPath = dFolderPath & "\"
If Not fso.FolderExists(dFolderPath) Then
MsgBox "The destination folder path '" & dFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
Dim r As Long ' current row in worksheet column
Dim sFilePath As String
Dim sPartialFileName As String
Dim sFileName As String
Dim dFilePath As String
Dim sYesCount As Long ' source file moved
Dim sNoCount As Long ' source file not found
Dim dYesCount As Long ' source file exists in destination folder
Dim BlanksCount As Long ' blank cell
Dim sExt As String 'extension (dot inclusive)
For r = fRow To lRow
sPartialFileName = CStr(ws.Cells(r, Col).Value)
sExt = CStr(ws.Cells(r, colExt).Value)
If Len(sPartialFileName) > 3 Then ' the cell is not blank
' 'Begins with' sPartialFileName
sFileName = Dir(sFolderPath & sPartialFileName & "*" & sExt)
Do While sFileName <> ""
If Len(sFileName) > 3 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.CopyFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
sFileName = Dir
Loop
Else ' the cell is blank
BlanksCount = BlanksCount + 1
End If
Next r
End Sub
Another Code which I run after copying the file to Destination folder which moves the files from Source to Archive folder.
Sub moveAllFilesInDateFolderIfNotExist()
Dim DateFold As String, fileName As String, objFSO As Object
Const sFolderPath As String = "E:\Uploading\Source"
Const dFolderPath As String = "E:\Uploading\Archive"
DateFold = dFolderPath & "\" & Format(Date, "ddmmyyyy") ' create the folder
if it does not exist
If Dir(DateFold, vbDirectory) = "" Then MkDir DateFold
fileName = Dir(sFolderPath & "\*.*")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Do While fileName <> ""
If Not objFSO.FileExists(DateFold & "\" & fileName) Then
Name sFolderPath & "\" & fileName As DateFold & "\" & fileName
Else
Kill DateFold & "\" & fileName
Name sFolderPath & "\" & fileName As DateFold & "\" & fileName
End If
fileName = Dir
Loop
End Sub
Please, use the next updated (your macro):
Sub AddMissingItems()
Dim Dic As Object, arr() As Variant, outArr() As Variant
Dim i As Long, k As Long, iRow As Long, c As Long
Dim r As Long, j As Long
Set Dic = CreateObject("Scripting.dictionary")
With Sheets("Sheet1")
arr = .Range("A1:A" & .Range("A" & .rows.count).End(xlUp).row).Value
For i = 1 To UBound(arr, 1)
If Dic.Exists(arr(i, 1)) = False Then
Dic.Add (arr(i, 1)), ""
End If
Next
End With
With Workbooks("ExtractFile.xlsx").Worksheets("Sheet1")
c = .cells(1, Columns.count).End(xlToLeft).column
r = .Range("A" & .rows.count).End(xlUp).row 'calculate the last row in A:A, too
arr = .Range("A1", .cells(r, c)).Value 'place in the array all existing columns
ReDim outArr(1 To UBound(arr), 1 To c) 'extend the redimmed array to all columns
For i = 1 To UBound(arr)
If Dic.Exists(arr(i, 1)) = False Then
k = k + 1
For j = 1 To c 'iterate between all array columns:
outArr(k, j) = arr(i, j) 'place the value from each column
Next j
End If
Next
End With
iRow = Sheets("Sheet1").Range("A" & rows.count).End(3).row + 1
If k <> 0 Then
Sheets("Sheet1").Range("A" & iRow).Resize(k, UBound(arr, 2)).Value = outArr 'resize by columns, too
k = 0
End If
End Sub
Sub moveFilesFromListPartial()
Const sPath As String = "E:\Uploading\Source", dPath As String = "E:\Uploading\Destination"
Const Col As String = "B", colExt As String = "C"
' Reference the worksheet.
Dim ws As Worksheet: Set ws = Sheet2
' Calculate the last row,
Dim lRow As Long: lRow = ws.cells(ws.rows.count, Col).End(xlUp).row
' Validate the last row.
If lRow < 2 Then MsgBox "No data in column range.", vbCritical: Exit Sub
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
' Validate the source folder path.
Dim sFolderPath As String: sFolderPath = sPath
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Not fso.FolderExists(sFolderPath) Then
MsgBox "The source folder path '" & sFolderPath & "' doesn't exist.", vbCritical: Exit Sub
End If
' Validate the destination folder path.
Dim dFolderPath As String: dFolderPath = dPath
If Right(dFolderPath, 1) <> "\" Then dFolderPath = dFolderPath & "\"
If Not fso.FolderExists(dFolderPath) Then
MsgBox "The destination folder path '" & dFolderPath & "' doesn't exist.", vbCritical: Exit Sub
End If
Dim r As Long, sFilePath As String, sPartialFileName As String, sFileName As String
Dim dFilePath As String, sExt As String 'extension (dot inclusive)
'_________________________________________________________________________________
Dim arrC, k As Long 'an array to keep the copied fileNames and a variable to keep
'the next array element to be loaded
Dim objFolder As Object: Set objFolder = fso.GetFolder(sPath)
ReDim arrC(objFolder.files.count) 'redim the array at the number of total files
'_________________________________________________________________________________
For r = 2 To lRow
sPartialFileName = CStr(ws.cells(r, Col).Value)
sExt = CStr(ws.cells(r, colExt).Value)
If Len(sPartialFileName) > 3 Then ' the cell is not blank
sFileName = Dir(sFolderPath & sPartialFileName & "*" & sExt)
Do While sFileName <> ""
If Len(sFileName) > 3 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the destination file...
fso.CopyFile sFilePath, dFilePath ' ... if doesn't exist...
'________________________________________________________________________
arrC(k) = sFileName: k = k + 1 'each copied file name is loaded in the array
'________________________________________________________________________
Else
'______________________________________________________________________
arrC(k) = sFileName: k = k + 1 'each copied file name is loaded in the array
'________________________________________________________________________
End If
End If
sFileName = Dir
Loop
End If
Next r
'__________________________________________________________________________________
If k > 0 Then ReDim Preserve arrC(k - 1) 'keep in the array only loaded elements
moveReminedFiles sPath, arrC
'_________________________________________________________________________________
End Sub
All modifications are between '_______________ lines
Copy the next Sub, which is called by the above one, in the same module:
Sub moveReminedFiles(sFolder As String, arr)
Dim fileName As String, mtch
Const destFolder As String = "E:\Uploading\Error Files\" 'use here your folder where errored files to be moved
If Right(sFolder, 1) <> "\" Then sFolder = sFolder & "\"
fileName = Dir(sFolder & "*.*")
Do While fileName <> ""
mtch = Application.match(fileName, arr, 0) 'if the file name does not exist in the array:
If IsError(mtch) Then Name sFolder & fileName As destFolder & fileName 'move it
fileName = Dir
Loop
End Sub
Please, test it and send some feedback. Of course, the bushy code could not be tested...
Edited:
Please, try the next updated (former) Sub which comes after the above code, moving all files in the Archive folder. Now, it should also do what you required in this question. Since it is not tested, you should send some feedback after testing it:
Sub moveAllFilesInDateFolderIfNotExist(sFolderPath As String, arr)
Dim DateFold As String, fileName As String, objFSO As Object, mtch
Const dFolderPath As String = "E:\Uploading\Archive\"
Const errFolder As String = "E:\Uploading\Error Files\"
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
DateFold = dFolderPath & "\" & Format(Date, "ddmmyyyy") & "\" ' create the cur date folder name
If Dir(DateFold, vbDirectory) = "" Then MkDir DateFold 'create the necessary folder if it does not exist
fileName = Dir(sFolderPath & "\*.*")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Do While fileName <> ""
mtch = Application.match(fileName, arr, 0)
If IsError(mtch) Then 'if the file name does not exist in the array:
If objFSO.FileExists(errFolder & "\" & fileName) Then
Kill errFolder & fileName
End If
Name sFolderPath & fileName As errFolder & fileName 'move it
Else
If Not objFSO.FileExists(DateFold & "\" & fileName) Then
Name sFolderPath & fileName As DateFold & fileName
Else
Kill DateFold & fileName
Name sFolderPath & fileName As DateFold & fileName
End If
End If
fileName = Dir
Loop
End Sub
You only have to change moveReminedFiles sPath, arrC with moveAllFilesInDateFolderIfNotExist sPath, arrC and run it. Take care that now it will also move the files in the archive folder. Of course, except the wrong spelled ones which will be moved in their special Error folder...
Please, send some feedback after testing it.
I have multiple workbooks each having the same sheet. I want to Copy the sheet's value to the master book.
I want to copy the selected range value of each Workbook to the single row of the new workbook.
Also, how can I retrieve the options button caption from the source workbook? Where Option buttons are ActiveX and linked cells.
If the options button is checked, copy the options button caption value to the destination cell.
Also I wish to add yyyy , mm,dd values in Date format (yyyy/mm/dd)
Sub test1()
Dim Wsh As New IWshRuntimeLibrary.WshShell
Dim result As WshExec
Dim fileData() As String
Dim path As String
Dim cmd As String
path = ThisWorkbook.path & "\Book1"
cmd = "dir" & path & "/Test"
Set result = Wsh.Exec("%ComSpec% /c" & cmd)
Do While result.Status = 0
DoEvents
Loop
fileData = Split(result.StdOut.ReadAll, vbCrLf)
Dim i As Long
i = 4
For Each strData In fileData
Cells(i, 2).Value = strData
If Cells(i, 2).Value <> "" Then
Cells(i, 3).Value = "='" & path & "\[" & strData & "]sheet1'!F1" '
Cells(i, 4).Value = "='" & path & "\[" & strData & "]sheet1'!C4" '
End If
i = i + 1
Next
End Sub
Retrieve Data From Closed Workbooks 2
Sub RetrieveDataFromClosedWorkbooks2()
Const SOURCE_SUBFOLDER_NAME As String = "Book1"
Const SOURCE_FILE_PATTERN As String = "*.xlsx"
Const SOURCE_WORKSHEET_NAME As String = "Sheet1"
Const SOURCE_CELL_ADDRESSES_LIST As String = "F1,C4"
Const DESTINATION_WORKSHEET_NAME As String = "Sheet1"
Const DESTINATION_FIRST_CELL_ADDRESS As String = "B4"
Dim dwb As Workbook: Set dwb = ThisWorkbook
Dim dws As Worksheet: Set dws = dwb.Worksheets(DESTINATION_WORKSHEET_NAME)
Dim dCell As Range: Set dCell = dws.Range(DESTINATION_FIRST_CELL_ADDRESS)
Dim pSep As String: pSep = Application.PathSeparator
Dim sFolderPath As String
sFolderPath = dwb.Path & pSep & SOURCE_SUBFOLDER_NAME
If Right(sFolderPath, 1) <> pSep Then sFolderPath = sFolderPath & pSep
Dim sFileNames() As String
sFileNames = FileNamesToArray(sFolderPath, SOURCE_FILE_PATTERN)
If UBound(sFileNames) = -1 Then
MsgBox "No files found.", vbExclamation
Exit Sub
End If
Dim sAddresses() As String
sAddresses = Split(SOURCE_CELL_ADDRESSES_LIST, ",")
Dim sf As Long
Dim sa As Long
Dim dFormula As String
For sf = 0 To UBound(sFileNames)
dCell.Offset(sf).Value = sFileNames(sf) ' source file name
For sa = 0 To UBound(sAddresses)
dFormula = "='" & sFolderPath & "[" & sFileNames(sf) _
& "]" & SOURCE_WORKSHEET_NAME & "'!" & sAddresses(sa)
'Debug.Print dFormula
With dCell.Offset(sf, sa + 1)
'Debug.Print .Address, sf, sFileNames(sf), sa, sAddresses(sa)
.Formula = dFormula
'.Value = .Value ' to keep only values
End With
Next sa
Next sf
MsgBox "Data retrieved.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the names of all files of a folder in an array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FileNamesToArray( _
ByVal FolderPath As String, _
Optional ByVal FilePattern As String = "*.*") _
As String()
Const DirSwitches As String = "/b/a-d"
Dim pSep As String: pSep = Application.PathSeparator
If Right(FolderPath, 1) <> pSep Then FolderPath = FolderPath & pSep
Dim ExecString As String ' '%comspec%' or 'cmd.exe' ?
ExecString = "%comspec% /c Dir """ _
& FolderPath & FilePattern & """ " & DirSwitches
Dim pString As String
pString = CreateObject("WScript.Shell").Exec(ExecString).StdOut.ReadAll
If Len(pString) = 0 Then ' multiple issues: no file, invalid input(s)
FileNamesToArray = Split("") ' ensure string array: 'LB = 0, UB = -1'
Else
pString = Left(pString, Len(pString) - 2) ' remove trailing 'vbCrLf'
FileNamesToArray = Split(pString, vbCrLf)
End If
End Function
I have code to copy selected files (names mentioned in Excel sheet) from one folder to another/multiple via partial list
The current code copies one file at a time and not all (if the initial file names are same).
How can I copy/move all the files (specified in the sheet) from one folder to another?
Sub CopyFilesFromListPartial()
Const sPath As String = "E:\Testing\Source"
Const dpath As String = "E:\Testing\Destination"
Const fRow As Long = 2
Const Col As String = "A"
' Reference the worksheet.
Dim ws As Worksheet: Set ws = Sheet1
' Calculate the last row,
' i.e. the row containing the last non-empty cell in the column.
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, Col).End(xlUp).Row
' Early Binding - needs a reference
' to 'Tools > References > Microsoft Scripting Runtime' (has intelli-sense)
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
' Late Binding - needs no reference (no intelli-sense)
'Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
' Validate the source folder path.
Dim sFolderPath As String: sFolderPath = sPath
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Not fso.FolderExists(sFolderPath) Then
MsgBox "The source folder path '" & sFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
' Validate the destination folder path.
Dim dFolderPath As String: dFolderPath = dpath
If Right(dFolderPath, 1) <> "\" Then dFolderPath = dFolderPath & "\"
If Not fso.FolderExists(dFolderPath) Then
MsgBox "The destination folder path '" & dFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
Dim r As Long ' current row in worksheet column
Dim sFilePath As String
Dim sPartialFileName As String
Dim sFileName As String
Dim dFilePath As String
Dim sYesCount As Long ' source file copied
Dim sNoCount As Long ' source file not found
Dim dYesCount As Long ' source file exists in destination folder
Dim BlanksCount As Long ' blank cell
For r = fRow To lRow
sPartialFileName = CStr(ws.Cells(r, Col).Value)
If Len(sPartialFileName) > 3 Then ' the cell is not blank
' 'Begins with' sPartialFileName
sFileName = Dir(sFolderPath & sPartialFileName & "*")
' or instead, 'Contains' sPartialFileName
'sFileName = Dir(sFolderPath & "*" & sPartialFileName & "*")
If Len(sFileName) > 3 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.CopyFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
Else ' the cell is blank
BlanksCount = BlanksCount + 1
End If
Next r
End Sub
Process new files if the initial characters of file names are the same like this:
' 'Begins with' sPartialFileName
sFileName = Dir(sFolderPath & sPartialFileName & "*")
Do While sFileName <> ""
If Len(sFileName) > 3 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.CopyFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
sFileName = Dir
Loop
I have a code which is perfect and can copy/move a specific file based on excel list with partial file name option.
However the only problem is that it only copies 1 file at a time (if the starting file names are same). Is there is any possible way where if i run the code it should copy/move all the files if there are more than 1 files where starting file names are same as well. Your cooperation will be highly appreciated.
Sub CopyFilesFromListPartial()
Const sPath As String = "E:\Asianet2"
Const dpath As String = "E:\Asianet\EMIS"
Const fRow As Long = 2
Const Col As String = "A"
' Reference the worksheet.
Dim ws As Worksheet: Set ws = Sheet1
' Calculate the last row,
' i.e. the row containing the last non-empty cell in the column.
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, Col).End(xlUp).Row
' Early Binding - needs a reference
' to 'Tools > References > Microsoft Scripting Runtime' (has intelli-sense)
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
' Late Binding - needs no reference (no intelli-sense)
'Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
' Validate the source folder path.
Dim sFolderPath As String: sFolderPath = sPath
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Not fso.FolderExists(sFolderPath) Then
MsgBox "The source folder path '" & sFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
' Validate the destination folder path.
Dim dFolderPath As String: dFolderPath = dpath
If Right(dFolderPath, 1) <> "\" Then dFolderPath = dFolderPath & "\"
If Not fso.FolderExists(dFolderPath) Then
MsgBox "The destination folder path '" & dFolderPath _
& "' doesn't exist.", vbCritical
Exit Sub
End If
Dim r As Long ' current row in worksheet column
Dim sFilePath As String
Dim sPartialFileName As String
Dim sFileName As String
Dim dFilePath As String
Dim sYesCount As Long ' source file copied
Dim sNoCount As Long ' source file not found
Dim dYesCount As Long ' source file exists in destination folder
Dim BlanksCount As Long ' blank cell
For r = fRow To lRow
sPartialFileName = CStr(ws.Cells(r, Col).Value)
If Len(sPartialFileName) > 3 Then ' the cell is not blank
' 'Begins with' sPartialFileName
sFileName = Dir(sFolderPath & sPartialFileName & "*")
' or instead, 'Contains' sPartialFileName
'sFileName = Dir(sFolderPath & "*" & sPartialFileName & "*")
If Len(sFileName) > 3 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.CopyFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
Else ' the cell is blank
BlanksCount = BlanksCount + 1
End If
Next r
End Sub
The following tweak to your loop should cause all files that match each sFileName to be copied.
For r = fRow To lRow
sPartialFileName = CStr(ws.Cells(r, Col).Value)
If Len(sPartialFileName) > 3 Then ' the cell is not blank
' 'Begins with' sPartialFileName
sFileName = Dir(sFolderPath & sPartialFileName & "*")
' or instead, 'Contains' sPartialFileName
'sFileName = Dir(sFolderPath & "*" & sPartialFileName & "*")
Do While sFileName <> ""
If Len(sFileName) > 3 Then ' source file found
sFilePath = sFolderPath & sFileName
dFilePath = dFolderPath & sFileName
If Not fso.FileExists(dFilePath) Then ' the source file...
fso.CopyFile sFilePath, dFilePath ' ... doesn't exist...
sYesCount = sYesCount + 1 ' ... in the destination
Else ' the source file exists in the destination folder
dYesCount = dYesCount + 1
End If
Else ' the source file doesn't exist
sNoCount = sNoCount + 1
End If
sFileName = Dir
Loop
Else ' the cell is blank
BlanksCount = BlanksCount + 1
End If
Next r
However, you may need to adjust your counts to get them to still accurately account for how many files were copied/failed/non-existent.