I have this code as an excel macro.
Dim MyData As DataObject
Set MyData = New DataObject
MyData.GetFromClipboard
MsgBox MyData.GetText
On Error GoTo NotFound
Cells.Find(What:=MyData.GetText, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
NotFound:
MsgBox writes the value correctly, but the What:=MyData.GetText just won't work. Why? Or, more importantly, how to fix it?
If it is not clear, I am trying to find the next value equal to the one in clipboard at the moment. I have referenced the MSForms so that is not the problem.
If I assign MyData.GetText to a variable and use the variable, the same happens, MsgBox works, BUT What:=myvariable doesn't.
Not sure why this works, but it does:
Sub test()
Dim MyData As DataObject
Dim rng As Excel.Range
Set MyData = New DataObject
MyData.GetFromClipboard
Set rng = ActiveSheet.Cells.Find(What:=MyData.GetText, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
rng.Activate
End Sub
Related
I have a problem, when I try to debug this coding it will appear
RUNTIME ERROR 91; OBJECT VARIABLE OR WITH BLOCK VARIABLE NOT SET
and it also will highlight at this line
Range("L8").Value = Cells(2, FindMe.Column).
May I know what is the error?
Sub Macro1()
'
' Macro1 Macro
'
' Keyboard Shortcut: Ctrl+Shift+A
'
Set Searchme = Range("L9")
Set FindMe = Range("A2:G126").Find(What:="Searchme", LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
Range("L8").Value = Cells(2, FindMe.Column)
Range("A1:G126").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
"L8:L9"), CopyToRange:=Range("N8:T8"), Unique:=False
End Sub
The value that you're trying to find doesn't exist in the range.
Try to wrap your code around If condition to check if find returns anything or not !
Sub test()
Set Searchme = Range("L9")
Set FindMe = Range("A2:G126").Find(What:="Searchme", LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If FindMe Is Nothing Then
MsgBox "No value found."
'or you can negate the condition like "If Not" if you want to continue and remove the else part.
Else
Range("L8").Value = Cells(2, FindMe.Column)
Range("A1:G126").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range( _
"L8:L9"), CopyToRange:=Range("N8:T8"), Unique:=False
End If
End Sub
I have an excel file that has the text "Income from Trans" where I will need to delete the entire column.
This is my current code in VBA 2010 that works until there are no more cells with "Income from Trans"; I can't get it to break out of the loop.
Any idea why?
Dim rng1 As Range
Dim target1 As String
target1 = "Income From Trans"
Set rng1 = Cells.Find(What:=target1, _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
Do Until rng1 Is Nothing
Cells.Find(What:=target1, After:=ActiveCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows,
SearchDirection _
:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.EntireColumn.Delete
Loop
Your code Set rng1 = Cells.Find... will set rng1 to be a range object, assuming it finds your value. Next is your loop which will ultimately cause rng1 to be deleted. It continues to loop because even though rng1 is deleted it still was assigned and therefore isn't Nothing. It ends with an run time error message of 91 because rng1 was set but deleted. You can see in the locals window View>Locals Window that its type is still Range\Range even though it's actually been deleted.
You have implicit cell references from the unqualified Cells usage. That means this code will run on whatever worksheet happens to be the ActiveSheet. Implicit references can have unintended side effects when you don't realize this. It's best to fully qualify them so there's no ambiguity as to which sheet they reside on. I'm assuming ActiveCell falls into this category too since you want it to wrap delete until there "Income from Trans" is no longer found.
The code .Activate followed by ActiveCell. isn't needed and can be shortened by removing both so it ends up as SearchFormat:=False).EntireColum.... Selecting a range object isn't usually necessary. Joining the two makes it apparent what you're doing.
Below you'll find a simpler version that uses .Find is in your original to find the first instance. After that it uses .FindNext() to continue looping until all are found. This eventually exits because it is setting the range variable found after every deletion, ultimately leaving found as Nothing after it's deleted the last. The RemoveColumns has parameters which allow you to use this on more than just a single sheet.
Sub Test()
RemoveColumns Sheet1, "Income From Trans"
End Sub
Sub RemoveColumns(ByVal sheetToSearch As Worksheet, ByVal value As String)
Dim found As Range
Set found = sheetToSearch.Cells.Find(What:=value, After:=sheetToSearch.Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False)
Do Until found Is Nothing
found.EntireColumn.Delete
Set found = sheetToSearch.Cells.FindNext
Loop
End Sub
Check the search result inside the loop as well
Dim rng1 As Range, target1 As String, firstFound As String
target1 = "Income From Trans"
Set rng1 = Cells.Find(What:=target1, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not rng1 Is Nothing Then
Do
firstFound = rng1.Address
Set rng1 = Cells.Find(What:=target1, After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False)
If Not rng1 Is Nothing Then rng1.EntireColumn.Delete
Loop While Not rng1 Is Nothing And rng1.Address <> firstFound
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
I'm receiving a Run-time Error '91' Object Variable or With Block not Set for the following code.
I'm confused as I'm not using any object variables (I don't think, I'm new to VBA). Debugging highlights the 6th row.
My code is:
Dim i As Integer
i = 1
Columns("A:A").Select
Selection.Find(What:="" & Cells(i, 19).Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
MsgBox ActiveCell.Row
I'm receiving a Run-time Error '91' Object Variable or With Block not Set for the following code.
When working with .Find, check if a match was returned and then show the row if found else you will get the above error.
Try this
Option Explicit
Sub Sample()
Dim i As Integer
Dim aCell As Range
Dim ws As Worksheet
i = 1
'~~> Replace this with the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
Set aCell = .Columns(1).Find(What:=.Cells(i, 19).Value, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
'~~> Check if the find returned a match
If Not aCell Is Nothing Then
MsgBox aCell.Row
Else
MsgBox "Not Found"
End If
End With
End Sub
I am struggling to create a code to search for a value within a workbook that I am accessing without bringing it to the foreground. I am using the following code to access the file as "xl0":
'DATABASE ACCESS
Dim xl0 As New Excel.Application
Dim xlw As New Excel.Workbook
Dim db_directory As String
db_directory = "R:\New Quality Management System\xls\Supplier Non-Conformance\Supplier Non-Conformance Database.xlsm"
Set xlw = xl0.Workbooks.Open(db_directory)
I have successfully had this working to add records to the xl0 spreadsheet however I also need to create a modify record macro to "find" an index value and extract the row number. I tried several variations (2 examples below) with no success, can anyone advise?
Eg 1.
Windows("Supplier Non-Conformance Database.xlsm").Activate
Cells.Find(What:="2015-16-46", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Eg 2.
xl0.Worksheets("SNCR Log").Range("B:B").Find(What:="2015-16-46",
After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Thanks in advance,
Dan
Here is a start :
(btw, the activation is really greedy in resources, so try to avoid it as much as possible!)
Application.ScreenUpdating=False
'DATABASE ACCESS
Dim xl0 As New Excel.Application
Dim xlw As New Excel.Workbook
Dim db_directory As String
xl0.Visible=False
db_directory = "R:\New Quality Management System\xls\Supplier Non-Conformance\Supplier Non-Conformance Database.xlsm"
Set xlw = xl0.Workbooks.Open(db_directory)
MsgBox xlw.Sheets(1).Cells.Find(What:="2015-16-46", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
Application.ScreenUpdating=True