在 Excel VBA 与 "WITH" 中键入不匹配错误
Type Mismatch Error In Excel VBA With "WITH"
我正在尝试 select 从我的工作簿中加载的加载项按名称创建工作表。我的代码迭代到 With worksheets(ws1)
行,然后抛出
Type mismatch error
对该工作表执行操作并使用 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)
当您执行 Worksheets(ws1)
时,您实际上是在调用 Application.Workbooks.Item
(Excel.Worksheets
集合 class 的默认 属性 .
集合 class 的 Item
属性 已参数化 - 它需要 key 来检索 Object
引用.所以你需要一个 key.
A VBA.Collection
键控为 String
。 Excel.Worksheets
集合 class 的 Item
属性 需要一个 Variant
- 这意味着在编译时, 你给它的任何东西都会起作用。问题发生在 运行 时间,当时 Variant
值用于检索与您提供的 key 关联的 Object
。
您可以对任何 Long
(或 Integer
)执行 Set ws1 = ThisWorkbook.Worksheets(1)
以通过 index.
检索项目
您可以对任何 String
执行 Set ws1 = ThisWorkbook.Worksheets("Sheet1")
以通过 name.
检索项目
仅此而已。字符串或数字。
Dim ws2 As Worksheet, ws1 As Worksheet
打败了我为什么你会在 ws1
之前有 ws2
,但无论如何 ws1
是一个 Worksheet
对象引用,而不是 String
,不是Long
.
所以您的代码可以编译,因为您将该引用传递给 Variant
参数,并在 运行 时因 类型不匹配 而爆炸错误,因为您提供的类型 (Worksheet
) 与预期的类型 不匹配(String
或任何整数类型)。
With
块可以很好地为您保留该引用 - 这使您无需变量声明:
With ThisWorkbook.Worksheets("Tastatas")
aData = .Range("A1").Value
End With
请注意作业右侧的显式 .Value
:如果您将其省略,它仍然存在,只是它是 隐式 。那是因为 Range
class 有一个 default 属性 指向它的 Value
,这是一个 Variant
可以包含一个字符串、一个日期、一个数字、一个错误值...将值读入 Variant
是一个很好的主意:它使您免于另一个 类型不匹配 如果您正在阅读的单元格包含 #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.
使用 显式 代码更清楚:
aData = .Range("A1").Value
Set aData = .Range("A1")
我正在尝试 select 从我的工作簿中加载的加载项按名称创建工作表。我的代码迭代到 With worksheets(ws1)
行,然后抛出
Type mismatch error
对该工作表执行操作并使用 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)
当您执行 Worksheets(ws1)
时,您实际上是在调用 Application.Workbooks.Item
(Excel.Worksheets
集合 class 的默认 属性 .
集合 class 的 Item
属性 已参数化 - 它需要 key 来检索 Object
引用.所以你需要一个 key.
A VBA.Collection
键控为 String
。 Excel.Worksheets
集合 class 的 Item
属性 需要一个 Variant
- 这意味着在编译时, 你给它的任何东西都会起作用。问题发生在 运行 时间,当时 Variant
值用于检索与您提供的 key 关联的 Object
。
您可以对任何 Long
(或 Integer
)执行 Set ws1 = ThisWorkbook.Worksheets(1)
以通过 index.
您可以对任何 String
执行 Set ws1 = ThisWorkbook.Worksheets("Sheet1")
以通过 name.
仅此而已。字符串或数字。
Dim ws2 As Worksheet, ws1 As Worksheet
打败了我为什么你会在 ws1
之前有 ws2
,但无论如何 ws1
是一个 Worksheet
对象引用,而不是 String
,不是Long
.
所以您的代码可以编译,因为您将该引用传递给 Variant
参数,并在 运行 时因 类型不匹配 而爆炸错误,因为您提供的类型 (Worksheet
) 与预期的类型 不匹配(String
或任何整数类型)。
With
块可以很好地为您保留该引用 - 这使您无需变量声明:
With ThisWorkbook.Worksheets("Tastatas")
aData = .Range("A1").Value
End With
请注意作业右侧的显式 .Value
:如果您将其省略,它仍然存在,只是它是 隐式 。那是因为 Range
class 有一个 default 属性 指向它的 Value
,这是一个 Variant
可以包含一个字符串、一个日期、一个数字、一个错误值...将值读入 Variant
是一个很好的主意:它使您免于另一个 类型不匹配 如果您正在阅读的单元格包含 #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.
使用 显式 代码更清楚:
aData = .Range("A1").Value
Set aData = .Range("A1")