VBA cannot correctly handle range returned by find method - vba

I have this code:
Private Sub UserForm_Initialize()
Dim Text_Cell As Range
Dim temp As Control
Set Text_Cell = Sheet1.Cells.Find("Text")
Do Until Text_Cell.Offset(1, 0).Value = ""
Set temp = UserForm1.MultiPage(1).Controls.Add("Forms.Commandbutton.1", "h")
Set Text_Cell = text_Cell.Offset(1, 0)
Loop
EDIT: Just a quick clarification - using MsgBoxes, breakpoints, science, magic, etc. I found out the cause of the "Object required" error occurs well before VBA gets to the loop.
I am trying to find a cell in a sheet that has the value of "text" then for each cell with a value below it - create a control on my userform. The problem I am having is that the Find method finds the correct cell, returns and assigns it but for some reason VBA cannot handle the "text_Cell" variable, even though after setting a breakpoint and taking a look at the local variable of "text_Cell" I saw it is assigned to the proper cell. I keep getting "Object Required" error. Getting the cell alone returns nothing, hence trying to reference Offst(1,0) raises the "Object required" error.

I am trying to find a cell in a sheet that has the value of "text" then for each cell with a value below it - create a control on my userform.
Use the following to cycle through all of the non-blank cells beneath the cell with text.
Set Text_Cell = Sheet1.Cells.Find(What:="text", MatchCase:=False, _
LookAt:=xlWhole, LookIn:=xlFormulas)
Do Until Text_Cell.Value = ""
Set temp = UserForm1.MultiPage(1).Controls.Add("Forms.Commandbutton.1", "h")
Set text_Cell = text_Cell.Offset(1, 0)
Loop

Related

Excel VBA .Find Function changing values in selection

Heya this is probably simple but I cannot figure out what is wrong.
I am trying to do .find for a specific date and change that selection to a user input date.
I have a userform to select a date from a combobox (date1_cbo). The combobox source is linked to dates on a worksheet (Backend). There is a textbox below for writing the new date to change it to (date1_txt). I keep getting an error
object variable or with block variable not set.
I have tried a few options without any luck here is my code:
Dim selection As Range
Dim check As Boolean
'input box validation
check = IsDate(date1_txt.Value)
If check = True Then
'find cell matching combobox
With Worksheets("Backend").Range("A1:A500")
Set selection = .Find(date1_cbo.Value) 'this is the problem
selection.Value = date1_txt.Value
End With
Else
End If
Interestingly .Find returns the range or Nothing. however because the combobox is linked to the cells I am searching through this should never return nothing... I dont understand why the error is occurring.
a variable named as 'selection' is bad coding practice but totally legal. Don't use such names for the sake of clarity.
Error 91 is caused when you are trying to read a property( .value) from null object. your selection variable is null cause date formats on the sheet and combobox are different.
Just convert to date before attempting to find it in sheet.
Set selection = .Find(CDate(date1_cbo.Value)) '/ once again, selection is valid but bad name for variable.
You are using a variable named Selection. VBA uses it as well. Rename your variable to anything else, rewrite your code and it should work. Even Selection1 is quite ok:
Public Sub TestMe()
Dim selection1 As Range
With Worksheets(1).Range("A1:A500")
Set selection1 = .Find("vi")
End With
If Not selection Is Nothing Then
selection1.Value = "some other value"
End If
End Sub
To change multiple values with Find() as here - A1:A10, then some possibility is to do it like this:
Public Sub TestMe()
Dim myRng As Range
With Worksheets(1).Range("A1:A500")
.Range("A1:A10") = "vi"
Set myRng = .Find("vi")
If Not myRng Is Nothing Then
Do Until myRng Is Nothing
myRng.Value = "New value"
Set myRng = .Find("vi")
Loop
End If
End With
End Sub
It is a bit slow, as far as it loops every time and it can be improved, if the range is united and replaced at once.

accessing .name.name attribute of excel cell while iterating over usedrange

I'm trying to iterate over the used range in a worksheet and match the given .name.name attribute to a cStringBuilder for future use in a web application.
But I'm running into errors with the append function and using the .name.name attribute of a cell.
If I use something like Worksheets("MAIN").Range("F2").name.name I extract the correct information. But it doesn't work will the for loop.
If I use cell.nameit does however extract the correct cell values. But I have to match a .name.name attribute as I can't be sure on exactly where in the sheet the data is presented always.
The error message I'm getting is: Run-time error '1004': Application-defined or object-defined error
Here's my coding that I'm trying to make work.
Public Function Testing() As cStringBuilder
Dim strJson As cStringBuilder
Set strJson = New cStringBuilder
For Each cell In Worksheets("MAIN").UsedRange
If cell.Value <> "" Then
strJson.Append (cell.name.name)
End If
Next
Testing = strJson
End Function
For Each cell In Worksheets("MAIN").UsedRange
On Error Resume Next
Debug.Print cell.Name.Name
Next cell
This seems to work for me, if there isn't a name, you'll get an error.

Error runtime 91 and 429

This code feels like Schrodinger is executing it. If I open the project and run the code, I won't get any errors at all. If I view the code to edit or add anything, the first time I run the code, I get 'Run-time error 91'. If I try to run it a second time, making no changes, I get 'Run-time error 429' (ActiveX component can't create object).
What I'm trying to achieve is to find the row (BuildSel) in a range on worksheet (Ref) that has the same value as what's selected in a list on a userform (BuildList). Then once the row is found, to take data from that row and columns A and B, and put them in textbox's on my userform. Is my code right and ActiveX making the error? I apologize for terrible coding too.
EDIT: The listbox is on a multipage on my userform. I first noticed the issue today when I tried adding another listbox on a different page.
Private Sub BuildList_Click()
Dim Ref As Worksheet, BuildSel As Long
Set Ref = ThisWorkbook.Sheets("Ref")
BuildSel = Ref.Range("B2", Ref.Range("B" & Rows.Count).End(xlUp)).Find(BuildList.Value, lookat:=xlPart).Row
BuilderText.Value = Ref.Range("A" & BuildSel).Value
CompNameText.Value = Ref.Range("B" & BuildSel).Value
End Sub
Not sure why altering 'BuildSel' to variant makes it work, but the code as it stands has no error checking for when there is no matching list item to be found
The following code should be better suited for usage:
Private Sub BuildList_Click()
Dim Ref As Worksheet: Set Ref = ThisWorkbook.Sheets("Ref")
Dim BuildSel As Range
With Ref
Set BuildSel = .Range("B2", .Range("B" & Rows.Count).End(xlUp)).Find _
(BuildList.Value, lookat:=xlPart)
If Not BuildSel Is Nothing Then
BuilderText.Value = .Range("A" & BuildSel.Row).Value
CompNameText.Value = .Range("B" & BuildSel.Row).Value
Else
BuilderText.Value = ""
CompNameText.Value = ""
End If
End With
End Sub

Use VLOOKUP to pass cell reference to a public variable?

I have a userform that opens on cell change in a column.
That userform contains checkboxes, which all trigger a second userform with a text box which looks up a cell on a hidden sheet for its contents. (The checkbox that's ticked determines which cell the textbox looks for). The user then edits the box, clicks a button, and the new text is written back to the same cell.
This is the VBA for when the checkbox is ticked. It works great. Hooray!
Dim vln As Variant
Dim reta As Worksheet
Set reta = ActiveWorkbook.Sheets("RetailerActivity")
Set vln = ActiveCell.Offset(-1, -3)
UserForm2.TextBox1.Text = Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False)
UserForm2.TescoSave.Visible = True
UserForm2.Show
End Sub
When the textbox has been edited, I would like to write it back to the same cell it came from. I figure the easiest way to do that is to have a public variable (as range), and to pass the result of the vlookup into that variable so the second userform can have a line which reads
Private Sub ASave_Click()
publicvariable.Value = TextBox1.Value
userform1.hide
End Sub
Nice and easy, rather than doing a VLookup again. Right?
Either way, I can't seem to set the public variable as the lookup.
Outside of any sub I have
Public bums As Range
And in the code above, after the bit where I've set the text box, I've tried to add the line
Set bums = Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False)
But the code errors with a "type mismatch".
If I try
Set bums = Range(Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False))
I get method "Range" of object "_global" failed.
I code by cobbling bits off the internet, as you can probably tell, so this is I don't doubt a complete kludge.
Any advice would be super appreciated.
VLookup returns a value, not a Range. You could use Match to find the row and then Cells to get the actual reference - for example:
Dim vMatch
vMatch = Application.Match(vln, reta.Range("A1:A100"),0)
If Not IsError(vMatch) then
Set bums = reta.Cells(vMatch, "C")
else
msgbox "No match for " & vln
Exit Sub
End If
Personally I would also not use a public variable, but create a property for Userform2 to which you can assign the range.

VBA for Excel throws "Object variable or with block variable not set" when there is no Object

In my code, I have declared these variables:
Dim Field_Name, Datatype, row As Integer
Then, inside a For loop, I have this code:
Field_Name = Worksheets(i).UsedRange.Find("Field Name").Column
Datatype = Worksheets(i).UsedRange.Find("Datatype").Column
row = Worksheets(i).UsedRange.Find("Field Name").row + 1
However, that code throws the "Object variable or with block variable not set" run-time error. According to the API, the Range.Column and Range.row property is a read-only Long. I have tried making the datatype of my variables to Long, but with no success. It would appear that VBA expecting me to do
Set Field_Name = Worksheets(i).UsedRange.Find("Field Name").Column
Set Datatype = Worksheets(i).UsedRange.Find("Datatype").Column
Set row = Worksheets(i).UsedRange.Find("Field Name").row + 1
However, said variables are not objects, so doing that throws the "Object required" compile error.
Any help with this would be greatly appreciated. If you're not sure about how to fix it, then any workarounds or alternative ways to get the column number and row number of a cell would be greatly appreciated.
Even though this is an old question, I'd like to say something too.
I had the same problem to get this error while using the .Find method. I came to this question and so others will do the same.
I found a simple solution to the problem:
When Find does not find the specified string it returns Nothing. Calling anything directly after Find will lead to this error. So, your .Column or .row will throw an error.
In my case I wanted an Offset of the found cell and solved it this way:
Set result = Worksheets(i).Range("A:A").Find(string)
If result Is Nothing Then
'some code here
ElseIf IsEmpty(result.Offset(0, 2)) Then
'some code here
Else
'some code here
End If
Simplified answer:
Your .Find call is throwing the error.
Simply adding "Set " to that line will address the problem. i.e...
Set Datatype = Worksheets(i).UsedRange.Find("Datatype").Column
Without "Set," you are attempting to assign "nothing" to a variable. "Nothing" can only be assigned to an object.
You can stop reading here unless you would like to understand what all the other (valid, worthwhile) fuss was about your code.
To paraphrase all of the (warranted) code critiquing, your Dim statement is bad. The first two variables are not being "typed" and end up as variants. Ironically, this is why the solution I just described works.
If you do decide to clean up that Dim statement, declare DataType as a variant...
Dim DataType as variant
What about the below code:
For i = 1 to 1 ' change to the number of sheets in the workbook
Set oLookin1 = Worksheets(i).UsedRange
sLookFor1 = "Field Name"
Set oFound1 = oLookin1.Find(What:=sLookFor1, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If Not oFound1 Is Nothing Then
Field_Name = oFound1.Column
RRow = oFound1.Row +1
' code goes here
Else
Msgbox "Field Name was not found in Sheet #" & i
End If
Set oLookin2 = Worksheets(i).UsedRange
sLookFor2 = "Datatype"
Set oFound2 = oLookin2.Find(What:=sLookFor2, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If Not oFound2 Is Nothing Then
DataType = oFound2.Column
' code goes here
Else
Msgbox "Datatype was not found in Sheet #" & i
End If
Next i
This is an old old post - but I ran across it when I was having trouble figuring out why I suddenly could not import a PDF export into my excel sheet.
For me the problem was a row I was trying to match on was merged - did a simple unmerge for the entire sheet first and it worked like a charm.
'////// Select and open file
FieldFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") 'pick the file
Set frBook = Workbooks.Open(FieldFileName, UpdateLinks:=0, ReadOnly:=True, AddToMru:=False)
For Each mySheet In frBook.Worksheets
mySheet.Cells.UnMerge
Next mySheet