【问题标题】:Some doubts about Dim and Set Worksheet关于 Dim and Set Worksheet 的一些疑问
【发布时间】:2018-08-04 21:11:04
【问题描述】:

通常情况下,Dim 应该先完成,然后 Set 应该在 vba 代码中完成,如下面的代码。

Dim xWs1 As Worksheet
Dim xWs2 As Worksheet
.
.
.
Dim xWsN As Worksheet
Set xWs1 = Worksheets("A")
Set xWs2 = Worksheets("B")
.
.
.
Set xWsN = Worksheets("NNN")

如果我需要调暗和设置 5 个工作表,则需要 10 行代码。当我需要 Dim 和 Set 5 个以上的工作表时,似乎代码会太长。

我发现如果我只使用Set,vba代码也可以正常运行。我想问如果我不使用 Dim 会不会有什么问题?

Set xWs1 = Worksheets("A")
Set xWs2 = Worksheets("B")
.
.
.
Set xWsN = Worksheets("NNN")

谢谢!

【问题讨论】:

  • 你在隐式声明你的变量。它不会破坏您的代码,但如果您拼错变量或尝试使用错误的数据类型,那么它可能会成为调试的噩梦。
  • 您的代码在没有 Dim 的情况下工作,因为您没有 Option Explicit 。这不是好的做法,因为它会阻止检测到您的拼写错误。
  • 虽然这通常被认为是不好的做法并且会使调试更加困难,但您可以在同一行上进行多个声明 Dim ws As Worksheet, ws1 As Worksheet。
  • @Drager 我有答案吗! .....给我几分钟解释一下
  • 谢谢大家,你解决了我的疑惑。 @QHarr 感谢您的建议,我会在我的代码中尝试一下。

标签: excel vba


【解决方案1】:

如果不使用 dim 语句,变量会自动创建为 Variant 类型。

Variant 类型可以是整数、字符串、工作簿或任何其他类型的变量,它可以随着变量的变化而变化,有一次它可以是字符串,然后可以更改为工作簿.

使用昏暗

不使用 Dim

不使用Dim主要有两个问题,

  1. 变体类型使用更多的计算机内存,因此它会使您的代码变慢,尤其是在您使用循环时。
  2. 很难找到错误(在您的情况下,您可以将任何内容分配给变量 XWs1,例如数字、名称等,如果您使用 dim 可以避免这些错误)

【讨论】:

  • 谢谢。我忽略了内存问题,你澄清了我一些vba的基本概念。非常感谢!
【解决方案2】:

如何使用 92 个字符声明和设置 92 个对象:

如果您担心“占用空间”,并且假设您想将 5 个过程级变量 (w1..w5) 显式设置为 Set 到 5 个工作表 (Sht1..Sht5),您可以使用:

示例 #1:

DefObj W
Sub wSet1()
  Dim w1, w2, w3, w4, w5
  Set w1=[Sht1]:Set w2=[Sht2]:Set w3=[Sht3]:Set w4=[Sht4]:Set w5=[Sht5]
End Sub

...或者,更节省空间,例如,如果您在 92 个声明的变量中有 92 个工作表到 Set >?那么:

示例 #2:

DefObj W
Sub wSet2():Dim wks(1To 92),x:For x=1To 92:Set wks(x)=Sheets("Sht"&x):Next x:End Sub

(这是 92 个字符...不算换行符!)


说明:

在这两种缩短声明的方式之间,我们使用了六个快捷方式。以下是每一项的摘要,有关每一项的完整文档,请参见“更多信息”下的链接。

免责声明:我们不应该在编程中使用快捷方式的原因有很多。显而易见的一点是,您压缩的代码越多,阅读和理解就越困难(尤其是其他人),因此可能更难排除故障或扩展。

如果你不知道什么是“标准方法”,就不要先学捷径!在学习捷径之前先学习如何以“正确的方式”做事,无论它看起来多么吸引人。曾几何时,我认为缩进和注释等整洁,以及 full,适当的技术,并不重要。我错了;必须以艰难的方式学习。如果您正在阅读本文,那么您可能也必须通过艰苦的方式学习,但至少:

在您的 Stack Overflow 问题中发布示例代码时不要使用快捷方式。 (这不是 [MCVE]的方法!)你可能会被骂! ...并且可能有你的问题被否决或被忽略... 你被警告了!


DefObj (默认数据类型)

[Deftype statements][1] are a forgotten method of declaring default data types.  Normally, the default data type is [`Variant`][2], so this:

Dim myVariable as Variant

...等同于:

Dim myVariable 

...但是DefObj W 语句(在模块级别使用)说:

在此模块中声明的所有变量,以字母“W”开头的变量默认类型为Object(除非另有说明)。请注意,Deftypes 语句必须在模块级别使用(在您的第一个 Sub 之前)。

整个列表:(More Info)

DefBool DefByte DefCur DefDate DefDbl DefDec DefInt DefLng DefSng DefStr DefObj DefVar


, (“Dim”语句中的逗号)

使用Dim 声明变量时,可以在同一行列出多个变量,用逗号分隔。因此:

Sub mySub()
    Dim myVariable1 as Currency  
    Dim myVariable2 as Currency  
    …

...与此相同:(结合示例与 Deftypes

DefCur m
Sub mySub()
    Dim myVariable1, myVariable1 
    …

Sheets ('Sheets' 集合)

  • WorkSheets 对象 是指指定或活动工作簿中所有工作表 对象 的集合。

  • Charts Object`指的是指定或活动工作簿中的**所有图表对象的集合。

    • 但是 **Sheets Objectrefers to ***both*** theWorksheets*and*Charts` 集合。

所以,如果一个工作簿有 3 个工作表和 2 个图表表,在 VBA 中:

  • Sheets.Count 将返回 5

  • Worksheets.Count 将返回 3

警告:如果您有同名的图表和工作表,使用Sheets 可能会导致冲突(在引用其他文件中的工作表时也应避免使用)。但是对于一个简单的单文件、仅工作表的工作簿,为自己节省一些 Work 并坚持使用 Sheets


[ ] (方括号参考快捷方式)

[方括号]可用作引用工作表单元格范围 个人的快捷方式细胞。您可以使用A1 参考样式 或括号内的命名范围 作为 Range 属性的快捷方式。您不必键入“范围”一词或使用引号。

Worksheets("Sheet1").[A1:B5].ClearContents 

[MyRange].Value = 30 

这几乎不是documented,而且记录较少的事实是,如果按逻辑顺序使用,方括号可以用来指代工作表。

结合示例,所有这些语句都会有相同的结果

Worksheets("Sheet1").Range("A1") = Now()
Sheets("Sheet1").Range("A1") = Now()
Worksheets("Sheet1").[A1] = Now()
Sheets("Sheet1").[A1] = Now()
[Sheet1].[A1] = Now()

wks() (变量数组)

如果您要声明大量相似的对象,将它们组合成一个数组通常更容易(也更有条理)。数组可以声明为任何类型,例如,Object、Worksheet。 (...甚至是很少使用和奇怪的类型,如LongLongIConverterApplicationPreferences。(显然,谁想到了那个人并不关心捷径。)


For..Set..Next (循环设置变量数组)

当使用对象数组(任何任何变量集)时,下一个合乎逻辑的步骤是减少需要对整个对象组执行的任何任务的代码。


其他说明:

示例 #1 可以压缩为一行,但我希望它在答案中易于阅读。如果我们的工作表名称是 S1..S5 而不是 oh-so-longy Sht1..Sht5and 我们使用 :,我们可以用 105 个字符完成同样的事情:

示例 #1b:

DefObj W
Sub wSet():Dim w1,w2,w3,w4,w5:Set w1=[S1]:Set w2=[S2]:Set w3=[S3]:Set w4=[S4]:Set w5=[S5]:End Sub

数据类型快捷方式符号

另一组很少使用的可追溯到 1974 年:Gary Kildall 为 CP/M 操作系统选择的数据类型快捷方式

Symbol  Data Type  Constant                                                            

%       Integer    vbInteger = 2
$       String     vbString = 8
&       Long       vbLong = 3
@       Decimal    vbDecimal = 6
!       Single     vbSingle = 4
#       Double     vbDouble = 5

许多编码语言至今仍受支持,例如,您可以互换使用这些语言:

Dim myVariable as String
Dim myVariable$

更多信息:

【讨论】:

  • 哦,很详细的解释。非常感谢。我只是有一个问题,您在代码中使用 Dim ... As Variant。它不使用 Dim ... As Worksheet 更好地分配内存吗?另外,谢谢你教了我没学过的DefObj。我想我知道您所说的其他内容,例如 [Sht1](评估)、wks()(数组)、For..Set..Next(For 循环)和 Sheets(对象)。
  • @ashleedawg,您写了 “如果您有同名的图表和工作表”。但这真的可能吗?我现在没有通过任何 PC 对其进行测试,但我似乎记得这是不可能的。
【解决方案3】:

以下面的例子说明为什么使用隐式变量声明通常是个坏主意:

Sub Test()

    myVariable = 10

    myOutcome = myVaraible + 5

End Test

myOutcome = 5。你知道为什么吗?

我在第二行拼错了myVariable,所以我只是创建了一个全新的变量myVaraible(默认值为0)。

这就是为什么你应该总是在每个模块的开头使用Option Explicit;以及为什么要始终显式声明所有变量。

虽然它仍然有效,但您只是在为不必要的调试头痛做好准备。


如果你的问题是你想压缩你的代码以使用更少的行,你可以这样做:

Option Explicit

Sub Test()

    Dim myVariable As Long:    myVariable = 10
    Dim myOutput As Long
    myOutput = myVariable + 5

End Sub

你也可以在同一行声明多个变量:

Option Explicit

Sub Test()

    Dim myVariable As Long, myOutput As Long
    myVariable = 10
    myOutput = myVariable + 5

End Sub

不一定推荐这样做(因为它会降低可读性),但它是另一种声明变量的方法。这确实需要相同的数据类型,但您可以将工作表添加到数组中(来自您的示例):

Option Explicit

Sub Test()

    Dim xWs(1 To 5) As Worksheet

    Set xWs(1) = Worksheets("A")
    Set xWs(2) = Worksheets("B")
    Set xWs(3) = Worksheets("C")
    Set xWs(4) = Worksheets("D")
    Set xWs(5) = Worksheets("E")

End Sub

【讨论】:

  • 这我知道,但如果我只使用 Set 例如设置 xWs = Worksheets("A"),设置 xWs2 = Worksheets("B") xWs.cells(1,1).value = xWs2.cells(1,1).value。没有发生错误,代码运行正常。所以我怀疑 Set 工作表不能使用 Dim?
  • @Drager 这就是我要说的。您确实不必使用Dim(声明您的变量)。但是这样做,您将面临拼写错误的风险。这就是Dim 存在的全部原因,只是为了防止意外使用xWss1 而不是xWs1,因为Excel 会通知您在使用Option Explicit 时没有声明变量。它还可以防止您尝试使用错误的数据类型然后声明。
  • 简而言之,Dim 是作为“安全功能”而不是要求。
  • 哦,谢谢。最初,我只想使用 Set 来缩短代码行。阅读您的评论后,使用 Option Explicit 时仅使用 Set 无法运行。似乎使用 Dim 可以更安全地防止错误。
  • Dim 还可以确保您声明一个 tyoe,以便为要使用的对象提供正确的内存分配。
猜你喜欢
  • 2012-04-02
  • 1970-01-01
  • 2020-08-07
  • 2012-12-01
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多