VBA Find problems - error when nothing found - excel

I bet this is something simple. Even though I've researched a lot and tried several methods I still get run time error 424.
The code is to find a number the user has entered. If the number is in the data set I want to do one thing but if the number is not in the data set I want to do something else.
Code is below.
Sub Test()
Dim Material As String
Dim cell As Range
Material = InputBox("Enter BIS # for material type")
Range("A7:a40").Select
Set cell = Selection.Find(What:=Material, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _, SearchFormat:=False).Activate
If cell Is Nothing Then
MsgBox "Boo"
Else
MsgBox "Great"
End If
End Sub

You can't call Activate if Find returns nothing, so that will cause an error. Also, Activate is a sub, not a function, so you can't set cell to its return value.
Note: There's no need to Select the Range("A7:A40") for the Find function to work. You can fully qualify the Range that the Find function is searching for the specific value by using Range("A7:A40").Find...
Try this instead:
Sub Test()
Dim Material As String
Dim cell As Range
Material = InputBox("Enter BIS # for material type")
Set cell = Range("A7:A40").Find(What:=Material, LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False)
If cell Is Nothing Then ' <-- this lines checks if Find failed to find a match
MsgBox "Boo"
Else
cell.Activate
MsgBox "Great"
End If
End Sub

Related

Copy a range to a variable, then offset that range variable and save the value to another variable

So I am trying to search for a cell range with a specific string, then copy the contents of the cell 3 spaces under it to save to another spreadsheet.
The code I have so far does this, but it seems clumsy to need to select the cell then offset it with variableName.Select then ActiveCell.Offset(blahblah).
Is it possible to offset to (and pull the value from) the desired cell by calling variableName.Offset(3,0).Value or something of that nature to clean up the code?
Here is the code I have so far, and thanks in advance for your help!
Dim ra As Range
Sheets("starting").Activate
Set ra = Cells.Find(What:="Product Name", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True)
'finds correct cell
If ra Is Nothing Then
MsgBox ("Search Error: Not found")
Else
MsgBox (ra.Address) ' to test
End If
Dim foundCell
ra.Select
ActiveCell.Offset(3, 0).Select
'foundCell = Cells(ra).Offset(0, 3) '.Address '.value ' <<< not grabbing the data
foundCell = ActiveCell.Value
MsgBox foundCell 'shows the value of the desired cell now! (to test)
Sheets("testing").Activate
Sheets("testing").Cells(2, "F").Value = foundCell '2,"F" will be replaced by a range stored in a variable
This will do the same thing:
Sub Test()
Dim ra As Range
Set ra = Sheets("starting").Cells.Find(What:="Product Name", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True)
If ra Is Nothing Then
MsgBox ("Search Error: Not found")
Else
MsgBox (ra.Address) ' to test
Sheets("testing").Cells(2, 6) = ra.Offset(3, 0)
End If
End Sub
I've put the copying it into the testing sheet within the If ra Is Nothing test.
As your code stands it would display the message "Search Error: Not found" and then try offset three rows from the value it didn't find giving an Object variable or With block variable not set error.

How to check whether a row contains certain text

I am trying to check whether Row 1 of my active sheet named "Exceptions" contains the text "Control  Date" (two spaces) or "Control Date".
My code finds the condition false.
Dim a As Range
Dim exceptions As Worksheet
Set exceptions = ActiveWorkbook.Worksheets("Exceptions")
For Each c In Exceptions.Range("A1:Z1")
If c = "Control Date" Then
Cells.Find(What:="control date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Else
Cells.Find(What:="Control Date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
End If
Next c
Example of a worksheet with two spaces in "Control  Date"
How to write the condition
As far as checking if the cell value is "Control Date" with a single space or one with two spaces, there are two ways of going about it:
Use the like operator
The like operator makes it easy to compare a string to a basic pattern. In this example, using the wildcard character * (Zero or more characters) will return true regardless of how many spaces are between Control and Date.
If cell.Value2 Like "Control*Date" Then
' Do something with that cell
End If
Use the or operator
Using the or operator ok to use as well, although not a flexible and perhaps a bit more difficult to see what's going on for your specific example.
If cell.Value2 = "Control Date" Or cell.Value2 = "Control Date" Then
' Do something with that cell
End If
Worksheet Codename
Each worksheet has whats called a codename. This is a reference that can be called directly in the code to that specific worksheet by it's name.
To set this name, in the properties window update the name property
So instead of
Dim Exceptions As Worksheet
Set Exceptions = ActiveWorkbook.Worksheets("Exceptions")
For Each cell In Exceptions.Range("A1:Z1")
' Do something...
Next cell
you can call the worksheet reference directly
For Each cell In Exceptions.Range("A1:Z1")
' Do something...
Next cell
Putting it together
Instead of using c for your variable, I like to make my variables easier to read and follow so I used cell.
Also, instead of hard coding your header columns in range, you could loop the cells of the entire first row. This is option suggestion though.
Lastly, be more explicit in what property you are looking for in your Cell. In my example I use .value2 to show I am looking for the value of that cell.
Public Sub Demo()
Dim cell As Range
For Each cell In Exceptions.Rows(1).Cells
If cell.Value2 Like "Control*Date" Then
' Do something with that cell
End If
Next cell
End Sub
Why duplicate the data into a third column? Whenever you need the "combined" date, just go get it, but do not store it twice.
Option Explicit '<<-- always have this
Sub doFindControl()
Dim a As Range
Dim c As Range '<<-- add this
Dim colDate As Long, colNumber As Long, colBlank As Long '<<--add this
Dim exceptions As Worksheet
Set exceptions = ActiveWorkbook.Worksheets("Exceptions")
For Each c In exceptions.Range("A1:Z1")
' first find the 2 key columns
If InStr(c, "Control") > 0 Then
If InStr(c, "Date") > 0 Then
colDate = c.Column
ElseIf InStr(c, "Number") > 0 Then
colNumber = c.Column
End If
' second look for the first blank column for you to put results in
ElseIf c.Text = "" Then
colBlank = c.Column
Exit For ' stop looking after its found
End If
Next c
' now you have the 2 FROM columns, and the TO column
MsgBox (colDate & " " & colNumber & " " & colBlank)
' and you can loop thru all the rest of the rows doing combine
End Sub
Thank you for all the answers! Robert Todar's answer led me to my lightbulb moment, and I can't believe at how simple the answer was. All I had to do was change this code:
Cells.Find(What:="Control Date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
to:
Cells.Find(What:="Control*Date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate

Macro to look up value in sheet 2 from a cell in sheet 1, and input date into corresponding row in sheet 2

I'm really new to VBA, and could do with your help please.
Sheet2 is a long list of data (jobs) where each row in column B contains a unique job reference number.
I want users to input one of these numbers into a cell in Sheet 1 (G11), then the macro searches Sheet2ColumnB for the number, goes across 21 cells in that same row, then enters today's date and time into that cell.
(It then goes back to Sheet1 and says "Job Booked Out" but I think I can do this bit)
I've tried to modify some other code I've found, but get errors in the 4th line, and I have no clue if it works.
Sub CloseJob()
Dim cell As Range
Dim temp As Range
For Each cell In Sheets("Sheet1").UsedRange.cell("G11").Cells
If cell <> "" And cell.Row <> 1 Then
Set temp = Sheets("Sheet2").Columns("B").Find(What:=cell.Value, _
LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=True)
'if found
If Not temp Is Nothing Then
'if the search_criteria is in the same sheet
cell.Offset(0, 21) = Date
End If
End If
Next
End Sub
Error:
"Run-time error 483. Object doesn't support this property or method"
by your narrative you seem after this:
Sub CloseJob()
Dim temp As Range
Set temp = Sheets("Sheet2").Columns("B").Find(What:=Sheets("Sheet1").Range("G11").Value, _
LookIn:=xlFormulas, LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=True)
'if found
If Not temp Is Nothing Then temp.Offset(0, 21) = Date
End Sub
notice I changed LookAt:=xlPart to LookAt:=xlWhole for an exact match
Test and I will be able to get connect with like minded peopl

MsgBox after not finding a value

I have a macro that runs an InputBox in which user types number and then excel finds a cell in a certain range which contains that value. I'd like to make an MsgBox which would make an alert if given number is not found and run InputBox again until the value is in range.
I have kinda idea how do I do it, but can't make the finding itself work. I've recorded a macro but don't know how to set it properly if it doesn't find anything.
My code so far:
Sub leftbutton()
Start: n = InputBox("Podaj numer punktu z wykresu") 'give me a point number from a chart
If n = "" Then Exit Sub
If n = "0" Then
MsgBox ("Liczba musi byc wieksza od zera") 'number must be > 0
GoTo Start
End If
If Not IsNumeric(n) Then
MsgBox ("Podaj liczbe!") 'give me a number!
GoTo Start
End If
Range("AS3:AS50000").Select
if
Selection.Find(What:=n, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase _
:=False, SearchFormat:=False).Activate 'now how to know if it finds value or not?
Then msgbox("Nie ma takiego punktu na wykresie") 'there's no such point on a chart
Goto Start
Else '~> select cell with the found value
End If
End Sub
Code below will check in your range you specified and either give you error if nothing is found or row number of cell with match.
Dim FindResult As Object
n=... 'set whatever value you want to find
Range("AS3:AS50000").Select
Set FindResult = Selection.Find(n, LookIn:=xlFormulas, LookAt:=xlWhole)
If FindResult Is Nothing Then
MsgBox ("missing")
Else
MsgBox (FindResult.Row)
End If

Excel Macro: Find and Compare Username from a Range of Authorized Usernames

Excel Macro: How to code this "If username [example code: Environ("Username")] is equal to one of the values within this range [example: Range I created from a workbook: Range("Authorized_Users")] then..." Thanks!
Basically you have to do exactly what you have written. What currently is missing for your solution are two things:
A way to retrieve the user name.
A way to search in a range.
Both tasks should't be that hard because excel already offer some great functions to do so.
For the second point, you would have to create a function, that searches a range. The find in range function would look something like this:
Function ExistsInRange(range As range, name As String) As Boolean
ExistsInRange = False
Dim resultRange As range
If Trim(name) <> "" Then
With range
Set resultRange = .Find(What:=name, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not resultRange Is Nothing Then
ExistsInRange = True
End If
End With
End If
End Function
If you want to search all rows in Column B for the user name "jeff", the call would look something like this:
If ExistsInRange( sheet.Range("B:B"), "jeff") Then
Your spec is so close to the required code...
If Not IsError(Application.Match(Environ("Username"), [Authorized_Users], 0)) Then

Resources