Find file and insert path into cell - vba

I have a file name of a pdf that I want to search for in a folder on a shared network drive \\Share\Projects. The pdf will be in one of the subfolders under projects. I then want to return the entire file path of the pdf into a cell (eg \\Share\Projects\Subfolder\Another subfolder\thisone.pdf).
I have started the code but can't figure out how to search a file system:
Sub InsertPath()
Dim PONumber As String
PONumber = InputBox("PO Number:", "PO Number")
'search for order
Dim myFolder As Folder
Dim myFile As File
'This bit doesn't work
Set myFolder = "\\Share\Projects"
For Each myFile In myFolder.Files
If myFile.Name = "PO" & PONumber & ".pdf" Then
'I have absolutely no idea how to do this bit
End If
Next
End Sub
Am I on the right track or is my code completely wrong?

get list of subdirs in vba
slighly modified the above post.
Public Arr() As String
Public Counter As Long
Sub LoopThroughFilePaths()
Dim myArr
Dim i As Long
Dim j As Long
Dim MyFile As String
Const strPath As String = "C:\Personal\" ' change it as per your needs
myArr = GetSubFolders(strPath)
Application.ScreenUpdating = False
Range("A1:B1") = Array("text file", "path")
For j = LBound(Arr) To UBound(Arr)
MyFile = Dir(myArr(j) & "\*.pdf")
Do While Len(MyFile) <> 0
i = i + 1
Cells(i, 1) = MyFile
Cells(i, 2) = myArr(j)
MyFile = Dir
Loop
Next j
Application.ScreenUpdating = True
End Sub
Function GetSubFolders(RootPath As String)
Dim fso As Object
Dim fld As Object
Dim sf As Object
Dim myArr
Set fso = CreateObject("Scripting.FileSystemObject")
Set fld = fso.GetFolder(RootPath)
For Each sf In fld.SUBFOLDERS
Counter = Counter + 1
ReDim Preserve Arr(Counter)
Arr(Counter) = sf.Path
myArr = GetSubFolders(sf.Path)
Next
GetSubFolders = Arr
Set sf = Nothing
Set fld = Nothing
Set fso = Nothing
End Function

Well, your folder declaration isn't set against a filesystemobject so it can't find the folder. And because it's a network location, you may need to map a network drive first so that it's a secure link.
So here's an updated version of your code.
EDIT - to OP's conditions.
Dim PONumber As String
Sub InsertPath()
PONumber = InputBox("PO Number:", "PO Number")
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim Servershare As String
ServerShare = "S:\"
Dim Directory As Object
Set Directory = fso.GetFolder(ServerShare)
Subfolderstructure Directory
End Sub
Function Subfolderstructure(Directory As Object)
For Each oFldr in Directory.SubFolders
For Each FileName In oFldr.Files
If FileName.Name = "PO" & PONumber & ".pdf" Then
sheets("Sheet1").range("A1").value = ServerShare & "\PO" & PONumber & ".pdf"
Exit For
End If
Next
Dim sbfldrs : Set sbfldrs = ofldr.SubFolders
If isarray(sbfldrs) then
Subfolderstructure ofldr
End if
Next
'Cleanup
Set FileName = Nothing
Set Directory = Nothing
Set fso = Nothing
End Function
I have not tested this code. Try it out and let me know how it works.

Related

Excel VBA - movefile syntax

Please help with the code for copying files one by one to the destination folder. I tried with "for Each loop but it is copying all the files at once to the destination folder. I am new to to vba and would be helpful if someone could crack the code for me. thanks in advance. here's the code i have managed to come up with.
I am getting run time error 53, File not found,e highlighting the below syntax.
FSO.movefile Source:="C:\Users\wazeer.ahamed\Documents\Outlookemails_Macro\" & Fname, Destination:="C:\Users\wazeer.ahamed\Documents\TcktIDfolder\" & Fname
Sub Example1()
'Extracting file names Dim objFSO As Object Dim objFolder As Object Dim newobjFile As Object
Dim lastID As Long Dim myRRange As Range Dim Maxvalue As Integer
Dim sFolder As String Dim dFolder As String
Sub Example1()
'Extracting file names
Dim FSO
Dim objFolder As Object
Dim newobjFile As Object
Dim FromDir As String
Dim ToDir As String
Dim lastID As Long
Dim myRRange As Range
Dim Maxvalue As Integer
Dim Fname As String
FromDir = "C:\Users\wazeer.ahamed\Documents\Outlookemails_Macro\"
ToDir = "C:\Users\wazeer.ahamed\Documents\TcktIDfolder\"
Fname = Dir(FromDir)
If Len(FromDir) = 0 Then
MsgBox "No files"
Exit Sub
End If
Set myRange = Worksheets("Sheet1").Range("C:C")
Maxvalue = Application.WorksheetFunction.Max(myRange)
lastID = Maxvalue
'finding the next availabe row
erow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'Extracting file names
'Create an instance of the FileSystemObject
Set FSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = FSO.GetFolder("C:\Users\wazeer.ahamed\Documents\Outlookemails_Macro")
'loops through each file in the directory and prints their names and path
For Each newobjFile In objFolder.Files
'print file name
Cells(erow, 1) = Fname
'print file path
Cells(erow, 2) = newobjFile.Path
'PrintUniqueID
Cells(erow, 3) = lastID + 1
FSO.movefile Source:="C:\Users\wazeer.ahamed\Documents\Outlookemails_Macro\" & Fname, Destination:="C:\Users\wazeer.ahamed\Documents\TcktIDfolder\" & Fname
Cells(erow, 5) = "file succesfully copied"
Next newobjFile
Set FSO = Nothing
Set newobjFile = Nothing
Set objFolder = Nothing
End Sub
I think that the code can be more simple and dynamic if you play with your own excel file.
Use "A1" range to put the source folder.
Use "B:B" range to put the
name of the files.
Use "C:C" range to concatenate the previous
columns.
Use "D1" range to put the destination folder.
Sub copyFiles()
'Macro for copy files
'Set variable
Dim source As String
Dim destination As String
Dim x As Integer
Dim destinationNumber As Integer
destinationNumber = WorksheetFunction.CountA(ThisWorkbook.Sheets("Sheet1").Range("C:C"))
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Create the folder if not exist
If Dir(ThisWorkbook.Path & "\" & ThisWorkbook.Sheets("Sheet1").Range("D1"), 16) = "" Then
MkDir ThisWorkbook.Path & "\" & ThisWorkbook.Sheets("Sheet1").Range("D1")
End If
'Run the loop to copy all the files
For x = 1 To destinationNumber
source = ThisWorkbook.Sheets("Sheet1").Range("C" & x)
destination = ThisWorkbook.Sheets("Sheet1").Range("D1")
FileCopy source, destination
Next x
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
With this you can change the folders' paths and file names whenever you want. I've used FileCopy to preserve your files in the source but if you need to delete it's better use other method.

Getting the directory of the file and send as attachment in outlook

I have this code that gets the filenames on the selected directories.
Sub browsefile()
Dim file As Variant
Dim i As Integer
Dim lRow As Long
Set main = ThisWorkbook.Sheets("Main")
file = Application.GetOpenFilename("All Files, *.*", , "Select File", , True)
For i = 1 To UBound(file)
lRow = Cells(Rows.Count, 15).End(xlUp).Row
lRow = lRow + 1
ThisWorkbook.Sheets("Main").Range("O" & lRow).Value = GetFileName(CStr(file(i)))
Next i
End Sub
Function GetFileName(filespec As String)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
GetFileName = fso.GetFileName(filespec)
End Function
Once I've selected the files, I have to put it in Column O. I have tried using .FullName but is not applicable in this area or maybe I've just misused it. Then later this will be send as attached file in an email in outlook.
By the way, I've got some of its code here.
Any help?
In Outlook include attachments with Attachments.Add
Private Sub browsefile_Att()
' Multiselect = False so file is not an array
' Dim file As Variant
Dim file As String
Dim lRow As Long
Dim main As Worksheet
Dim olOlk As Object
Dim olNewmail As Object
Set main = ThisWorkbook.Sheets("Main")
' Multiselect = False so file is not an array
file = Application.GetOpenFilename("All Files, *.*", , "Select File", , False)
lRow = Cells(Rows.Count, 15).End(xlUp).Row
lRow = lRow + 1
ThisWorkbook.Sheets("Main").Range("O" & lRow).Value = file
Set olOlk = CreateObject("Outlook.Application")
Set olNewmail = olOlk.CreateItem(olMailItem)
olNewmail.Attachments.Add file
olNewmail.Display
ExitRoutine:
Set olNewmail = Nothing
Set olOlk = Nothing
End Sub
I assume you are trying to obtain the full path to the file that you have selected. Application.GetOpenFilename already returns you that and hence, there is no need to reprocess your file with GetFileName function?
Changing
ThisWorkbook.Sheets("Main").Range("O" & lRow).Value = GetFileName(CStr(file(i)))
To
ThisWorkbook.Sheets("Main").Range("O" & lRow).Value = CStr(file(i))
should work assuming i have understood your question correctly. Hope this helps!

VBA, Search in Subfolders

I am looking in the Folder for specific file in .docx and want to open it. I put the Name of X into Inputbox, go to Sheet Y, look on the next right cell of X and open this as Word (next cell right is an file in word I want to open). It is working, but the Problem is that the target Word Doc may be in multiples subfolders. Is there any quick way to search in These subfolder?
Private Sub CommandButton1_Click()
On Error GoTo ErrorHandling
Application.ScreenUpdating = False
Dim AppWD As Object
Dim SearchX As String
Dim SearchArea As Range
Dim Y As String
Dim sPath As String
sPath = "C:\Users\VS\Desktop\test"
SearchRule = InputBox("X")
Set SearchArea = Sheets("Look").Range("A:A").Find(what:=SearchX, _
LookIn:=xlFormulas, lookat:=xlWhole)
ActiveWindow.Visible = True
Target = SearchArea.Offset(0, 1).Value
Set AppWD = CreateObject("Word.Application")
AppWD.Visible = True
AppWD.documents.Open (sPath & "\" & Target & "." & "docx")
ErrorHandling: Exit Sub
End Sub
My take on searching throught subfolders
Sub searchSub()
Dim fso As FileSystemObject, fFile As File, fFolder As Folder
Dim fSubFolder As Folder, fPath As String, FileToSearch As String
Set fso = New FileSystemObject
FileToSearch = "SomeDocument.docx"
fPath = ThisWorkbook.Path
Set fFolder = fso.GetFolder(fPath)
For Each fFolder In fFolder.SubFolders
Set fSubFolder = fso.GetFolder(fFolder.Path)
For Each fFile In fSubFolder.Files
If fFile.Name = FileToSearch Then
'do something with file
End If
Next fFile
Next fFolder
End Sub

Excel VBA Open Workbooks without duplicating it

I have a list of filenames in one of my workbook. I was wondering if anyone knows how to open the file when the name is not in that list. For example, the list contains names for file “ab”, “bc”, “cd” & “de”. File “ac”, “bd” & “eg” are not in the list, and I only want to open that files so there is no duplication. I know I can just remove the duplication, but it’s time consuming to open files that already exist in the list. I’m new with VBA and I did some research about this topic, but found nothing. I really appreciate anyone that can help me. Thank you!
So here is what I came up so far:
Sub Test1()
Dim File As String
Dim wb As Workbook
Dim wbList As Workbook
Dim filesRange As Range
Dim f As Range
Dim fileName As String
Dim Average As Double
Dim StdDev As Double
Dim OpenNum As Double
Dim Min As Double
Dim Max As Double
Dim wbDestination As Workbook
Const wbPath As String = "C:\Users\10 stop.xlsx"
Const pathToFiles As String = "C:\Users\J\"
File = Dir(pathToFiles, vbDirectory)
Set wbList = Workbooks.Open(wbPath)
Set filesRange = wbList.Sheets("18x17 - 10 mil stop").Range("A:A")
Do While Len(File) > 0
Set f = filesRange.Find(What:=f, LookIn:=xlValues, Lookat:=xlWhole)
If f Is Nothing Then
Set wb = Workbooks.Open(pathToFiles & File)
fileName = ActiveWorkbook.Name
Worksheets(1).Select
Average = Range("B15")
Worksheets(1).Select
StdDev = Range("B16")
Worksheets(1).Select
OpenNum = Range("B13")
Worksheets(1).Select
Min = Range("B17")
Worksheets(1).Select
Max = Range("B18")
Set wbDestination = Workbooks.Open("C:\Users\10 stop.xlsx")
Worksheets(ActiveSheet.Name).Select
Worksheets(ActiveSheet.Name).Range("a1").Select
RowCount = Worksheets(ActiveSheet.Name).Range("a1").CurrentRegion.Rows.Count
With Worksheets(ActiveSheet.Name).Range("a1")
.Offset(RowCount, 0) = fileName
.Offset(RowCount, 1) = Average
.Offset(RowCount, 2) = StdDev
.Offset(RowCount, 3) = OpenNum
.Offset(RowCount, 4) = Min
.Offset(RowCount, 5) = Max
End With
End If
File = Dir()
Loop
End Sub
I got Runtime-error '5': Invalid Procedure Call or Argument on
Set f = filesRange.Find(What:=f, LookIn:=xlValues, Lookat:=xlWhole)
For the files that I want to open and read, I would like to use wildcard "-10_.csv"
I tried many different ways, but all of them gave me blank sheets as result.
I used the 'RecursiveDir' previously, but it's slow and open every files over and over again when I try to update my data.
This is so frustrating :(
Please help!
Added sub-folder searching. Compiled but not tested.
Sub Test1()
Dim wb As Workbook
Dim wbList As Workbook
Dim filesRange As Range
Dim f As Range
Dim wbDestination As Workbook
Dim rw As Range
Dim allFiles As New Collection, File, fName
Const wbPath As String = "C:\Users\10 stop.xlsx"
Const pathToFiles As String = "C:\Users\J\"
Set wbList = Workbooks.Open(wbPath)
Set filesRange = wbList.Sheets("18x17 - 10 mil stop").Range("A:A")
GetFiles pathToFiles, "*-10_.csv", True, allFiles
For Each File In allFiles
fName = FileNameOnly(File)
Set f = filesRange.Find(What:=fName, LookIn:=xlValues, Lookat:=xlWhole)
If f Is Nothing Then
Set wb = Workbooks.Open(File)
'***need to specify sheet name below...
Set rw = wbList.Sheets("sheetname").Cells(Rows.Count, 1) _
.End(xlUp).Offset(1, 0).EntireRow
rw.Cells(1).Value = fName 'or `File` if you want the full path
With wb.Sheets(1)
rw.Cells(2).Value = .Range("B15").Value 'avg
rw.Cells(3).Value = .Range("B16").Value 'stdev
rw.Cells(4).Value = .Range("B13").Value 'opennum
rw.Cells(5).Value = .Range("B17").Value 'min
rw.Cells(6).Value = .Range("B18").Value 'max
End With
wb.Close False 'don't save
End If
Next File
End Sub
'given a path, return only the filename
Function FileNameOnly(sPath)
Dim arr
arr = Split(sPath, "\")
FileNameOnly = arr(UBound(arr))
End Function
Sub GetFiles(StartFolder As String, Pattern As String, _
DoSubfolders As Boolean, ByRef colFiles As Collection)
Dim f As String, sf As String, subF As New Collection, s
If Right(StartFolder, 1) <> "\" Then StartFolder = StartFolder & "\"
f = Dir(StartFolder & Pattern)
Do While Len(f) > 0
colFiles.Add StartFolder & f
f = Dir()
Loop
sf = Dir(StartFolder, vbDirectory)
Do While Len(sf) > 0
If sf <> "." And sf <> ".." Then
If (GetAttr(StartFolder & sf) And vbDirectory) <> 0 Then
subF.Add StartFolder & sf
End If
End If
sf = Dir()
Loop
For Each s In subF
GetFiles CStr(s), Pattern, True, colFiles
Next s
End Sub

Excel VBA - PDF file properties

first-time poster but long-time fan for finding VBA and SQL solutions on this site. I have a VBA subroutine that is designed to find all PDF files within a directory that the user designates. The program does recursions through all subfolders and generates a spreadsheet as follows:
Column A: complete file path ("C:\Users\Records\NumberOne.pdf")
Column B: folder path containing the file ("C:\Users\Records\")
Column C: the file name itself ("NumberOne.pdf")
Up to this point, the program (code below) works flawlessly. I've used it to search a directory with over 50,000 PDF files, and it successfully generates the spreadsheet every time (total elapsed time for the program is usually 5-10 minutes in large directories).
The problem is that I want to add Column D to capture the date that the PDF file was created. I have Googled this and labored over it for hours, trying techniques like FSO.DateCreated and so forth, and nothing has worked. If FSO.DateCreated is what I need, I'm not sure where to insert it in my subroutine to make it work. Usually I get an error that the object does not support that property or method. Does anybody happen to know where I can insert the proper code for my program to find the date each PDF was created and drop it into Column D on my output spreadsheet?
Sub GetFiles()
'-- RUNS AN UNLIMITED RECURSION SEARCH THROUGH A TARGETED FOLDER AND FINDS ALL PDF FILES WITHIN
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim j As Long
Dim ThisEntry As String
Dim strDir As String
Dim FSO As Object
Dim strFolder As String
Dim strName As String
Dim DateCreated As Date '--(Possibly String?)
Dim strArr(1 To 1048576, 1 To 1) As String, i As Long
Dim fldr As FileDialog
'-- OPEN DIALOG BOX TO SELECT DIRECTORY THE USER WISHES TO SEARCH
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select the directory you wish to search"
.AllowMultiSelect = False
If .Show <> -1 Then
Exit Sub
Set fldr = Nothing
Else
strDir = .SelectedItems(1) & "\"
End If
End With
'-- LOOK FOR RECORDS WORKSHEET; IF IT DOES NOT EXIST, CREATE IT; IF IT DOES EXIST, CLEAR CONTENTS
If Not (wsExists("records")) Then
Worksheets.Add
With ActiveSheet
.Name = "records"
End With
Set ws = ActiveSheet
Else
Sheets("records").Activate
Range("A1:IV1").EntireColumn.Delete
Set ws = ActiveSheet
End If
'-- SET SEARCH PARAMETERS
Let strName = Dir$(strDir & "\" & "*.pdf")
Do While strName <> vbNullString
Let i = i + 1
Let strArr(i, 1) = strDir & strName
Let strName = Dir$()
Loop
'-- UNLIMITED RECURSIONS THROUGH SUBFOLDERS
Set FSO = CreateObject("Scripting.FileSystemObject")
Call recurseSubFolders(FSO.GetFolder(strDir), strArr(), i)
Set FSO = Nothing
'-- CREATE COLUMN HEADERS ON OUTPUT WORKSHEET
With ws
Range("A1").Value = "AbsolutePath"
Range("B1").Value = "FolderPath"
Range("C1").Value = "FileName"
Range("D1").Value = "DateCreated"
End With
If i > 0 Then
ws.Range("A2").Resize(i).Value = strArr
End If
lr = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lr
ThisEntry = Cells(i, 1)
'-- EXTRACT FOLDER PATH AND FILE NAME FROM STRING
For j = Len(ThisEntry) To 1 Step -1
If Mid(ThisEntry, j, 1) = Application.PathSeparator Then
Cells(i, 2) = Left(ThisEntry, j)
Cells(i, 3) = Mid(ThisEntry, j + 1)
Exit For
End If
Next j
Next i
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
----------
Private Sub recurseSubFolders(ByRef Folder As Object, _
ByRef strArr() As String, _
ByRef i As Long)
Dim SubFolder As Object
Dim strName As String
For Each SubFolder In Folder.SubFolders
Let strName = Dir$(SubFolder.Path & "\" & "*.pdf")
Do While strName <> vbNullString
Let i = i + 1
Let strArr(i, 1) = SubFolder.Path & "\" & strName
Let strName = Dir$()
Loop
Call recurseSubFolders(SubFolder, strArr(), i)
Next
End Sub
You need to get the file with GetFile before you can access the DateCreated.
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(myFileName)
str = f.DateCreated
MsgBox (str)
Your code is fine (beside some issues with indentation). I just added the instruction to get the creation date from the file system, as you can see below:
Set FSO = CreateObject("Scripting.FileSystemObject")
For i = 1 To lr
ThisEntry = Cells(i, 1)
'-- EXTRACT FOLDER PATH AND FILE NAME FROM STRING
For j = Len(ThisEntry) To 1 Step -1
If Mid(ThisEntry, j, 1) = Application.PathSeparator Then
Cells(i, 2) = Left(ThisEntry, j)
Cells(i, 3) = Mid(ThisEntry, j + 1)
Cells(i, 4) = FSO.GetFile(ThisEntry).DateCreated
Exit For
End If
Next j
Next i
I don't know why you weren't able to use the FSO object, but I believe it can be because few lines below you set it to nothing, so I instantiated it again before the first For cycle:
Set FSO = CreateObject("Scripting.FileSystemObject")
Hope this helps,
The Macro Guru
FileSystem.FileDateTime(inputfilepath) returns a variant or date of when the file was last created or modified.