setting the value of a cell in a range - excel

I am having an issue with runtime error 91, Object variable or With block variable not set. I am trying to write to a cell in a range. Below is my latest code, with various methods I have tried to write to it.
Using .Value didn't work, nor did .Cells(1, 1).Value, nor did Set .Cells(1, 1).Value. Not quite sure what I am missing here.
The value I am trying to write occasionally passes, it seems, but I would like to know exactly what I am doing wrong so I can prevent this from happening in the future.
Thanks,
Code in question, ElseIf is where it hangs up. The If may or may not have problems...
Private Sub IncrementSPN()
If Not tempSPNRange Is Nothing And Not isDuplicate Then
' Increment appropriate SPN family
tempSPNRange.Value = tempSPN + 1
ElseIf tempSPNRange Is Nothing And Not isDuplicate Then
' Don't increment anything, silly!
Set tempSPNRange.Cells(1, 1).Value = tempSPNRange.Cells(1, 1).Value + 1
End If
End Sub

If tempSPNRange has been Dim'ed as a Range, then within the ElseIf it needs to be Set to a group of cells within a worksheet and then values can be assigned to cells within the group.

Related

VBA - Excel - Finding the cell location of a userform TextBox populated by a for i loop?

What do I need to know?
How do I get the location of the data that a textbox is displaying? How do I know where it is?
What am I doing?
I have some code that loops through i and assigns it a value then pulls the cell value from a sheet based on i....so (i, 2) is simply: Row i from Column 2. This is then displayed in a userform Textbox.
What I want to do?
Add a dbl_click event, so that someone can double click on the textbox and be sent to the sheet/row/column that is being displayed. I have no issue creating the dbl_click event, but my problem appears to be how to get the cell location being displayed?
If it is relevant, this is my code for the loop:
Dim code as String
code = search.Value
For i = 2 To LastRow
If Sheet1.Cells(i, 9).Value = code Then
ssn1.Text = Sheet1.name
hb11.Text = Sheet1.Cells(i, 9).Value
End If
Next i
This is a snippet, as this goes on for awhile, hb11 runs though to hb37 - didn't see any reason to paste it all here.
The problem is, that the loop continues through, across multiple sheets as well, finding all examples of "code" so i keeps changing, after it has written the data to the TextBox - so I can't rely on (i, 9) from the loop.
I have gotten this far in terms of code:
Sub bt11_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
If hb11.Value <> ("") Then
Application.Goto Reference:=Sheet1.Range(hb11)
End If
End Sub
However this appears to be relying on the value of hb11, rather than the cell location.
I know this is a dumb question, I know, but I just can't seem to find the answer?
I get the feeling that it lies in:
Dim cell as Range
Then:
Set cell = hb11.something
But I have been through the list, cell/range gives a mismatch, and don't actually exist in the list. There is no 'linked cell' as I thought that might do it...
I am a bit lost.
Profit from using the .Tag property
I'm assuming each of your 27 textboxes refers to exactly one source range address which consists of sheetname, row and column (or column character).
If so you can profit from assigning a combined reference string (e.g. "Sheet22" & "," & i & "," & 9) to a textbox'es ►.Tag property during the initializing loop, e.g. in a comma separated way like perhaps
hb11.Tag = "Sheet22,17,9" ' << i.e. sheet name, row 17, column 9
I think it'll be easy to get all data from there:
Dim src: src = split(hb11,",")
Application.Goto Reference:= _
ThisWorkbook.Worksheets(src(0)).Range(Cells(Val(src(1)), Val(src(2))).Address), Scroll:=True
Too many hours later, I have worked this out.
Thanks to T.M. for the idea about re-writing the data out of a stored place.
Outside of any sub, I created a String - right at the top.
Dim ac1 As String
Inside my loop, I simply gave ac1 the value of i,
For i = 2 To LastRow
If Sheet1.Cells(i, 9).Value = code Then
ssn1.Text = Sheet1.name
hb11.Text = Sheet1.Cells(i, 9).Value
ac1 = i
End If
Next i
This works, because you only run through this loop, IF code exists, since the list is unique, code only exists once. So you only go into the loop once, and when you do, i = the row.
Then using T.M.'s idea, I wrote out:
Application.Goto Reference:=Sheet1.Range("A" & ac1)
This is a range reference that Goto can handle.
The advantage of this method is, because I am searching multiple sheets with multiple Textboxes, I only need ac1 for a whole sheets worth of Textboxes.
Hope this helps someone in the future.

Object Required or Object variable or With Block errors

I am trying to use VBA to combine data from several different look up ranges for an SQL script writer. At this stage I am trying to identify whether the value I am looking up has an adjacent cell with a specific value. I have tried several iterations. My most recent is the following:
Dim r As String
With Worksheets(12).Range("q2:R80")
r = Cells(.Find(u(0, 1).Row, 18)).Value
End With
I have tried with and without the "With" statement as well as with and without "." before the methods and properties and with and with out the ".Value" and no matter what combination I use, I get an object error of some kind or another. I know I am missing something obvious, but Google has been of no help.
Your parentheses look off:
With Worksheets(12).Range("q2:R80")
r = Cells(.Find(u(0, 1).Row, 18)).Value
End With
seems like it should be:
With Worksheets(12).Range("q2:R80")
r = Cells(.Find(u(0, 1)).Row, 18).Value
End With
But this is still problematic, becauses it assumes the Find succeeded by chaining the .Row call.
Better practice is the following:
With Worksheets(12).Range("q2:R80")
Dim foundRng as Range
Set foundRng = .Find(u(0,1)) '<~ you really should specify the other parameters of Range.Find
If Not foundRng Is Nothing Then
r = Cells(foundRng.Row, 18).Value '<~ make sure to qualify the worksheet the Cells are on
End If
End With

VBA how to change a range variable using something like offset

I'd think that the following code should produce a diagonal of numbers, and I am wondering why this code doesn't work as intended:
Sub RangeExample()
Dim a As Range
Set a = Sheets(1).Range("a1")
a.Value = 0
Dim i As Integer
For i = 1 To 100
a = a.Offset(1, 1)
a.Value = i
Next i
End Sub
I understand there are many ways of producing a diagonal of numbers, I'm not asking how to do that.
What I'm asking is how I would change my range variable a to become a different range, and do that iteratively. It seems to me that as a.offset(1,1) returns a range object that's one over and one down, I should be able to reassign a as this new range, assign a value, and move on.
Your current issue is that you're missing a Set:
Set a = a.Offset(1, 1)
Note that you could also just use i and not reSet:
a.Offset(i, i).Value = i
Another option is to use Cells, e.g.
Sheets(1).Cells(i + 1, i + 1).Value = i
There's more than one way to skin a cat - pick whatever is easiest and most intuitive to future you.
Thanks for the answer, I didn't know set was required in this case. The specific answer I was looking for I have now found at:
What does the keyword Set actually do in VBA?
Specifically, the following answer by LeppyR64. "Set is used for setting object references, as opposed to assigning a value."
I didn't know that equality alone only impacted the value of the range object a. To actually change the range a was referencing, I needed set because a is supposed to refer to a new range object.
the issue has already been addressed by #BigBen
but you could avoid re-setting the range at every iteration by means of With...End With block
Option Explicit
Sub RangeExample()
Dim i As Long
With Sheets(1).Range("a1") ' reference topleftmost cell
.Value = 0 ' write referenced cell value
For i = 1 To 100
.Offset(i, i).Value = i 'write referenced cell current offset value
Next
End With
End Sub

How to fix sudden Run-Time error '1004' on vba find function?

On part of code where I need to find in which row certain String appears code breaks throwing '1004' error. This started suddenly and originally code worked without issue.
Option explicit is on and all variables defined! zRow returns last row as it should, xSelectC is really string that needs to be searched in range.
I've tried approach with application.match - same error appears,
also, I've tried replacing with Range objects (Dim objRng as Range, Set objRng = ws3.Cells(1, "B")) but with no luck.
On the end, I've used For loop approach and it worked but as this is just part of much larger code and there is quite a number of parts that use this same approach I would like to avoid for loop and actually in general understand why suddenly this '1004' started to appear.
vRow = ws3.Range("B1:B" & zRow + 1).Find(What:=xSelectC, After:=ws3.Cells(1, "B"), SearchDirection:=xlNext).Row
Instead of (for example) returning number of row 1244, it is throwing '1004'.
The general approach you should take is to return the Find into a Range variable, test that variable for Not Nothing, and only then refer to its properties.
Something like
Dim rng as Range
Dim research as Range, rAfter As Range
' ...
Set rSearch = ws3.Range("B1:B" & zRow + 1)
Set rAfter=ws3.Cells(1, "B")
Set rng = rSearch.Find(What:=xSelectC, After:=rAfter, SearchDirection:=xlNext)
If rng is Nothing Then
' nothing found, what now?
Else
vRow = rng.Row
' rest of your code
End If
Note that you should explicitly set parameters LookIn, LookAt, SearchOrder, and MatchBy, as they are saved each time Find is called _ either by code or the user. Failure to set them can result in unexpected behaviour see here

Data from the active worksheet is being extracted when trying to reference a different worksheet

I am trying to retrieve data from another worksheet in my workbook, but when i execute the code, the cell references are working, but they are retrieving from the current worksheet, not the other one.
I have tried using the name of the worksheet, as well as "Sheet7" (as seen below), one just grabs the data from the active worksheet and the other produces a runtime error 9.
While found = False
If Worksheets("Sheet7").Range("B" + CStr(i)).Value = cmbSA.Value Then
numBuilt = Worksheets("Sheet7").Range("C" + CStr(i + 1)).Value
found = True
Else
i = i + 1
End If
Wend
I expect the if statement to be true when i = 4, but it is only true when i=10, which is the required value, only its from the active worksheet.
A loop is overkill here, and could cause issues. What if cmbSA.value is never found? Also, While...Wend is deprecated.
It sounds like all you need is Range.Find.
As an example:
Dim foundCell as Range
Set foundCell = Worksheets("Sheet7").Range("B:B").Find(What:=cmbSA.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not foundCell is Nothing Then
numBuilt = foundCell.Offset(1, 1).Value
End If
I know you've asked a VBA question and might want to do it in VBA for other reasons, but there is a fairly simple formula to get this with no code.
Use MATCH to find your value and OFFSET to get it. You can do this from another sheet. I won't explain further in case you specifically don't want to use formulae.

Resources