使用"WITH"在Excel VBA中键入不匹配错误

Icy*_*rts 1 excel vba excel-vba excel-2013

我试图从我的工作簿中加载的加载项中按名称选择工作表.我的代码迭代到With worksheets(ws1)它然后抛出一行

键入不匹配错误

在该工作表上执行操作并使用该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
Run Code Online (Sandbox Code Playgroud)

Mat*_*don 5

With Worksheets(ws1)
Run Code Online (Sandbox Code Playgroud)

当你这样做时Worksheets(ws1),你实际上是在调用Application.Workbooks.Item(Excel.Worksheets 集合类的默认属性).

Item集合类的属性是参数化的 - 它需要一个来检索Object引用.所以你需要一把钥匙.

A VBA.Collection是键入的String.集合类的Item属性Excel.Worksheets需要一个Variant- 这意味着在编译时,你给它的任何东西都可以工作.问题发生在运行时,当该Variant值用于检索Object与您给出的密钥相关联的值时.

您可以Set ws1 = ThisWorkbook.Worksheets(1)使用任何Long(或Integer)按索引检索项目.

您可以Set ws1 = ThisWorkbook.Worksheets("Sheet1")使用any String来按名称检索项目.

就这样.字符串或数字.

Dim ws2 As Worksheet, ws1 As Worksheet

打败我ws2以前的原因ws1,但无论如何ws1是一个Worksheet对象参考,而不是一个String,而不是一个Long.

因此,您的代码编译是因为您将该引用传递给Variant参数,并在运行时因类型不匹配错误而爆炸,因为您提供的类型(Worksheet)与预期的类型不匹配(a String或任何整数数字类型) .


With块可以很好地保存该引用 - 这使您免受变量声明的影响:

With ThisWorkbook.Worksheets("Tastatas")
    aData = .Range("A1").Value
End With
Run Code Online (Sandbox Code Playgroud)

请注意.Value赋值右侧的显式:如果你将它遗漏,它仍然存在,只有它是隐含的.这是因为Range类有一个默认属性指向它Value,这是一个Variant可以包含字符串,日期,数字,错误值...读值成Variant是一个非常不错的主意:它不遗余力你从另一个如果您正在读取的单元格包含一个或任何其他单元格erorr值,则会出现类型不匹配错误#REF!.

但是由于隐含的默认值,唯一可以告诉我们的aData是值还是引用,是赋值本身:

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

使用显式代码可以更清楚:

aData = .Range("A1").Value
Set aData = .Range("A1")
Run Code Online (Sandbox Code Playgroud)