I am working on a project where I search an entire workbook and then have the results shown on a search page. So far I have it down to being able to search for a string and it finding that string. But if I just search for a keyword like "motor" it will show no results because no where in the workbook is just "motor" written in a cell. Is their any way that I can make it so that it will search for any thing that is typed in the search box?
Here is the code. The search script is Sub FindOne()
Private Sub ComboBox1_Change()
End Sub
Private Sub ComboBox2_Change()
UpdateSearchBox
End Sub
Private Sub CommandButton1_Click()
Select Case TextBox1.Value
Case "F"
TextBox1.Value = "G"
Case "E"
TextBox1.Value = "F"
Case "D"
TextBox1.Value = "E"
Case "C"
TextBox1.Value = "D"
Case "B"
TextBox1.Value = "C"
Case "A"
TextBox1.Value = "B"
Case "G"
TextBox1.Value = "A"
End Select
End Sub
Private Sub CommandButton2_Click()
FindOne
End Sub
Private Sub TextBox1_Change()
UpdateSearchBox
End Sub
Sub UpdateSearchBox()
Dim PageName As String, searchColumn As String, ListFiller As String
Dim lastRow As Long
If TextBox1.Value <> "" Then
PageName = TextBox1.Value
Else
Exit Sub
End If
Select Case ComboBox2.Value
Case "EQUIPMENT NUMBER"
searchColumn = "A"
Case "EQUIPMENT NAME"
searchColumn = "C"
Case "DUPONT NUMBER"
searchColumn = "F"
Case "SAP NUMBER"
searchColumn = "G"
Case "SSI NUMBER"
searchColumn = "H"
Case "PART NAME"
searchColumn = "I"
Case ""
MsgBox "Please select a value for what you are searching by."
End Select
lastRow = Sheets(PageName).Range("A65536").End(xlUp).Row
If lastRow <> 0 And PageName <> "" And searchColumn <> "" Then
ListFiller = PageName & "!" & searchColumn & "2" & ":" & searchColumn & lastRow
ComboBox1.ListFillRange = ListFiller
End If
End Sub
Sub FindOne()
Range("B19:J1500") = ""
Application.ScreenUpdating = False
Dim k As Integer, EndPasteLoopa As Integer
Dim myText As String, searchColumn As String
Dim totalValues As Long
Dim nextCell As Range
k = ThisWorkbook.Worksheets.Count
myText = ComboBox1.Value
Set nextCell = Range("B20")
If myText = "" Then
MsgBox "No Address Found"
Exit Sub
End If
Select Case ComboBox2.Value
Case "EQUIPMENT NUMBER"
searchColumn = "A"
Case "EQUIPMENT NAME"
searchColumn = "C"
Case "DUPONT NUMBER"
searchColumn = "F"
Case "SAP NUMBER"
searchColumn = "G"
Case "SSI NUMBER"
searchColumn = "H"
Case "PART NAME"
searchColumn = "I"
Case ""
MsgBox "Please select a value for what you are searching by."
End Select
For i = 2 To k
totalValues = Sheets(i).Range("A65536").End(xlUp).Row
ReDim AddressArray(totalValues) As String
For j = 0 To totalValues
AddressArray(j) = Sheets(i).Range(searchColumn & j + 1).Value
Next j
For j = 0 To totalValues
If (myText = AddressArray(j)) Then
EndPasteLoop = 1
If (Sheets(i).Range(searchColumn & j + 2).Value = "") Then EndPasteLoop = Sheets(i).Range(searchColumn & j + 1).End(xlDown).Row - j - 1
For r = 1 To EndPasteLoop
Range(nextCell, nextCell.Offset(0, 8)).Value = Sheets(i).Range("A" & j + r, "I" & j + r).Value
Set nextCell = nextCell.Offset(1, 0)
Next r
End If
Next j
Next i
Application.ScreenUpdating = True
End Sub
I have no idea if this is even possible. Thank You!
Use the Instr function. Here is an example of how it works:
Dim startPosition As Integer
startPosition = InStr("find the comma, in the string", ",")
This bit of code will return 15, saying that the position there there is a , is the 15th position.
Now just adjust this for your code. Iterate over what you want to search through. If the InStr function does not return 0, you've got a (semi)match.
If you want to learn more, go to this question: Check if a string contains another string.
#A.S.H answered the question in the comments.
Related
I am a beginner on vba, sarching and reading different things about vba I have created a piece of code but doesn't work how I want to. If I search for a specific value the code find it and show on specific textboxes a specific value, but if there are more than one same values (in searching column) I want to make the code go to next one until find every same value, what my actual code doesn't do. Any help on improving this code or any other code that does it I appreciate.
Here is my code,
Private Sub Search_Click()
Dim a As String
Dim b As Double
Dim k As Range
On Error GoTo dontexist:
If Me.TextBox20.Value = "" Or Me.TextBox20.Value = "Number of invoice" Then
Me.Label29.Caption = "Number of invoice"
b = Me.TextBox24.Value
Set k = Sheets("Sheet2").Range("E:E")
r = Application.WorksheetFunction.Match(b, k, 0)
Me.TextBox21.Value = Sheets("Sheet2").Cells(r, 2).Value
Me.TextBox22.Value = Sheets("Sheet2").Cells(r, 8).Value
Me.TextBox23.Value = Sheets("Sheet2").Cells(r, 4).Value
Exit Sub
Else
Me.Label29.Caption = "Sum of invoice"
a = Me.TextBox20.Value
Set k = Sheets("Sheet2").Range("H:H")
r = Application.WorksheetFunction.Match(a, k, 0)
Me.TextBox21.Value = Sheets("Sheet2").Cells(r, 2).Value
Me.TextBox22.Value = Sheets("Sheet2").Cells(r, 5).Value
Me.TextBox23.Value = Sheets("Sheet2").Cells(r, 4).Value
Exit Sub
End If
dontexist:
MsgBox "This record dosn't exist!", vbInformation, "Info!"
End Sub
Add a label to your form to hold the last found row and start the search from there. I have used label30.
Option Explicit
Private Sub Search_Click()
Dim rngSearch As Range, rngFound As Range, sColumn As String
Dim sValue As String, iCount As Long
Dim ws As Worksheet
Set ws = Sheets("Sheet2")
' label to hold row to start search at
If Label30 = "" Then Label30 = "1"
If Len(TextBox24) > 0 Then
' search on number
sValue = TextBox24
sColumn = "E"
Label29 = "Number of invoice"
ElseIf Len(TextBox20) > 0 Then
' search on total
sValue = TextBox20
sColumn = "H"
Label29 = "Sum of invoice"
Else
MsgBox "No search values entered", vbExclamation
Exit Sub
End If
' count number of matches
Set rngSearch = ws.Cells(1, sColumn).EntireColumn
iCount = Application.WorksheetFunction.CountIf(rngSearch, sValue)
If iCount > 0 Then
' continue search from last position
Set rngFound = rngSearch.Find(sValue, _
After:= ws.Range(sColumn & Label30), _
LookIn:=xlValues, _
LookAt:=xlWhole)
If rngFound Is Nothing Then
' not found
Label30 = ""
MsgBox "No more records found"
Else
' is row new
If rngFound.Row > Label30 Then
'MsgBox rngFound.Row
' copy into text boxes
With rngFound.EntireRow
If sColumn = "E" Then
TextBox21 = .Cells(1, 2)
TextBox22 = .Cells(1, 8)
TextBox23 = .Cells(1, 4)
Else
TextBox21 = .Cells(1, 2)
TextBox22 = .Cells(1, 5)
TextBox23 = .Cells(1, 4)
End If
End With
Label30 = rngFound.Row
Else
MsgBox "No more records found", vbExclamation
Label30 = ""
Exit Sub
End If
End If
Else
MsgBox "No records found", vbExclamation
Label30 = ""
End If
End Sub
I have a Userform with a listbox for which I am using conditional logic to determine output values to the sheet of selected or non-selected items in the listbox. The issue is that when the Textbox (Tbl_AliasName) is blank, the code executes this:
ElseIf .Selected(k) = True And Tbl_AliasName = vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Trim(Cells(2, 1).Value2) & "." & .Column(1, k)
But if Tbl_AliasName is not blank then the code does nothing, but it is supposed to do this:
ElseIf .Selected(k) = True And Tbl_AliasName <> vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Tbl_AliasName & "." & .Column(1, k)
I have used several variations of If statements, and non of which have worked.
Below is My Code:
Option Explicit
Public Tbl_AliasName As String
Tbl_AliasName = Trim(UserForm_Finder.txtConcat.Value)
Private Sub BtnConcat_Click()
Dim k As Long, lstbxRow As Long, LR As Long
lstbxRow = 1
'****************
'This if statement works perfectly
If (Cells(2, 1).Value2 = vbNullString Or Cells(2, 2).Value2 = vbNullString) _
And Tbl_AliasName = vbNullString Then
MsgBox "You must Search for a Table or Column first.", _
vbExclamation, "Error Encountered"
Exit Sub
ElseIf (UserForm_Finder.ListBx_TblsCols.ListCount = 0 And Tbl_AliasName <> vbNullString) Then
MsgBox "You must Search for a Table or Column first.", _
vbExclamation, "Error Encountered"
'(Cells(2, 1).Value2 = vbNullString Or Cells(2, 2).Value2 = vbNullString) And _
Exit Sub
End If
With UserForm_Finder.ListBx_TblsCols
For k = 0 To .ListCount - 1
'****************
This is where the problems begin
If .Selected(k) = False Then
MsgBox "You must Select 1 or more items from the list box.", _
vbExclamation, "Error Encountered"
Exit Sub
ElseIf .Selected(k) = True And Tbl_AliasName <> vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Tbl_AliasName & "." & .Column(1, k)
ElseIf .Selected(k) = True And Tbl_AliasName = vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Trim(Cells(2, 1).Value2) & "." & .Column(1, k)
End If
Next k
End With
End Sub
My goal is to do the following:
If a Textbox (Tbl_AliasName) is not blank and the user has selected one or more items in the listbox (ListBx_TbleCols) then concatenate the Tbl_AliasName to the selected items in the listbox
If Tbl_AliasName is blank, then use the value in Cells(2,1) to concatenate to the selected Items in the list box.
I have tried the following additions:
Dim LstBxItemSelected As Boolean
'This was placed in the for loop
LstBxItemSelected = True
'this was placed outside the for loop
If LstBxItemSelected = False Then
MsgBox "You must Select 1 or more items from the list box.", _
vbExclamation, "Error Encountered"
Exit Sub
End If
Is there a better way to tell if items are selected, because I feel that the way I have it structured in my loop, the code will throw the error if everything isn't selected? Thank you in advance for any ideas, answers, or suggestions!
Note: The Listbox is populated by the click of another button on the userform which calls the following sub:
Sub FillLstBxCols()
Dim ListBx_Target As MSForms.ListBox
Dim rngSource As Range
Dim LR As Long
If Cells(2, 1).Value2 <> vbNullString Then
LR = Worksheets("New TRAX").Cells(Rows.Count, 2).End(xlUp).Row
'Set reference to the range of data to be filled
Set rngSource = Worksheets("New Trax").Range("A" & 2 & ":" & "B" & LR)
'Fill the listbox
Set ListBx_Target = UserForm_Finder.ListBx_TblsCols
With ListBx_Target
.RowSource = rngSource.Address
End With
End If
End Sub
Hard to say without sample data and expected results, but I think this is what you're looking for:
Private Sub btnConcat_Click()
Dim ws As Worksheet
Dim bSelected As Boolean
Dim sConcat As String
Dim i As Long, lRowIndex As Long
Set ws = ActiveWorkbook.Sheets("New TRAX")
lRowIndex = 1
bSelected = False
sConcat = Trim(Me.txtConcat.Text)
If Len(sConcat) = 0 Then sConcat = Trim(ws.Cells(2, "A").Value)
If Len(sConcat) = 0 Then
MsgBox "You must Search for a Table or Column first.", vbExclamation, "Error Encountered"
Exit Sub
End If
For i = 0 To Me.ListBx_TblsCols.ListCount - 1
If Me.ListBx_TblsCols.Selected(i) Then
If bSelected = False Then
bSelected = True
ws.Range("C2", ws.Cells(ws.Rows.Count, "C")).Clear 'clear previous concat results (delete this line if not needed)
End If
lRowIndex = lRowIndex + 1
ws.Cells(lRowIndex, "C").Value = sConcat & "." & Me.ListBx_TblsCols.List(i)
End If
Next i
If bSelected = False Then MsgBox "Must select at least one item from the list"
End Sub
I am trying to create a message box that will give the user the option to continue or stop if their search comes up with more than 1000 results. I have the message box made, but I don't know how to code the vbYes and the vbNo to either continue on with the code (vbYes) or to end the script (vbNO).
Here is my code.
Sub FindOne()
Range("B19:J5000") = ""
Application.ScreenUpdating = False
Dim k As Integer, EndPasteLoopa As Integer, searchColumn As Integer, searchAllCount As Integer
Dim myText As String
Dim totalValues As Long
Dim nextCell As Range
Dim searchAllCheck As Boolean
k = ThisWorkbook.Worksheets.Count
myText = ComboBox1.Value
Set nextCell = Range("B20")
If myText = "" Then
MsgBox "No Address Found"
Exit Sub
End If
Select Case ComboBox2.Value
Case "SEARCH ALL"
searchAllCheck = True
Case "EQUIPMENT NUMBER"
searchColumn = 1
Case "EQUIPMENT DESCRIPTION"
searchColumn = 3
Case "DUPONT NUMBER"
searchColumn = 6
Case "SAP NUMBER"
searchColumn = 7
Case "SSI NUMBER"
searchColumn = 8
Case "PART DESCRIPTION"
searchColumn = 9
Case ""
MsgBox "Please select a value for what you are searching by."
End Select
For I = 2 To k
totalValues = Sheets(I).Cells(Rows.Count, "A").End(xlUp).Row
ReDim AddressArray(totalValues) As String
If searchAllCheck Then
searchAllCount = 5
searchColumn = 1
Else
searchAllCount = 0
End If
For qwerty = 0 To searchAllCount
If searchAllCount Then
Select Case qwerty
Case "1"
searchColumn = 3
Case "2"
searchColumn = 6
Case "3"
searchColumn = 7
Case "4"
searchColumn = 8
Case "5"
searchColumn = 9
End Select
End If
For j = 0 To totalValues
AddressArray(j) = Sheets(I).Cells(j + 1, searchColumn).Value
Next j
If totalValues > 1000 Then
Results = MsgBox("Your Search has Returned Over 1000 Results. Continuing Could Cause Excel to Slow Down or Crash. Do you Wish to Continue?", vbYesNo + vbExclamation, "Warning")
End If
If Results = vbNo Then
End
End If
If Results = vbYes Then
For j = 0 To totalValues
If InStr(1, AddressArray(j), myText) > 0 Then
EndPasteLoop = 1
If (Sheets(I).Cells(j + 2, searchColumn).Value = "") Then EndPasteLoop = Sheets(I).Cells(j + 1, searchColumn).End(xlDown).Row - j - 1
For r = 1 To EndPasteLoop
Range(nextCell, nextCell.Offset(0, 8)).Value = Sheets(I).Range("A" & j + r, "I" & j + r).Value
Set nextCell = nextCell.Offset(1, 0)
Next r
End If
Next j
Else
End
End If
Next qwerty
Next I
Debug.Print tc
Application.ScreenUpdating = True
End Sub
If I understood your problem, you have to compare the "Results" variable if is vbYes or vbNo.
Below a little and simple example.
If MsgBox("Continue?", vbYesNo,"Confirmation") = vbYes Then
'code if yes
Else
'End
End If
Hope that helps. ;)
vbYes is a constant, a member of an enum called VbMsgBoxResult that defines a bunch of related constants, including vbYes and vbNo.
If vbYes Then
That's like saying
If 42 Then
You have a constant expression that evaluates to a Long integer, and an If statement works with a Boolean expression that evaluates to a Boolean value (True/False).
You need to compare vbYes to something to get that Boolean expression.
If Results = vbYes Then
enter image description hereWe are trying to write a code that, given a site name (column) and SKU (row), the value of the resulting cell gets shown in a text box. We've gotten to the point where we have the cell number, ie. E16, but we can't figure out how to print the value of E16 into the text box. txtPrice.value in the last line is supposed to be what gets posted in the text box, but it keeps coming out empty
Private Sub btnGO_Click()
Dim rowNum, cellNum As Variant
rowNum = Application.WorksheetFunction.Match(txtSKU.Value,
Worksheets("AllSites").Range("B:B"), 0)
If IsError(rowNum) Then MsgBox "SKU not found": Exit Sub
If cbxSite.Value = "Fairburn" Then
cellNum = "C" & rowNum
ElseIf cbxSite.Value = "Aberdeen" Then
cellNum = "D" & rowNum
ElseIf cbxSite.Value = "University Park" Then
cellNum = "E" & rowNum
ElseIf cbxSite.Value = "Roanoke" Then
cellNum = "F" & rowNum
ElseIf cbxSite.Value = "Lathrop" Then
cellNum = "G" & rowNum
Else: cbxSite.Value = "Redlands"
cellNum = "H" & rowNum
If IsError(cellNum) Then MsgBox "Site not found": Exit Sub
txtPrice.Value = Worksheets("AllSites").Cells(cellNum).Value
End If
End Sub
You are trying to use something like Cells("H6").Value. It should be .Range("H6").Value.
'where cellNum is a string something like "H6"
txtPrice.Value = Worksheets("AllSites").Range(cellNum).Value
The problem is with the structure of your If statement. Your End If statement is in the wrong place. This caused Excel to insert a colon after your Else statement. Using a colon is a way to put two statements on the same line. So the effect of this is that if none of the other If & ElseIf condtions are met, then this statement cellNum = "H" & rowNum will always execute and probably directs cellNum to a blank cell.
Even if one of the other If conditions is met, then the code is skipping the part that sets the textbox value because everything between Else: and End If is part of the Else: clause so those statements don't get executed if any of the other If conditions evaluate to True.
So you need to change the Else: condition to antoher ElseIf and move the End If statement below that block.
Additionally, you need to change .Cells to .Range as others here have noted.
Private Sub btnGO_Click()
Dim rowNum, cellNum As Variant
rowNum = Application.WorksheetFunction.Match(txtSKU.Value, Worksheets("AllSites").Range("B:B"), 0)
If IsError(rowNum) Then MsgBox "SKU not found": Exit Sub
If cbxSite.Value = "Fairburn" Then
cellNum = "C" & rowNum
ElseIf cbxSite.Value = "Aberdeen" Then
cellNum = "D" & rowNum
ElseIf cbxSite.Value = "University Park" Then
cellNum = "E" & rowNum
ElseIf cbxSite.Value = "Roanoke" Then
cellNum = "F" & rowNum
ElseIf cbxSite.Value = "Lathrop" Then
cellNum = "G" & rowNum
ElseIf cbxSite.Value = "Redlands" Then
cellNum = "H" & rowNum
End If
If IsError(cellNum) Then MsgBox "Site not found": Exit Sub
txtPrice.Value = Worksheets("AllSites").Range(cellNum).Value
End Sub
Try this:
Textbox.Text = Worksheets("AllSites").Cells(cellNum).Value
This is not a question, so much as a solution, but I wanted to share it here as I had gotten help for things I needed here.
I wanted to find a specific Excel sheet, in the Active Workbook, searching by the name of the sheet. I built this to find it. It is a "contains" search, and will automatically go to the sheet if it is found, or ask the user if there are multiple matches:
To end at any time, just enter a blank in the input box.
Public Sub Find_Tab_Search()
Dim sSearch As String
sSearch = ""
sSearch = InputBox("Enter Search", "Find Tab")
If Trim(sSearch) = "" Then Exit Sub
'MsgBox (sSearch)
Dim sSheets() As String
Dim sMatchMessage As String
Dim iWorksheets As Integer
Dim iCounter As Integer
Dim iMatches As Integer
Dim iMatch As Integer
Dim sGet As String
Dim sPrompt As String
iMatch = -1
iMatches = 0
sMatchMessage = ""
iWorksheets = Application.ActiveWorkbook.Sheets.Count
ReDim sSheets(iWorksheets)
'Put list of names in array
For iCounter = 1 To iWorksheets
sSheets(iCounter) = Application.ActiveWorkbook.Sheets(iCounter).Name
If InStr(1, sSheets(iCounter), sSearch, vbTextCompare) > 0 Then
iMatches = iMatches + 1
If iMatch = -1 Then iMatch = iCounter
sMatchMessage = sMatchMessage + CStr(iCounter) + ": " + sSheets(iCounter) + vbCrLf
End If
Next iCounter
Select Case iMatches
Case 0
'No Matches
MsgBox "No Match Found for " + sSearch
Case 1
'1 match activate the sheet
Application.ActiveWorkbook.Sheets(iMatch).Activate
Case Else
'More than 1 match. Ask them which sheet to go to
sGet = -1
sPrompt = "More than one match found. Please enter number from following list"
sPrompt = sPrompt + "to display the sheet" + vbCrLf + vbCrLf + sMatchMessage
sPrompt = sPrompt + vbCrLf + vbCrLf + "Enter blank to cancel"
sGet = InputBox(sPrompt, "Please select one")
If Trim(sGet) = "" Then Exit Sub
sPrompt = "Value must be a number" + vbCrLf + vbCrLf + sPrompt
Do While IsNumeric(sGet) = False
sGet = InputBox(sPrompt, "Please select one")
If Trim(sGet) = "" Then Exit Sub
Loop
iMatch = CInt(sGet)
Application.ActiveWorkbook.Sheets(iMatch).Activate
End Select
End Sub
I hope someone finds this useful, and would also welcome enhancement suggestions.
For fun tried to do this in as few lines as possible with loops
Uses a range name, xlm, and VBS under utilised Filter to provide the same multi-sheet search functionality as above.
The bulk of the code relates to the sheet selection portion
Sub GetNAmes()
Dim strIn As String
Dim X
strIn = Application.InputBox("Search string", "Enter string to find", ActiveSheet.Name, , , , , 2)
If strIn = "False" Then Exit Sub
ActiveWorkbook.Names.Add "shtNames", "=RIGHT(GET.WORKBOOK(1),LEN(GET.WORKBOOK(1))-FIND(""]"",GET.WORKBOOK(1)))"
X = Filter([index(shtNames,)], strIn, True, 1)
Select Case UBound(X)
Case Is > 0
strIn = Application.InputBox(Join(X, Chr(10)), "Multiple matches found - type position to select", , , , , 1)
If strIn = "False" Then Exit Sub
On Error Resume Next
Sheets(CStr(X(strIn))).Activate
On Error GoTo 0
Case 0
Sheets(X(0)).Activate
Case Else
MsgBox "No match"
End Select
End Sub