简体   繁体   English

Excel VBA中带有“ WITH”的类型不匹配错误

[英]Type Mismatch Error In Excel VBA With “WITH”

I am attempting to select a worksheet by name from an Add-In that is loaded in my workbook. 我正在尝试从工作簿中加载的加载项中通过名称选择工作表。 My code iterates up to the line of With worksheets(ws1) then it throws a 我的代码迭代到With worksheets(ws1)的行,然后抛出

Type mismatch error 类型不匹配错误

What would be the correct way to perform actions on that worksheet and use the with feature? 在该工作表上执行操作并使用with功能的正确方法是什么?

Dim ws2 As Worksheet, ws1 As Worksheet
Dim aData

Set ws2 = ActiveWorkbook.ActiveSheet
Set ws1 = ThisWorkbook.Worksheets("Tastatas")

With Worksheets(ws1)
aData = .Range("a1").CurrentRegion
End With
 With Worksheets(ws1) 

When you do Worksheets(ws1) , you're actually calling Application.Workbooks.Item (the default property of the Excel.Worksheets collection class . 当您执行Worksheets(ws1) ,实际上是在调用Application.Workbooks.ItemExcel.Worksheets 集合类的默认属性。

The Item property of a collection class is parameterized - it needs a key to retrieve an Object reference. 集合类的Item属性已参数化-它需要一个来检索Object引用。 So you need a key . 所以你需要一把钥匙

A VBA.Collection is keyed with a String . VBA.CollectionString键输入。 The Item property of the Excel.Worksheets collection class takes a Variant - this means at compile-time, anything you give it will work . Item的物业Excel.Worksheets集合类需要一个Variant -这意味着在编译时, 任何你给它会奏效 The problem happens at run-time, when the Variant value is used to retrieve the Object associated with the key you gave it. 当使用Variant值检索与您提供的相关联的Object时,会在运行时发生问题。

You can do Set ws1 = ThisWorkbook.Worksheets(1) with any Long (or Integer ) to retrieve the item by index . 您可以对任何Long (或Integer )执行Set ws1 = ThisWorkbook.Worksheets(1)以通过index检索项目。

You can do Set ws1 = ThisWorkbook.Worksheets("Sheet1") with any String to retrieve the item by name . 您可以对任何String进行Set ws1 = ThisWorkbook.Worksheets("Sheet1")来按名称检索项目。

And that's all. 就这样。 A string or a number. 字符串或数字。

Dim ws2 As Worksheet, ws1 As Worksheet

Beats my why you'd have ws2 before ws1 , but anyway ws1 is a Worksheet object reference, not a String , not a Long . 击败了我为什么在ws2之前有ws1 ,但无论如何ws1是一个Worksheet对象引用,不是String ,不是Long

So your code compiles because you're passing that reference to a Variant parameter, and blows up at run-time with a type mismatch error, because the type you supplied ( Worksheet ) mismatches the type that was expected (a String , or any integer numeric type). 所以您的代码会编译,因为您正在将该引用传递给Variant参数,并在运行时因类型不匹配错误而崩溃 ,因为您提供的类型( Worksheet )与预期的类型不匹配String或任何整数)数字类型)。


The With block could very well hold that reference for you - which spares you the variable declaration: With块可以很好地为您保存该引用-从而节省了变量声明:

With ThisWorkbook.Worksheets("Tastatas")
    aData = .Range("A1").Value
End With

Notice the explicit .Value in the right-hand side of the assignment: it's still there if you leave it out, only it's implicit . 请注意,赋值右侧的显式.Value :如果将其省略,它仍然存在,只有隐式 That's because the Range class has a default property that points to its Value , which is a Variant that can contain a string, a date, a number, an error value... reading the value into a Variant is a very good idea: it spares you from another type mismatch error if the cell you're reading contains a #REF! 这是因为Range类具有指向其Value默认属性 ,该属性是一个Variant ,可以包含字符串,日期,数字,错误值...将值读入Variant是一个好主意:如果您正在读取的单元格包含#REF!其他类型的不匹配错误#REF! or any other cell erorr value. 或任何其他单元格erorr值。

But because of the implicit default value, the only thing that can tell us whether aData is a value or a reference, is the assignment itself: 但是由于隐式默认值,唯一可以告诉我们aData是值还是引用的就是赋值本身:

[Let] aData = .Range("A1") ' value assignment: aData is the cell's value.
Set aData = .Range("A1")   ' reference assignment: aData is a Range object.

Things are clearer with explicit code: 使用显式代码可以使事情变得更清楚:

aData = .Range("A1").Value
Set aData = .Range("A1")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM