I would like to be able to get file information on a list of paths that I enter into a range of cells. I also don't want to get all the Subfolders either. I have this code that works great using 1 folder path.
Sub Get_Information()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim fso As New FileSystemObject
Dim fo As Folder
Dim f As File
Dim last_row As Integer
sh.Rows(1).Font.Size = 18
Set fo = fso.GetFolder(sh.Range("H1").Value)
For Each f In fo.Files
last_row = sh.Range("A" & Application.Rows.Count).End(xlUp).Row + 1
sh.Range("A" & last_row).Value = f.Name
sh.Range("B" & last_row).Value = f.Type
sh.Range("C" & last_row).Value = f.Size / 1024
sh.Range("D" & last_row).Value = f.DateLastModified
Next
MsgBox ("Done")
If you have all paths in one cell, you could split the string in that cell and then loop
with an array
Sub Get_Information()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim fso As New FileSystemObject
Dim fo As Folder
Dim f As File
Dim pathArray as Variant
Dim SplitString as String
Dim last_row As Integer
sh.Rows(1).Font.Size = 18
SplitString = sh.Range("H1").Value
pathArray = Split(SplitString, ";") 'change to whatever seperator you are using
For each pth in pathArray
Set fo = fso.GetFolder(pth)
For Each f In fo.Files
last_row = sh.Range("A" & Application.Rows.Count).End(xlUp).Row + 1
sh.Range("A" & last_row).Value = f.Name
sh.Range("B" & last_row).Value = f.Type
sh.Range("C" & last_row).Value = f.Size / 1024
sh.Range("D" & last_row).Value = f.DateLastModified
Next f
Next pth
MsgBox ("Done")
EDIT
If you want to loop through a range of cells instead:
Sub Get_Information()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim fso As New FileSystemObject
Dim fo As Folder
Dim f As File
Dim c as Range
Dim last_row As Integer
sh.Rows(1).Font.Size = 18
For each pth in sh.Range("H1:H" & last_row) 'Edit range
If not pth.value = ""
Set fo = fso.GetFolder(c.Value)
For Each f In fo.Files
last_row = sh.Range("A" & Application.Rows.Count).End(xlUp).Row + 1
sh.Range("A" & last_row).Value = f.Name
sh.Range("B" & last_row).Value = f.Type
sh.Range("C" & last_row).Value = f.Size / 1024
sh.Range("D" & last_row).Value = f.DateLastModified
Next f
End If
Next pth
MsgBox ("Done")
Related
I have written a code and it pops with error "For without next". Please help me rectify the error.
I'm planning to send bulk emails to 1000 users.
My attempt:
Sub Send_Emails()
Dim sh As Worksheet
Set sh = ThisWorkbook("Send_Emails")
Dim OA As Object
Dim msg As Object
Set OA = CreateObject("Outlook.application")
Dim Last_Row As Integer
Last_Row = Application.CountA(sh.Range("A:A"))
For i = 2 To Last_Row
Set msg = OA.CreateItem(0)
msg.To = sh.Range("A" & i).Value
msg.CC = sh.Range("B" & i).Value
msg.Subject = sh.Range("C" & i).Value
msg.Body = sh.Range("D" & i).Value
End Sub
Some suggestions:
1º Use Option Explicit it will help you code better.
2º Declare the variables.
3º Set the values.
In that order...
Always close the loops, whiles, if statemenet, etc.. As first thing, is easy to forget.
This should work:
Option Explicit
Sub Send_Emails()
Dim sh As Worksheet, OA As Object
Dim msg As Object, Last_Row As Integer
Last_Row = Application.CountA(sh.Range("A:A"))
Set sh = ThisWorkbook.Worksheets("Send_Emails")
Set OA = CreateObject("Outlook.application")
For i = 2 To Last_Row
Set msg = OA.CreateItem(0)
msg.To = sh.Range("A" & i).Value
msg.CC = sh.Range("B" & i).Value
msg.Subject = sh.Range("C" & i).Value
msg.Body = sh.Range("D" & i).Value
Next i
End Sub
How can I determine if my code creates the oExec and nchromePro objects successfully?
it show error message in if (Compile Error: Type mismatch)
Option Explicit
Sub Runprofile()
Dim chromePath As String
chromePath = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --profile-directory=""Profile "
Dim myUrl As String
myUrl = "https://www.facebook.com"
Dim intRow As Long, LastRow As Long
With Worksheets("Data")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
For intRow = 1 To LastRow
Dim myPr As String
myPr = Range("A" & intRow).Value
Dim chromePro As String
chromePro = (chromePath & "" & myPr & """ " & myUrl)
Dim wshell, oExec As Object
Set wshell = CreateObject("Wscript.Shell")
Set oExec = wshell.exec(chromePro)
Application.Wait (Now + TimeValue("0:00:05"))
Dim nUrl As String
nUrl = "https://www.facebook.com/checkpoint/"
Dim nchromePro As String
nchromePro = (chromePath & "" & myPr & """ " & nUrl)
If oExec Is nchromePro Then
.Range("A" & intRow).Font.Color = vbRed
Else
.Range("A" & intRow).Font.Color = vbBlack
End If
Next intRow
End With
End Sub
I want to change color text in my Sheet in Excel if anyprofile browser checkpoint but it alway error when i use oExec in my if:
Private Sub CommandButton1_Click()
Dim chromePro As String
Dim wshell As Object
Dim oExec As Object
chromePath = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --profile-directory=""Profile "
myUrl = "https://www.facebook.com"
Dim LastRow As Long, intRow As Long
With Worksheets("Data")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
For intRow = 1 To LastRow
myPr = Range("A" & intRow).Value
chromePro = (chromePath & "" & myPr & """ " & myUrl)
Set wshell = CreateObject("Wscript.Shell")
Set oExec = wshell.exec(chromePro)
cUrl = "https://www.facebook.com/checkpoint/"
nchromePro = (chromePath & "" & myPr & """ " & cUrl)
***'This block i want to record checkpoint but it error when i use oExec in if***
If oExec = nchromePro Then
.Range("A" & intRow).Font.Color = vbRed
Else
.Range("A" & intRow).Font.Color = vbBlack
End If
Next intRow
End With
End Sub
I am a bit stuck with finishing the script below.
I got to this point and it does the basic thing I need it to do but it does need a bit of tweaking to get perfect.
It does the following: 1-pickup and prep master output file; 2- open each file in folder 'xls' and copy data from the designated sheet at the end of the master output file; 3-final edit of the master file; 4-save master file with name based on the input archives.
Where I need help is and was unable to fix up is: I want the script to cycle through subfolders in 'xls' folder and create a single master for each subfolder in 'xls' collecting data from files in that subfolder and name it after subfolder.
I understand I need another loop for subfolders but I am not really good with dirs in vba. Would this require a major overhaul?
Sub Joiner()
'Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim FileNAME As String
Dim wb As Workbook
Dim Masterwb As Workbook
Dim sh As Worksheet
Dim NewSht As Worksheet
Dim FindRng As Range
Dim PasteRow As Long
Dim DayVar As String
Dim RangeVar As Variant
Dim LastRow As Long
Dim Targetsh As Worksheet
Dim RecordsCount As Long
' set master workbook
Workbooks.Open FileNAME:="C:\TA\output\Master Template.xlsx"
Set Masterwb = Workbooks("Master Template.xlsx")
Set Targetsh = Masterwb.Sheets("Data")
With ActiveWorkbook.Sheets("Data")
.Range("A1").FormulaR1C1 = "SysTime"
.Range("B1").FormulaR1C1 = "Seq#"
.Range("C1").FormulaR1C1 = "A1"
.Range("D1").FormulaR1C1 = "F2"
.Range("E1").FormulaR1C1 = "F3"
.Range("F1").FormulaR1C1 = "T4"
.Range("G1").FormulaR1C1 = "T5"
.Range("H1").FormulaR1C1 = "T6"
.Range("I1").FormulaR1C1 = "T7"
.Range("J1").FormulaR1C1 = "T8"
.Range("K1").FormulaR1C1 = "A9"
.Range("A1:K1").Font.Bold = True
.Range("A1:K1").Interior.ColorIndex = 19
.Range("L1").FormulaR1C1 = "Date"
.Range("M1").FormulaR1C1 = "Date/Seq#"
End With
folderPath = "C:\TA\xls\" 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
Application.ScreenUpdating = False
FileNAME = Dir(folderPath & "*.xls*")
Do While FileNAME <> ""
Set wb = Workbooks.Open(folderPath & FileNAME)
'DayVar = Left(Right(wb.Name, 13), 8)
LastRow = wb.Sheets("Cleaned").Range("A1").End(xlDown).Row
RangeVar = wb.Sheets("Cleaned").Range("A2:K" & LastRow)
Targetsh.Range("A" & Rows.Count).End(xlUp)(2).Resize(UBound(RangeVar, 1), UBound(RangeVar, 2)) = RangeVar
wb.Close False
Exit_Loop:
Set wb = Nothing
FileNAME = Dir
Loop
Application.ScreenUpdating = True
With Masterwb.Sheets("Data")
.Range(Range("A2"), Range("A2").End(xlDown)).NumberFormat = "dd/mm/yyyy hh:mm:ss"
End With
LastRow = ActiveWorkbook.Sheets("Data").Range("A1").End(xlDown).Row
With ActiveWorkbook.Sheets("Data")
.Range("L2").FormulaR1C1 = "=INT(C1)"
.Range("M2").FormulaR1C1 = "=C12&""-""&C2"
End With
Range("L2").AutoFill Destination:=Range("L2" & ":L" & LastRow)
With ActiveSheet
.Columns("L:L").Cells = .Columns("L:L").Cells.Value
End With
Range("M2").AutoFill Destination:=Range("M2" & ":M" & LastRow)
With ActiveSheet
.Columns("M:M").Cells = .Columns("M:M").Cells.Value
End With
With Masterwb.Sheets("Data")
.Range(Range("L2"), Range("L2").End(xlDown)).NumberFormat = "dd/mm/yyyy"
End With
'Name the master output based on id
Dim FirstName As String
Dim InterName As String
Dim FinalName As String
Dim FilePath As String
FirstName = Dir("C:TA\Input\*.cab", vbNormal)
InterName = "Master Template " & Right(Left(FirstName, 12), 4)
'MsgBox FirstName
'MsgBox InterName
FilePath = "C:\TA\output"
ActiveWorkbook.SaveAs FileNAME:=FilePath & "\" & InterName & ".xlsx", _
FileFormat:=51, CreateBackup:=False
'
End Sub
Thank you for any advice.
With this code you can list excel files in a folder and subfolders
Sub ListSubfoldersFile() ' only one level subfolders
arow = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
mFolder = "F:\Download\" ' path to change
Set mainFolder = objFSO.GetFolder(mFolder)
StrFile = Dir(mFolder & "*.xls*")
Do While Len(StrFile) > 0
Cells(arow, 1).Value = mFolder & StrFile
arow = arow + 1
StrFile = Dir
Loop
For Each mySubFolder In mainFolder.subfolders
StrFile = Dir(mySubFolder & "\*.xls*")
Do While Len(StrFile) > 0
Cells(arow, 1).Value = mySubFolder & "\" & StrFile
arow = arow + 1
StrFile = Dir
Loop
Next
End Sub
Thank you Patel!
I used your solution to complement my current vba snippet.
It may be a bit clunky but it does what I need it to do.
Thank you.
Posting a solution below for the benefit of the community.
Sub MassJoiner()
'this is a version of joiner with subfolders
'Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim FileNAME As String
Dim wb As Workbook
Dim Masterwb As Workbook
Dim sh As Worksheet
Dim NewSht As Worksheet
Dim FindRng As Range
Dim PasteRow As Long
Dim DayVar As String
Dim RangeVar As Variant
Dim LastRow As Long
Dim Targetsh As Worksheet
Dim RecordsCount As Long
Dim StrFile As String
Dim mFolder As String
Dim BatchCount As Long
Dim ID As String
Set objFSO = CreateObject("Scripting.FileSystemObject")
mFolder = "D:\TA\TEST\" ' path to change
Set mainFolder = objFSO.GetFolder(mFolder)
StrFile = Dir(mFolder & "*.xls*")
BatchCount = 0
Workbooks.Open FileNAME:="C:\TA\output\Master Template.xlsx"
For Each mySubFolder In mainFolder.subfolders
StrFile = Dir(mySubFolder & "\*.xls*")
Do While Len(StrFile) > 0
Set Masterwb = Workbooks("Master Template.xlsx")
Set Targetsh = Masterwb.Sheets("Data")
With ActiveWorkbook.Sheets("Data")
.Range("A1").FormulaR1C1 = "SysTime"
.Range("B1").FormulaR1C1 = "Seq#"
.Range("C1").FormulaR1C1 = "A1"
.Range("D1").FormulaR1C1 = "F2"
.Range("E1").FormulaR1C1 = "F3"
.Range("F1").FormulaR1C1 = "T4"
.Range("G1").FormulaR1C1 = "T5"
.Range("H1").FormulaR1C1 = "T6"
.Range("I1").FormulaR1C1 = "T7"
.Range("J1").FormulaR1C1 = "T8"
.Range("K1").FormulaR1C1 = "A9"
.Range("A1:K1").Font.Bold = True
.Range("A1:K1").Interior.ColorIndex = 19
.Range("L1").FormulaR1C1 = "Date"
.Range("M1").FormulaR1C1 = "Date/Seq# pair"
End With
'FileNAME = Dir(folderPath & "*.xls*")
'Do While FileNAME <> ""
Set wb = Workbooks.Open(mySubFolder & "\" & StrFile)
'DayVar = Left(Right(wb.Name, 13), 8)
LastRow = wb.Sheets("Cleaned").Range("A1").End(xlDown).Row
RangeVar = wb.Sheets("Cleaned").Range("A2:K" & LastRow)
Targetsh.Range("A" & Rows.Count).End(xlUp)(2).Resize(UBound(RangeVar, 1), UBound(RangeVar, 2)) = RangeVar
wb.Close False
'Exit_Loop:
' Set wb = Nothing
' FileNAME = Dir
'Loop
StrFile = Dir
Loop
With Masterwb.Sheets("Data")
.Range(Range("A2"), Range("A2").End(xlDown)).NumberFormat = "dd/mm/yyyy hh:mm:ss"
End With
LastRow = ActiveWorkbook.Sheets("Data").Range("A1").End(xlDown).Row
With ActiveWorkbook.Sheets("Data")
.Range("M2").FormulaR1C1 = "Date/Seq# pair"
.Range("m2").FormulaR1C1 = "=C12&""-""&C2"
End With
Range("L2").AutoFill Destination:=Range("L2" & ":L" & LastRow)
With ActiveSheet
.Columns("L:L").Cells = .Columns("L:L").Cells.Value
End With
Range("M2").AutoFill Destination:=Range("M2" & ":M" & LastRow)
With ActiveSheet
.Columns("M:M").Cells = .Columns("M:M").Cells.Value
End With
With Masterwb.Sheets("Data")
.Range(Range("l2"), Range("l2").End(xlDown)).NumberFormat = "dd/mm/yyyy"
End With
'Name the master output based on job id
Dim FirstName As String
Dim InterName As String
Dim FinalName As String
Dim FilePath As String
FirstName = mySubFolder
InterName = "Master Template " & Right(FirstName, 4)
ID = Right(FirstName, 4)
'MsgBox FirstName
'MsgBox InterName
FilePath = "C:\TA\output"
ActiveWorkbook.SaveAs FileNAME:=FilePath & "\" & InterName & ".xlsx", _
FileFormat:=51, CreateBackup:=False
ActiveWorkbook.Close False
BatchCount = BatchCount + 1
Application.Speech.Speak "Batch job" & BatchCount & "finalized. ID" & ID
Workbooks.Open FileNAME:="C:\output\Master Template.xlsx"
Next
Application.ScreenUpdating = True
End Sub
I am looking for help with VBA to find file names listed in an excel Column A from a folder and return the file path in Column B
The code below works, however if I would like excel to skip the row if the filename cannot be found so that the filepath results are returned in the cell directly next to the filename.
Private Sub CommandButton1_Click()
Dim sh As Worksheet, rng As Range, lr As Long, fPath As String
Set sh = Sheets(1) 'Change to actual
lstRw = sh.Cells.Find(What:="*", After:=sh.Range("A1"), LookAt:=xlWhole, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row
Set rng = sh.Range("A2:A" & lstRw)
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
fPath = .SelectedItems(1)
End With
If Right(fPath, 1) <> "\" Then
fPath = fPath & "\"
End If
fwb = Dir(fPath & "*.*")
x = 2
Do While fwb <> ""
For Each c In rng
If InStr(LCase(fwb), LCase(c.Value)) > 0 Then
Worksheets("Sheet2").Range("A" & x) = fwb
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(fPath & fwb)
Worksheets("Sheet1").Range("B" & x) = f.Path
Set fs = Nothing
Set f = Nothing
x = x + 1
End If
Next
fwb = Dir
Loop
Set sh = Nothing
Set rng = Nothing
Sheets(2).Activate
End Sub
As mentioned in my comments above, use the DIR inside the range loop. See this example.
Here it won't output anything to Col B if the respective cell in Col A doesn't return anything.
Sub Sample()
Dim sh As Worksheet
Dim rng As Range
Dim i As Long, Lrow As Long
Dim fPath As String, sPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
fPath = .SelectedItems(1)
End With
If Right(fPath, 1) <> "\" Then
fPath = fPath & "\"
End If
Set sh = ThisWorkbook.Sheets("Sheet1")
With sh
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 2 To Lrow
'~~> Check for partial match
sPath = fPath & "*" & .Range("A" & i).Value & "*.*"
If Len(Trim(Dir(sPath))) > 0 Then
.Range("B" & i).Value = Dir(sPath)
End If
Next i
End With
End Sub
Note: If you do not want a partial match then consider revising
sPath = fPath & "*" & .Range("A" & i).Value & "*.*"
to
sPath = fPath & .Range("A" & i).Value & ".*"