Reputation: 55
I am trying to modify some code I had put together and having a bit of a difficult time converting it. My previous code looked through files in a folder, pulled the name from the file, and used that to determine if it was the right file. I am now trying to run through a master list (one file) where the names are in cells instead of on a file name.
The first userform asks for a first
and last
name and presents a button, search
.
Private Sub search_Click() ' In userform1
' Declare and set variables
Dim fname As String, lname As String
Dim Path As String, fCell As Range, fAdd As String
Path = "C:\Master List.xlsx"
fname = userform1.firstname_Search.Text
lname = userform1.lastname_Search.Text
' Store the name searched for
With Worksheets("Sheet1")
.Range("A1") = fname
.Range("A2") = lname
End With
Workbooks.Open (Path)
' Ensure the name searched for exists in the master list
With Workbooks("Master List").Worksheets("Master List").Range("A:A")
Set fCell = .Find(fname)
If Not fCell Is Nothing And fCell = fname Then
' Column A is first name, B is middle initial, C is last name, D is suffix, F is date of birth
If fCell.Offset(0, 2) = lname Then
userform2.firstname_Text.Text = fCell
userform2.middlename_Text.Text = fCell.Offset(0, 1)
userform2.lastname_Text.Text = Trim(fCell.Offset(0, 2) & " " & fCell.Offset(0, 3))
userform2.dob_Text.Text = fCell.Offset(0, 5)
Unload Me
userform2.Show vbModeless
userform3.Label1.Caption = "Now that we have the information from " & fCell & "'s file, what would you like to do?"
Else
MsgBox ("I could not find a client by that name.")
Workbooks("Master List").Close False
End If
Else
MsgBox ("I could not find a client by that name.")
Workbooks("Master List").Close False
End If
End With
End Sub
This section appears to run fine and will pull up the first entry that matches the first name and last name entered. The issue is occurring when the second userform, userform2
is pulled up, because it displays the relevant information to determine if the right person has been pulled up. It presents first
, middle
, last
names and the date of birth
along with a Yes
and No
button. Clicking Yes
pulls the information (which I have not written yet), while clicking No
should cycle through the remaining matches (for example, if there are 3 William Jackson s listed, clicking No
should cycle to the second; a second No
should cycle to the third; it should then present the MsgBox because no other entries exist for that name).
The issue is that I cannot find a way to cycle past the first No
; if No
was clicked a second time, it wouldn't go past the second entry found. I know this is because of the Set fCell = .Find(fname)
and Set fCell = .FindNext(fCell)
at the beginning, but short of making a cell dedicated to how many times No
has been clicked, is there a better way to do this?
Private Sub no_Click() ' In userform2
' Declare and set variables
Dim fname As String, lname As String
Dim Path As String, fCell As Range, fAdd As String
Path = "C:\Master List.xlsx"
With Workbooks("FirstWorkbook").Worksheets("Sheet1")
fname = .Range("A1")
lname = .Range("A2")
End With
' Ensure a client exists
With Workbooks("Master List").Worksheets("Master List").Range("A:A")
Set fCell = .Find(fname)
Set fCell = .FindNext(fCell)
If Not fCell Is Nothing And fCell = fname Then
If fCell.Offset(0, 2) = lname Then
firstname_Text.Text = fCell
middlename_Text.Text = fCell.Offset(0, 1)
lastname_Text.Text = Trim(fCell.Offset(0, 2) & " " & fCell.Offset(0, 3))
dob_Text.Text = fCell.Offset(0, 5)
userform3.Label1.Caption = "Now that we have the information from " & fCell & "'s file, what would you like to do?"
With Workbooks("FirstWorkbook").Worksheets("Sheet1")
.Range("A1") = fCell
.Range("A2") = fCell.Offset(0, 2)
End With
Else
MsgBox ("I could not find a client by that name.")
Workbooks("Master List").Close False
End If
Else
MsgBox ("I could not find a client by that name.")
Workbooks("Master List").Close False
End If
End With
End Sub
Maybe there's a better way to use one userform, or a better way to search through the master list; either a solution that helps to solve this problem or a point in the right direction so I can look at a different way to do it would help me greatly.
Upvotes: 1
Views: 77
Reputation: 20342
I think you want to list all files in all folders and all sub-folders. Check out this link.
http://www.learnexcelmacro.com/wp/2011/11/how-to-get-list-of-all-files-in-a-folder-and-sub-folders/
Download the file; that's the way to go. Once all paths and all file names are listed in your Excel worksheet, you can do all kinds of comparisons, manipulations, and the like.
Sub GetFilesInFolder(SourceFolderName As String)
'--- For Example:Folder Name= "D:\Folder Name\"
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Scripting.folder, SubFolder As Scripting.folder
Dim FileItem As Scripting.File
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(SourceFolderName)
'--- This is for displaying, whereever you want can be configured
r = 14
For Each FileItem In SourceFolder.Files
Cells(r, 2).Formula = r - 13
Cells(r, 3).Formula = FileItem.Name
Cells(r, 4).Formula = FileItem.Path
Cells(r, 5).Formula = FileItem.Size
Cells(r, 6).Formula = FileItem.Type
Cells(r, 7).Formula = FileItem.DateLastModified
Cells(r, 8).Formula = "=HYPERLINK(""" & FileItem.Path & """,""" & "Click Here to Open" & """)"
r = r + 1 ' next row number
Next FileItem
Set FileItem = Nothing
Set SourceFolder = Nothing
Set FSO = Nothing
End Sub
Sub GetFilesInFolder(SourceFolderName As String, Subfolders As Boolean)
'--- For Example:Folder Name= "D:\Folder Name\" and Flag as Yes or No
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Scripting.folder, SubFolder As Scripting.folder
Dim FileItem As Scripting.File
'Dim r As Long
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(SourceFolderName)
'--- This is for displaying, whereever you want can be configured
r = 14
For Each FileItem In SourceFolder.Files
Cells(r, 2).Formula = r - 13
Cells(r, 3).Formula = FileItem.Name
Cells(r, 4).Formula = FileItem.Path
Cells(r, 5).Formula = FileItem.Size
Cells(r, 6).Formula = FileItem.Type
Cells(r, 7).Formula = FileItem.DateLastModified
Cells(r, 8).Formula = "=HYPERLINK(""" & FileItem.Path & """,""" & "Click Here to Open" & """)"
r = r + 1 ' next row number
Next FileItem
'--- This is the Function to go each and Every Folder and get the Files. This is a Nested-Function Calling.
If Subfolders = True Then
For Each SubFolder In SourceFolder.Subfolders
ListFilesInFolder SubFolder.Path, True
Next SubFolder
End If
Set FileItem = Nothing
Set SourceFolder = Nothing
Set FSO = Nothing
End Sub
Upvotes: 0
Reputation: 166615
I would suggest factoring out the Find into a standalone function, and have it return all matches to the search value (in the example below it returns a collection object). You'd then store that return value in a global field in your form.
It's much easier to cycle through the return value of a function like this than to re-run the search (starting at a different location) every time the use clicks No.
Public Function FindAll(rng As Range, val As String) As Collection
Dim rv As New Collection, f As Range
Dim addr As String
Set f = rng.Find(what:=val, after:=rng.Cells(rng.Cells.Count), _
LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not f Is Nothing Then addr = f.Address()
Do Until f Is Nothing
rv.Add f
Set f = rng.FindNext(after:=f)
If f.Address() = addr Then Exit Do
Loop
Set FindAll = rv
End Function
Upvotes: 2