admin管理员组文章数量:1122832
I am completely new to VBA and have literally never done this before so this might be a stupid mistake. But unfortunately it seems so basic that no one has ever felt the need to explain it. I am trying to let the a variable, "row", equal the row value of a specific number being searched for in a given range of cells. I kept receiving the error "Run-time error '91': Object variable or With Block variable not set" and some people said it may be because the value I'm looking for isn't in that range.
So I wanted to check what values were in the range incase I had misreferenced or something, and so I wrote in the immediate window ?Range("B2:B30")
and it gives me the "Run-time error '13': Type Mismatch" error. I don't understand how this is possible because surely that's not even dependent on my code?
This is part of my code:
Sub CreateContract()
Dim wdApp As Word.Application
Set wdApp = CreateObject("Word.Application")
Dim ContractNumber As Double
Dim row As Double
Worksheets("Contract Creator").Select
ContractNumber = Range("O1").Value
row = Range("B2", Range("B2").End(xlDown)).Find(what:=ContractNumber, SearchOrder:=xlRows, SearchDirection:=xlPrevious).row
...
End Sub
I am completely new to VBA and have literally never done this before so this might be a stupid mistake. But unfortunately it seems so basic that no one has ever felt the need to explain it. I am trying to let the a variable, "row", equal the row value of a specific number being searched for in a given range of cells. I kept receiving the error "Run-time error '91': Object variable or With Block variable not set" and some people said it may be because the value I'm looking for isn't in that range.
So I wanted to check what values were in the range incase I had misreferenced or something, and so I wrote in the immediate window ?Range("B2:B30")
and it gives me the "Run-time error '13': Type Mismatch" error. I don't understand how this is possible because surely that's not even dependent on my code?
This is part of my code:
Sub CreateContract()
Dim wdApp As Word.Application
Set wdApp = CreateObject("Word.Application")
Dim ContractNumber As Double
Dim row As Double
Worksheets("Contract Creator").Select
ContractNumber = Range("O1").Value
row = Range("B2", Range("B2").End(xlDown)).Find(what:=ContractNumber, SearchOrder:=xlRows, SearchDirection:=xlPrevious).row
...
End Sub
Share
Improve this question
edited Nov 22, 2024 at 10:48
Darren Bartrup-Cook
19.6k2 gold badges26 silver badges48 bronze badges
asked Nov 22, 2024 at 10:47
saskiaclrsaskiaclr
11 silver badge2 bronze badges
1
- Avoid using VBA keywords as Variable names. "Row" is a property and when you assign it as variable, it can make your code confusing. Instead, use RW. – Frank Ball Commented Nov 22, 2024 at 21:10
3 Answers
Reset to default 1(1) You get a Type mismatch error for ? Range("B2:B30")
because you can only write one value at a time and Range("B2:B30")
returns (a 2-dimenional) array with 1x29 value. So nothing to worry about. Write for example ? Range("B2")
.
(2) Dont use Select
. Don't rely on the ActiveSheet. Write something like this:
With ThisWorkbook.Worksheets("Contract Creator")
row = .Range("B2", .Range("B2").End(xlDown)).Find(what:=ContractNumber, SearchOrder:=xlRows, SearchDirection:=xlPrevious).row
End With
Note the Dots before .Range
- that qualifies the Range - it tells VBA that you want to work with the object specified in the With
-statement (in your case the sheet "Contract Creator").
Obgligarory link: How to avoid using Select in Excel VBA
(3) Just to let you know: There are better ways to find the last cell of a range than to use End(xlDown)
. See Find last used cell in Excel VBA
(4) You get an "Object not Set" error when the Find
-command cannot find anything. Find
returns a Range if something is found, and using Range.Row
will give you the row number. However, if nothing is found, instead of a Range object you get Nothing
, and Nothing
has (of course) no Row property. Best is split such complex commands into pieces:
With ThisWorkbook.Worksheets("Contract Creator")
Dim ContractNumber As Variant
ContractNumber = .Range("O1").Value
Dim lastCell As Range, searchRange As Range, foundCell As Range
Set lastCell = .Range("B2").End(xlDown)
Set searchRange = .Range("B2", lastCell)
Set foundCell = searchRange.Find(what:=ContractNumber, SearchOrder:=xlRows, SearchDirection:=xlPrevious)
If foundCell Is Nothing Then
MsgBox "Contract Number not found"
Exit Sub
End If
row = foundCell.row
(...)
End With
(5) Don't use the data type Double
for a row number. Double
is a floating point value that should be used for calculations that don't result in integer values. Use Long
instead (forget about data type Integer
in VBA as it is obsolete). Same is true probably for the contract number.
?Range("B2:B30") returns an array.
To Debug.Print an array is not possible. You have to define which item of the range you want to get.
?Range("B2:B30")(1) returns B2
?Range("B2:B30")(1,2) returns C2 (!!!)
?Range("B2:B30")(29) returns B30
?Range("B2:B30")(30) returns B31
The same can be used with Cells
property
?Range("B2:B30").Cells(1)
?Range("B2:B30").Cells(1,2)
?Range("B2:B30")
refers to a range of cells, the immediate window won't return each value - it's not set up to know you want an array of values returned. ?Range("B2")
would work as it's only looking at a single cell.
Your posted code would work if the ContractNumber is in the range Range("B2", Range("B2").End(xlDown))
.
If it doesn't find the value it will return the error message you're getting - "Run-time error '91': Object variable or With Block variable not set"
I'd have a read of How to avoid using Select in Excel VBA and also With...End With Statement.
This is the verbose code I've explicitly stated the workbook and worksheet for each reference -
Public Sub CreateContract()
Dim ContractNumber As Double
ContractNumber = ThisWorkbook.Worksheets("Contract Creator").Range("O1").Value
'Note: Rather than `xlDown` the code starts at the bottom and uses `xlUp`.
'If your range only contained a value in cell B2 then `xlDown` would return the whole column from your start cell down.
Dim SearchRange As Range
Set SearchRange = ThisWorkbook.Worksheets("Contract Creator").Range("B2", ThisWorkbook.Worksheets("Contract Creator").Cells(Rows.Count, 2).End(xlUp))
Dim FoundRow As Range
Set FoundRow = SearchRange.Find(What:=ContractNumber, After:=SearchRange.Cells(1, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If Not FoundRow Is Nothing Then lRow = FoundRow.row
End Sub
Using With...End With it can be shortened to:
Public Sub CreateContract()
With ThisWorkbook.Worksheets("Contract Creator")
Dim ContractNumber As Double
ContractNumber = .Range("O1").Value
Dim SearchRange As Range
Set SearchRange = .Range("B2", .Cells(Rows.Count, 2).End(xlUp))
End With
Dim FoundRow As Range
Set FoundRow = SearchRange.Find(What:=ContractNumber, After:=SearchRange.Cells(1, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
Dim lRow As Long
If Not FoundRow Is Nothing Then lRow = FoundRow.row
If lRow = 0 Then
MsgBox "Value not found"
Else
MsgBox ContractNumber & " found on row " & lRow
End If
End Sub
Also worth having a read of:
Range.Find method and Worksheet.Cells property
本文标签: excelVBA is saying Type Mismatch when I try and check the value of a rangeStack Overflow
版权声明:本文标题:excel - VBA is saying Type Mismatch when I try and check the value of a range - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736304382a1932214.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论