This question already has answers here:
Cells.Find() Raises "Runtime Error 91: Object Variable or With Block Not Set"
(5 answers)
Closed 2 years ago.
When I skip through the sub where it shows the problem, this happens:
I can't seem to resolve the Issue since i use the code snippet from this sub multiple times and it works fine.. Code here
Private Sub UserForm_Initialize()
Sheets("Data").Range("A:T").AutoFilter Field:=18
Sheets("Data").Range("A:T").AutoFilter Field:=18, Criteria1:="FALSCH"
ActiveWorkbook.Worksheets("Data").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Data").AutoFilter.Sort.SortFields.Add Key:=Range( _
"I:I"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Data").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Dim lRow As Long
Dim lCol As Long
lRow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
The structure should be something like this:
Dim ws As Worksheet
Set ws = Worksheets("Data")
Dim FoundAt As Range
Set FoundAt = ws.Cells.Find(What:="*", _
After:=ws.Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
If Not FoundAt Is Nothing Then
Dim lRow As Long
lRow = FoundAt.Row
'your other code here …
Else
MsgBox "Find failed!"
End If
First try to find the cell with ws.Cells.Find and reference it to a range variable FoundAt so you can test if a cell was found or not using If Not FoundAt Is Nothing Then, because .Row only exists if a cell was found. If you found nothing then nothing has no row (obviously).
Related
I am looking to sort columns by header names since the column where the header is may change using VBA. I found the below code but couldnt figure out how to make it sort by more than one field. Basically i am looking to have this filter by KEY, Status, Enrolled on, Completed on in that order.
Dim sortAdd As String
Dim sortRange As Range
'Find which column "KEY" appears in
On Error GoTo err_chk
Rows("1:1").Find(What:="KEY", After:=Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
On Error GoTo 0
sortAdd = ActiveCell.Address(0, 0)
'Set sort range by using current region
Range("A1").CurrentRegion.Sort _
key1:=Range(sortAdd), order1:=xlAscending, Header:=xlYes
Exit Sub
'Error handling
err_chk:
If Err.Number = 91 Then
MsgBox "No header row with title of KEY", vbOKOnly, "ERROR!"
Else
MsgBox Err.Number & ": " & Err.Description
End If
Recorded macro seemed to work but not really ideal.
Range("Deduped[[#Headers],[Key]]").Select
ActiveWorkbook.Worksheets("Deduped").ListObjects("Deduped").sort.SortFields. _
Clear
ActiveWorkbook.Worksheets("Deduped").ListObjects("Deduped").sort.SortFields. _
Add2 Key:=Range("Deduped[Key]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Deduped").ListObjects("Deduped").sort.SortFields. _
Add2 Key:=Range("Deduped[HR Status]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Deduped").ListObjects("Deduped").sort.SortFields. _
Add2 Key:=Range("Deduped[Enrolled on Date]"), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Deduped").ListObjects("Deduped").sort.SortFields. _
Add2 Key:=Range("Deduped[Completion Date]"), SortOn:=xlSortOnValues, Order _
:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Deduped").ListObjects("Deduped").sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sort On Multiple Columns
Option Explicit
Sub SortOnMultipleColumns()
Dim SortHeaders As Variant
SortHeaders = Array("KEY", "Status", "Enrolled on", "Completed")
Dim SortOrders As Variant
SortOrders = Array(xlAscending, xlAscending, xlAscending, xlAscending)
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim srg As Range: Set srg = ws.Range("A1").CurrentRegion
Dim shrg As Range: Set shrg = srg.Rows(1)
Application.ScreenUpdating = False
Dim ColumnIndex As Variant
Dim n As Long
For n = LBound(SortHeaders) To UBound(SortHeaders)
ColumnIndex = Application.Match(SortHeaders(n), shrg, 0)
If IsNumeric(ColumnIndex) Then
srg.Sort srg.Columns(ColumnIndex), SortOrders(n), , , , , , xlYes
Else
MsgBox "Could not find the header '" & SortHeaders(n) & "'.", _
vbCritical
End If
Next n
Application.ScreenUpdating = True
End Sub
I am working on a macro that will ask an user for an input, search for that column header (which will be the first row), then once found, it will add a filter and sort the data, hopefully preserving data integrity (I don't want it to only sort the one column). Seems to work ok up until I have my sort function, I keep getting an error. Any help would be appreciated.
Dim PutInput As Range
Dim UserPut As String
UserPut = Application.InputBox("Select Unique ID", Type:=2)
Set PutInput = Sheets("Sheet1").Range("A1:ZZ1").Find(What:=UserPut, _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not PutInput Is Nothing Then
Sheets("Sheet1").UsedRange.AutoFilter Field:=PutInput.Column
Sheets("Sheet1").UsedRange.AutoFilter.Sort.SortFields.Add Key:=Range("Sheet1[[#All],["& PutInput &"]]"), SortOn:=xlSortOnValues,
Order:=xlAscending
Else
MsgBox "No match found."
End If
Try this. There's a few things going on. First, when you set the key, just use the PutInput range directly instead of trying to manually construct the range. Also, you need to check if the autofilter is turned on already (or just leave out the sht.autofilter part entirely, but then somebody can just turn them off and break your code. Things will be simpler if you set a worksheet object and assign the sheet to that once, instead of referring to it multiple times.
Let me know how this works for you.
Sub filterIt()
Dim PutInput As Range
Dim UserPut As String
Dim sht As Worksheet
Set sht = ActiveWorkbook.Sheets("Sheet1")
UserPut = Application.InputBox("Select Unique ID", Type:=2)
Set PutInput = sht.Rows(1).Find(What:=UserPut, _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not PutInput Is Nothing Then
If sht.AutoFilterMode = False Then sht.UsedRange.AutoFilter
sht.AutoFilter.Sort.SortFields.Clear
sht.AutoFilter.Sort.SortFields.Add _
Key:=PutInput.Columns(1), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
With sht.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Else
MsgBox "No match found."
End If
End Sub
I was unable to find a similar question to this. Basically, I have an excel macro that I have ran probably hundreds of times and has been working fine up until today. Today, when I run it, I get a run-time error 91, object block not set.
The issue begins at this statement: quidTab.AutoFilter.Sort.SortFields.Clear
Does anybody have any advice? I am truly lost
Here is the code:
' Remove The flags that have not triggered on this QUID.
Sub RemoveEmptyFlags()
'
' removeEmptyFlags2 Macro
'
Dim filterRow As Integer, notTriggeredFlagRow As Integer, quidTab As Worksheet
Range("A1").Select
Cells.Find(What:="CE_", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
filterRow = ActiveCell.Row - 1
Rows(CStr(filterRow) & ":" & CStr(filterRow)).Select
Selection.AutoFilter
Set quidTab = ActiveWorkbook.ActiveSheet
quidTab.AutoFilter.Sort.SortFields.Clear
quidTab.AutoFilter.Sort.SortFields.Add _
Key:=Range("C" & CStr(filterRow)), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortTextAsNumbers
With quidTab.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' Find the start of the flags that have not triggered, and delete down.
Range("C" & CStr(filterRow)).Select
Cells.Find(What:="2", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
notTriggeredFlagRow = ActiveCell.Row
If ActiveCell.Row > filterRow Then
Rows(CStr(notTriggeredFlagRow) & ":" & CStr(ActiveWorkbook.ActiveSheet.UsedRange.Rows.Count)).Select
Selection.Delete Shift:=xlUp
End If
Range("A1").Select
End Sub
I am stuck with a rather complex search and replace function, which is made up of one large table with 3 columns defining the 1) sheet where to SnR, 2) search term, 3) replacement word. I am testing on a Test sheet with 10 entries, but cant get the script to process any of the cells in range...
Sub FART_find_and_replace_text()
Dim sheet_name, label_old, label_new As String
Dim i As Integer
Dim sheetrng As Range
Set sheet_rng = Range(Sheets("Test").Range("B65536").End(xlUp), Range(Sheets("Test").Range("B5"))) 'all queries
'Set sheet_name = Range(Sheets("Test").Range("B65536").End(xlUp), Range(Sheets("Test").Range("B5"))) 'sheet name
'Set label_old = Range(Sheets("Test").Range("D65536").End(xlUp), Range(Sheets("Test").Range("D5"))) 'search term
'Set label_new = Range(Sheets("Test").Range("E65536").End(xlUp), Range(Sheets("Test").Range("E5"))) 'replacement
i = 0 'set counter to 0
For Each cell In sheet_rng
With ThisWorkbook.Sheets(cell.Value)
.Activate
.Cells.Find(What:=cell.Offset(0, 2).Value, After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
.ActiveCell.Replace What:=cell.Offset(0, 2), Replacement:=cell.Offset(0, 3), LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End With
i = i + 1
Next
End Sub
I am running Office on MAC which I have been told is not great with VBA, but I sadly have no choice and appreciate all the help I can get.
Thank you
EDIT:
here a screenshot of my sample data
Note: my sheet name is in A, search value in C and replace value in D
Looks like your data is in B, D and E columns.
Following is the macro for A, C and D columns.
Sub FindReplaceMutiValMutiSheet()
Dim FRdata As Range, TempSh As Worksheet, TempData As Range, FRarr
LRow = Range("A" & Rows.Count).End(xlUp).Row
Set FRdata = Sheets("Sheet1").Range("A1:D" & LRow)
'Copy FRData to temporary sheet and assign it to TempData
Set TempSh = Sheets.Add(, Sheets(Sheets.Count))
TempSh.Range("A1").Resize(FRdata.Rows.Count, FRdata.Columns.Count).Value = FRdata.Value
Set TempData = TempSh.Range("A1:D" & LRow)
'Sort TempData on "Sheet Name" (A) and "Search" (C) Columns
With TempSh.Sort
.SortFields.Add2 Key:=Range(TempData(1, 1), TempData(TempData.Rows.Count, 1)) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add2 Key:=Range(TempData(1, 3), TempData(TempData.Rows.Count, 3)) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Range(TempData.Address)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'Array of TempData Values
FRarr = TempData.Value
'Delete TempSh as no longer required.
Application.DisplayAlerts = False
TempSh.Delete
Application.DisplayAlerts = True
'Find and replace loop basded on FRarr array
For i = 2 To UBound(FRarr, 1)
If ActiveSheet.Name <> FRarr(i, 1) Then Sheets(FRarr(i, 1)).Activate
Range("A1").Activate
Cells.Replace What:=FRarr(i, 3), Replacement:=FRarr(i, 4), LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Next
End Sub
Tested it on following sample data; works fine.
Hi i am writing a code in vb to check a particular value in a sheet, if the value is not available then it should go back to another sheet to take new value to find, if the value is found i have to do some operation on that sheet i have the below code to find the value in the sheet but if i pass the same in a DO WHILE loop as condition it gives a compile error
find vaue code
Selection.Find(What:=last_received, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
could some one please help me to write a code of DO WHILE with the above find in the loop condition so that if the condition gives false (i,e if the value is not found in the sheet) then i should use some other value to find
this is the code that i am going to put in loop
Sheets("Extract -prev").Select
Application.CutCopyMode = False
ActiveWorkbook.Worksheets("Extract -prev").Sort.SortFields.Clear 'sorting with tickets
ActiveWorkbook.Worksheets("Extract -prev").Sort.SortFields.Add Key:=Range( _
"C2:C2147"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Extract -prev").Sort
.SetRange Range("A1:AB2147")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Application.Goto Reference:="R1C3" 'taking last received ticket
Selection.End(xlDown).Select
Selection.Copy
Sheets("Calc").Select
Application.Goto Reference:="Yesterday_last_received"
ActiveSheet.Paste
this code takes the last ticket but based on it's availablity in next sheet "extract" i have to take one ticket previous to the last one (and on).
Try below code :
Sub test()
Dim lastRow As Long
Dim rng As Range
Dim firstCell As String
lastRow = Sheets("sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastRow
Set rng = Sheets("sheet2").Range("A:A").Find(What:=Cells(i, 1), LookIn:=xlValues, lookAt:=xlPart, SearchOrder:=xlByRows)
If Not rng Is Nothing Then firstCell = rng.Address
Do While Not rng Is Nothing
rng.Offset(0, 1) = "found"
Set rng = Sheets("sheet2").Range("A:A").FindNext(rng)
If Not rng Is Nothing Then
If rng.Address = firstCell Then Exit Do
End If
Loop
Next
End Sub