need be more dynamic when using search function in vba - vba

I have the following code and is stuck when wondering how to make the search result more dynamic, that is after searching the "price", i need to copy the "price" and the cell at the right of it to cell A1, any help is appreciated.
Sub Macro1()
Cells.Find(What:="price", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
Range("L14:M14").Select
Selection.Copy
Range("A1").Select
ActiveSheet.Paste
Range("A1").Select
End Sub

Sub Macro1()
Dim f as Range
Set f = Activesheet.Cells.Find(What:="price", After:=ActiveCell, _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:= False, SearchFormat:=False
if not f is nothing then
f.resize(1,2).copy Activesheet.Range("a1")
end if
End Sub

Related

vba Entire Column should copy

" find " cell value in header will keep changing in raw file, i need " find " cell value ENTIRE column should copy and paste in sheet2
Sub Macro3()
Cells.Find(What:="FSP Center", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate`
Cells.FindNext(After:=ActiveCell).Activate`
Columns("A:A").Select 'i want to select entire column
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Paste
End Sub
Sub Macro3()
Dim f As Range
Set f = Rows(1).Find(What:="FSP Center", After:=ActiveCell, _
LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not f Is Nothing Then
f.EntireColumn.Copy Sheets("Sheet2").Range("A1")
End If
End Sub
'fixed the misspelling "If"

VBA Run-Time Error 91 - 2

I have a macro which works for the first 36 rows but then shows a run-time 91 error. It shows the error in find statement. The purpose of the macro is to calculate the 90th percentile of the figures populated in a column, count the number of values which are equal or greater the percentile, and provide the division across various departments. Can anybody please help me to correct the error?
For bb = 1 To temcnt
cc = Sheets("tem").Cells(bb, ttc + 4).Value
Sheets("Geographic Strength").Activate
Cells.Find(What:=cc, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ff1 = ActiveCell.Column
Sheets("tem").Activate
rnggg = Range(Cells(2, 6), Cells(ttr, 6))
mamm = WorksheetFunction.CountIf(Range(Cells(2, 6), Cells(ttr, 6)), cc)
Sheets("geographic strength").Activate
f222 = Sheets("individual strength").Cells(1, iii).Value
**Cells.Find(What:=f222, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
f333 = ActiveCell.Row**
'Error is in the above statement(Cells.Find)
Cells(f333, ff1).Value = mamm
Next bb
Sheets("tem").Delete
Next iii
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
it's because
Cells.Find(What:=f222, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
didn't succeed in finding the wanted cell so it returns Nothing, and you can't Activate Nothing
so you could go like follows:
'... your code before
f222 = Sheets("individual strength").Cells(1, iii).Value
Dim found As Range
Set found = Cells.Find(What:=f222, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not found Is Nothing Then '<-- check if any cell has been found
found.Activate
f333 = ActiveCell.Row
'... rest of your code should f222 have been found
End If
' rest of your code

Looking for multiple terms (sorted by priority)

Would it be possible to use the find method to search for back-up options?
Here's my code right now:
Set foundCell = Cells.Find(What:="RCP 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
foundCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A" & (PLcount + 8)).Select
ActiveSheet.Paste
Else
Set foundCell = Cells.Find(What:="RCP- 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
foundCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A" & (PLcount + 8)).Select
ActiveSheet.Paste
End If
End If
I would like to be able to do something like below. Note the text after .Find(What:=)
Set foundCell = Cells.Find(What:="RCP 1" "RCP- 1" "RCP 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
foundCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A" & (PLcount + 8)).Select
ActiveSheet.Paste
End If
Where the first term is the first priority, the second term is the second priority, the third term is the third priority, etc.
EDIT - there is only limited support for wildcards in Find() - you would probably not class it as "regex-level" functionality:
* - zero or more characters
? - single character
~ - escapes * or ? if you want to find those literal characters
Alternatively can put the Find into a separate function:
Sub Tester()
Dim foundCell, PLCount As Long
PLCount = 3
Set foundCell = FindFirst(Cells, Array("RCP 1", "RCP- 1"))
If Not foundCell Is Nothing Then
'no need for any select/activate
foundCell.EntireRow.Copy Destination:=Range("A" & (PLCount + 8))
End If
End Sub
'return the first match to a value in the array "arrWhat"
' Returns Nothing if no match
Function FindFirst(rngWhere, arrWhat) As Range
Dim v, f As Range
For Each v In arrWhat
Set f = rngWhere.Find(what:=v, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not f Is Nothing Then Exit For
Next v
Set FindFirst = f
End Function

If (search term) found, do (action). If not, end if

If you guys could help me out, that would be great because it would really help me.
Here's what I'm trying to do:
Search for a cell with a specific term
If found, copy the entire row that the cell is in and paste it into a row above it.
If not found, do nothing and continue with the code
Here's my code:
Sub Test()
'
' Test Macro
'
' Keyboard Shortcut: Ctrl+b
'
Range("A5").Select
Cells.Find(What:="PL 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
If Not IsEmpty(ActiveCell.Value) Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A5").Select
ActiveSheet.Paste
End If
Range("A5").Select
Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
If Not IsEmpty(ActiveCell.Value) Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A6").Select
ActiveSheet.Paste
End If
Range("A5").Select
Cells.Find(What:="PL 3", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
If Not IsEmpty(ActiveCell.Value) Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A7").Select
ActiveSheet.Paste
End If
End Sub
My code only works if the value is found. If it's not found it runs into the error below:
Cells.Find is a function that returns a Range object reference; when it doesn't find anything, the reference will be Nothing. And you can't call .Activate on Nothing:
This method returns Nothing if no match is found. The Find method does not affect the selection or the active cell. (MSDN)
Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
You need to rewrite your code and avoid .Select and .Activate, and avoid working with ActiveCell and implicitly with ActiveSheet (which you are doing by not qualifying the Cells call with a proper worksheet reference).
Your formatting makes it hard to read the code, for several reasons:
Arguments are being specified on different lines
Line continuations are being palced at arbitrary locations
Nested member calls aren't lined up
Compare to:
Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False) _
.Activate
That's just readability. The problem is that you basically assume that .Find returns a valid object reference. Don't assume, explicitly check:
Set result = Cells.Find(...)
If Not result Is Nothing Then result.Activate
But really, you need to figure out a way to avoid .Select and .Activate.
You can try something like this instead (untested):
Sub HideAndSeek()
Dim foundCell As Range
For i = 1 To 3
Set foundCell = Cells.Find(What:="PL " & i, LookIn:=xlFormulas, LookAt:=xlPart)
If Not foundCell Is Nothing Then
Intersect(foundCell.EntireRow, ActiveSheet.UsedRange).Offset(-1, 0).Value = _
Intersect(foundCell.EntireRow, ActiveSheet.UsedRange).Value
End If
Set foundCell = Nothing
Next
End Sub
The principle being that you write the code you need once and then create a loop to repeat the code for you.
The other part of this answer is checking that the cell was found - to do this we check that the range was actually set (which means it isn't Nothing) using
If Not foundRange Is Nothing

Problems with a table selection

I'm trying to select the contents (the range X11:Xnn) of the table:
KEYWORD2
X11 X12 ... X1N
X21 X22 ... X2N
... ... ... ...
XN1 XN2 ... XNN
KEYWORD1
No Important Thingsā€¦
So, I want select only the range X11:XNN doing a search of the 2 keywords and then select only the Xii.
I'm trying to do this:
Sub Macro3()
Cells.Find(What:="KEYWORD1", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Selection.Offset(-1, 0).Select 'I don't want the KeyWord1 appears
Cells.Find(What:="KEYWORD2", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Selection.Offset(1, 0).Select 'I don't want the KeyWord2 appears
Range(??, ??).Select
End Sub
Your main issue is that you are not returning the location of the keywords so that you may use them later. Lets capture those results and we can offset them we we call the range.
Sub Macro3()
Dim rngKeywordOneLocation As Range
Dim rngKeywordTwoLocation As Range
Set rngKeywordOneLocation = Cells.Find(What:="KEYWORD1", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Set rngKeywordTwoLocation = Cells.Find(What:="KEYWORD2", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Range(rngKeywordOneLocation.Offset(1, 0), rngKeywordTwoLocation.Offset(-1, 0)).Select
End Sub
Also, you should be careful with your use of .select.