声明变量Workbook/Worksheet VBA

25

我知道这可能是一个琐碎的问题,但我似乎无法在 VBA 中将 workbookworksheet 声明为变量。我有以下代码,但我无法弄清楚我做错了什么,应该很简单。通常我没有任何问题声明变量,如Dim i As Integer等。

sub kl() 

    Dim wb As Workbook
    Dim ws As Worksheet

    Set wb = ActiveWorkbook
    Set ws = Sheet("name")

    wb.ws.Select

End Sub
当我运行以上代码时,我收到一个 type missmatch 错误。

2
你收到了什么错误信息? - Oscar
这是用于Excel的VBA吗? - Bathsheba
1
请查看此链接:http://www.techrepublic.com/blog/10-things/10-ways-to-reference-excel-workbooks-and-sheets-using-vba/ - Oscar
1
除了“Sheets”问题之外,您的ws变量是一个变量,而不是工作簿的属性,因此它只是ws.select而不是wb.ws.select。另外请注意,在VBA中很少需要选择任何内容。 - Rory
1
我收到的错误是“类型不匹配”。 - Mads Østrup Christensen
9个回答

24

使用工作表(Sheets)而不是工作簿(Sheet),并按顺序激活它们:

Sub kl()
    Dim wb As Workbook
    Dim ws As Worksheet
    Set wb = ActiveWorkbook
    Set ws = Sheets("Sheet1")
    wb.Activate
    ws.Select
End Sub

3
这是正确的。但是 wb.activate 可能是多余的。如果在两行之前,wb 已经被分配为 activeworkbook,那么它已经被激活了。 - JNevill
4
@JNevill 好观点 我使用了两个语句,以防用户想要将Set指向其他工作簿。 - Gary's Student
3
请注意,Sheets 集合包含 Worksheet 对象,还包括 Chart 和一堆遗留的工作表类型。如果要检索实际的 Worksheet 对象,请使用 Worksheets 集合。 - Mathieu Guindon
1
通常情况下,但是“Name”也有可能被用户修改,从而破坏所有硬编码的VBA代码;-) - Mathieu Guindon
1
我已经发布了一个答案 =) 你可以通过保护工作簿结构来防止用户搞乱工作表名称/索引 =) - Mathieu Guindon
显示剩余3条评论

16

如果你想检索的工作表在编译时存在于ThisWorkbook中(即包含你正在查看的VBA代码的工作簿),那么最简单和最可靠的引用该Worksheet对象的方法是使用其代码名称

Debug.Print Sheet1.Range("A1").Value

您可以将代号设置为任何您需要的名称(只要它是有效的VBA标识符),而与其“选项卡名称”(用户随时可以修改)无关,方法是在属性工具窗口(F4)中更改(Name)属性:

Sheet1 properties

Name属性是指用户可以随意更改的“选项卡名称”;(Name)属性是指工作表的代号,用户无法在不访问Visual Basic Editor的情况下更改它。

VBA使用此代号来自动声明全局范围的Worksheet对象变量,以便您的代码可以在任何地方免费使用该变量来引用该工作表。

换句话说,如果该工作表在编译时存在于ThisWorkbook中,则永远不需要为其声明变量-变量已经存在!


如果工作表是在运行时创建的(无论是否在ThisWorkbook内部),那么然后您需要为其声明和分配Worksheet变量。

使用Workbook对象的Worksheets属性检索它:

Dim wb As Workbook
Set wb = Application.Workbooks.Open(path)

Dim ws As Worksheet
Set ws = wb.Worksheets(nameOrIndex)

重要提示...

  • 用户可以轻松地修改工作表的名称和索引(无论是不是故意的),除非工作簿结构受到保护。 如果工作簿未受保护,则您不能仅凭名称或索引就确定所需的工作表 - 最好验证工作表的格式(例如,验证A1单元格中是否包含某些特定文本,或者有一个名为特定名称并包含某些特定列标题的表)。

  • 使用 Sheets 集合包含 Worksheet 对象,但也可能包含 Chart 实例和另外六个旧版工作表类型,这些类型不是工作表。 从 Sheets(nameOrIndex) 返回的任何内容中分配 Worksheet 引用会因此导致运行时类型不匹配错误。

  • 限定 Worksheets 集合将引用隐式活动工作簿 - 这意味着 Worksheets 集合正在从当前执行指令的任何工作簿中检索数据。 这样的隐式引用使代码脆弱且容易出错,特别是如果用户可以在代码运行时导航和与Excel UI交互。

  • 除非您需要激活特定工作表,否则您永远不需要调用 ws.Activate 以执行与工作表的大多数操作。 只需使用您的 ws 变量即可。


2
第三种解决方案: 我会将ws设置为工作簿wb的一个工作表,因为使用Sheet("name")总是指向活动工作簿,而随着代码的发展,这可能会改变。
sub kl() 

    Dim wb As Workbook
    Dim ws As Worksheet

    Set wb = ActiveWorkbook
    'be aware as this might produce an error, if Shet "name" does not exist
    Set ws = wb.Sheets("name")
    ' if wb is other than the active workbook
    wb.activate
    ws.Select

End Sub

2

我刚遇到了同样的问题。

你需要声明wsObject类型。

另外,它应该是这样的:

Set ws = wb.Sheets("Sheet1")

不应该是:

Set ws = Sheet("Sheet1")

以下代码对我有效。
sub kl()

Dim wb As Workbook
Dim ws As Object

Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")

MsgBox ws.Name

End Sub

0

让你惊讶的是,在Excel 2007或更高版本中,你确实需要声明工作簿和工作表变量。只需添加单行表达式即可。

Sub kl()

    Set ws = ThisWorkbook.Sheets("name")
    ws.select
End Sub

抛开其他,享受编程的乐趣。 但是为什么要选择一个工作表呢?选择工作表已经过时了,现在可以通过添加公式来进行计算和操作。

Sub kl()

    Set ws = ThisWorkbook.Sheets("name")
    ws.range("cell reference").formula = "your formula"
'OR in case you are using copy paste formula, just use 'insert or formula method instead of ActiveSheet.paste e.g.:
   ws.range("your cell").formula
'or
   ws.colums("your col: one col e.g. "A:A").insert
'if you need to clear the previous value, just add the following above insert line
   ws.columns("your column").delete

End Sub

0

尝试更改变量的名称,有时它会与其他模块/子程序冲突

 Dim Workbk As Workbook
 Dim Worksh As Worksheet

但同时也要尝试

 Set ws = wb.Sheets("name")

我记不清它是否适用于Sheet


嗨,我已经尝试过这个(请参见上面的评论),但这也不起作用。这可能与我的设置有关吗? - Mads Østrup Christensen

-1
Dim ws as Object

Set ws = Worksheets("name")

在声明工作表时将其声明为“工作表”,而不是一个对象,我在这个工作表中使用 OptionButtons(Active X)时遇到了问题(我想任何 Active-X 元素都会有相同的问题)。当声明为对象时,一切正常。

-1
我曾经遇到过同样的问题。我使用了Worksheet而不是Worksheets,问题得到了解决。不确定它们之间的区别是什么。

1
“Worksheet”是一种类型 - 一个类名。“Worksheets”是隐藏的“_Globals”模块的属性,它隐式地引用了活动工作簿的“Worksheets”集合。 - Mathieu Guindon

-2

以上有很多答案!这是我的看法:

Sub kl()

    Dim wb As Workbook
    Dim ws As Worksheet

    Set ws = Sheets("name")
    Set wb = ThisWorkbook

With ws
    .Select
End With

End Sub

你的第一个(可能是无意中的)错误,正如我们所提到的,是“Sheet”... 应该是“Sheets”

使用 with 块很有用,因为如果你将 wb 设置为当前工作簿以外的任何内容,它都会正确执行


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接