“As Dictionary”和“As Scripting.Dictionary”是否相同(对于VBA早期绑定)?

时间:2022-05-11 14:51:51

When creating a dictionary object using early binding and the Microsoft Scripting Runtime Library, it looks like there are 2 equivalent type names for the same thing:

使用早期绑定和Microsoft Scripting Runtime Library创建字典对象时,看起来有两个相同的类型名称用于同一事物:

Dim dict as Dictionary
Set dict = New Dictionary

and

Dim dict as Scripting.Dictionary
Set dict = new Scripting.Dictionary

appear to do the same thing (at least so far).

似乎做同样的事情(至少到目前为止)。

I see the As Scripting.Dictionary syntax used by this resource, and I see the As Dictionary syntax used by this (really great) resource, but I haven't seen a comparison anywhere. And the MSDN documentation on dictionaries is either a literal joke, or not explicitly related to VBA.

我看到了这个资源使用的As Scripting.Dictionary语法,我看到了这个(非常好的)资源使用的As Dictionary语法,但我没有看到任何地方的比较。关于字典的MSDN文档要么是文字笑话,要么与VBA没有明确相关。

I don't see why I should be doing extra typing just to make my function declarations more crowded if I can just use As Dictionary, but I have learned that some things in VBA that look like they are equivalent can actually have subtle but significant differences (Application.InputBox vs. InputBox for example).

我不明白为什么我应该做额外的打字只是为了让我的函数声明更加拥挤,如果我可以使用As Dictionary,但我已经了解到VBA中看起来像是等价的一些东西实际上可以有微妙但显着的差异(例如,Application.InputBox与InputBox)。

Is there is really no difference between these, or are there subtle differences that I should be aware of?

这些之间真的没有区别,或者我应该注意哪些细微差别?

2 个解决方案

#1


8  

I don't see why I should be doing extra typing just to make my function declarations more crowded [...]

我不明白为什么我应该做额外的打字只是为了让我的函数声明更加拥挤[...]

It's called full-qualifying a type.

它被称为完全限定类型。

When you do this:

当你这样做:

Dim foo As Range

The type Range gets resolved in a very specific order, determined by the priority order, in the references dialog:

Range类型以特定顺序解析,由优先级顺序决定,在引用对话框中:

“As Dictionary”和“As Scripting.Dictionary”是否相同(对于VBA早期绑定)?

If the top-most type library that exposes a Range type is the Excel type library, then Range stands for Excel.Range.

如果公开Range类型的最顶层类型库是Excel类型库,则Range表示Excel.Range。

If you meant that to be Word.Range, then you have a bug, and fully-qualifying your declared types avoids these bugs.

如果你的意思是Word.Range,那么你有一个bug,并且完全限定你声明的类型可以避免这些错误。

The Scripting library exposes a Dictionary class. So when you reference the Scripting type library and do this:

Scripting库公开了一个Dictionary类。因此,当您引用Scripting类型库并执行此操作时:

Dim foo As Dictionary

You have all rights to expect that type to resolve to Scripting.Dictionary. But then if you add a class module and name it Dictionary, suddenly all these unqualified declarations are now referring to this custom class, because VBA type resolution will always prioritize types defined in the current project before looking at external references.

您有权期望该类型解析为Scripting.Dictionary。但是,如果添加一个类模块并将其命名为Dictionary,突然所有这些非限定声明现在都引用此自定义类,因为在查看外部引用之前,VBA类型解析将始终优先考虑当前项目中定义的类型。

Sure you can call it "extra typing". Just know that there are pros and cons to both approaches.

当然你可以称之为“额外打字”。只要知道这两种方法都有利有弊。

  • Fully-qualifying types avoids ambiguity when referencing type libraries that expose same-name classes: it enhances readability.
  • 完全限定类型在引用暴露同名类的类型库时避免了歧义:它增强了可读性。

  • Not qualifying types makes it easier to swap a class for another, e.g. replacing Scripting.Dictionary with a portable Dictionary implementation that works on a Mac.
  • 不符合条件的类型可以更容易地将一个类交换为另一个类,例如用可在Mac上运行的可移植的Dictionary实现替换Scripting.Dictionary。

Rule of thumb, programming isn't about writing code. It's about reading code. Write code that's easy to read, not code that's quick to write.

经验法则,编程不是关于编写代码。这是关于阅读代码。编写易于阅读的代码,而不是快速编写的代码。

#2


4  

As @braX said in your specific use case (early binding) it's the same thing and thus the Scripting. can be left off.

正如@braX在您的特定用例(早期绑定)中所述,它是相同的,因此是脚本。可以不用了。

However, there are cases where it may be helpful (or even needed). For example, if you were manipulating Excel in another Office app, you would (using early binding) write

但是,有些情况可能会有所帮助(甚至需要)。例如,如果您在另一个Office应用程序中操作Excel,则会(使用早期绑定)写入

Dim XL as Excel.Application

because you need to tell VBA which application, specifically, to use.

因为你需要告诉VBA具体使用哪个应用程序。

But you could go on to write

但你可以继续写下来

Dim myWB as Workbook

and VBA will know it's excel work. However, it may be more user-friendly to write

而且VBA会知道它的优秀工作。但是,编写它可能更加用户友好

Dim myWB as Excel.Workbook

That way it's totally clear what is going on.

这样就可以完全清楚发生了什么。

Now, in the case of a workbook, to most programmers, it's already clear, and that's fine, but what if you are in programming in Word and want to manipulate a Range object in Excel. Writing

现在,对于大多数程序员而言,对于大多数程序员来说,它已经很清楚了,这很好,但是如果你在Word中进行编程并想在Excel中操作Range对象会怎样。写作

Dim myRange as Range

may not work as you think it will because VBA will resolve it as a Word Range Object (since you are writing in Word - see MatMug's answer for better explanation), which will then lead to errors further down the code line when you refer to myRange.Offset(1), for example, because there is no Offset method of Word Range Object. So in this case, it's both necessary and user-friendly.

可能无法正常工作,因为VBA会将其解析为Word范围对象(因为您在Word中编写 - 请参阅MatMug的答案以获得更好的解释),当您引用myRange时,这将导致代码行中的错误进一步发生.Offset(1),例如,因为没有Word范围对象的偏移方法。所以在这种情况下,它既有必要又方便用户使用。

#1


8  

I don't see why I should be doing extra typing just to make my function declarations more crowded [...]

我不明白为什么我应该做额外的打字只是为了让我的函数声明更加拥挤[...]

It's called full-qualifying a type.

它被称为完全限定类型。

When you do this:

当你这样做:

Dim foo As Range

The type Range gets resolved in a very specific order, determined by the priority order, in the references dialog:

Range类型以特定顺序解析,由优先级顺序决定,在引用对话框中:

“As Dictionary”和“As Scripting.Dictionary”是否相同(对于VBA早期绑定)?

If the top-most type library that exposes a Range type is the Excel type library, then Range stands for Excel.Range.

如果公开Range类型的最顶层类型库是Excel类型库,则Range表示Excel.Range。

If you meant that to be Word.Range, then you have a bug, and fully-qualifying your declared types avoids these bugs.

如果你的意思是Word.Range,那么你有一个bug,并且完全限定你声明的类型可以避免这些错误。

The Scripting library exposes a Dictionary class. So when you reference the Scripting type library and do this:

Scripting库公开了一个Dictionary类。因此,当您引用Scripting类型库并执行此操作时:

Dim foo As Dictionary

You have all rights to expect that type to resolve to Scripting.Dictionary. But then if you add a class module and name it Dictionary, suddenly all these unqualified declarations are now referring to this custom class, because VBA type resolution will always prioritize types defined in the current project before looking at external references.

您有权期望该类型解析为Scripting.Dictionary。但是,如果添加一个类模块并将其命名为Dictionary,突然所有这些非限定声明现在都引用此自定义类,因为在查看外部引用之前,VBA类型解析将始终优先考虑当前项目中定义的类型。

Sure you can call it "extra typing". Just know that there are pros and cons to both approaches.

当然你可以称之为“额外打字”。只要知道这两种方法都有利有弊。

  • Fully-qualifying types avoids ambiguity when referencing type libraries that expose same-name classes: it enhances readability.
  • 完全限定类型在引用暴露同名类的类型库时避免了歧义:它增强了可读性。

  • Not qualifying types makes it easier to swap a class for another, e.g. replacing Scripting.Dictionary with a portable Dictionary implementation that works on a Mac.
  • 不符合条件的类型可以更容易地将一个类交换为另一个类,例如用可在Mac上运行的可移植的Dictionary实现替换Scripting.Dictionary。

Rule of thumb, programming isn't about writing code. It's about reading code. Write code that's easy to read, not code that's quick to write.

经验法则,编程不是关于编写代码。这是关于阅读代码。编写易于阅读的代码,而不是快速编写的代码。

#2


4  

As @braX said in your specific use case (early binding) it's the same thing and thus the Scripting. can be left off.

正如@braX在您的特定用例(早期绑定)中所述,它是相同的,因此是脚本。可以不用了。

However, there are cases where it may be helpful (or even needed). For example, if you were manipulating Excel in another Office app, you would (using early binding) write

但是,有些情况可能会有所帮助(甚至需要)。例如,如果您在另一个Office应用程序中操作Excel,则会(使用早期绑定)写入

Dim XL as Excel.Application

because you need to tell VBA which application, specifically, to use.

因为你需要告诉VBA具体使用哪个应用程序。

But you could go on to write

但你可以继续写下来

Dim myWB as Workbook

and VBA will know it's excel work. However, it may be more user-friendly to write

而且VBA会知道它的优秀工作。但是,编写它可能更加用户友好

Dim myWB as Excel.Workbook

That way it's totally clear what is going on.

这样就可以完全清楚发生了什么。

Now, in the case of a workbook, to most programmers, it's already clear, and that's fine, but what if you are in programming in Word and want to manipulate a Range object in Excel. Writing

现在,对于大多数程序员而言,对于大多数程序员来说,它已经很清楚了,这很好,但是如果你在Word中进行编程并想在Excel中操作Range对象会怎样。写作

Dim myRange as Range

may not work as you think it will because VBA will resolve it as a Word Range Object (since you are writing in Word - see MatMug's answer for better explanation), which will then lead to errors further down the code line when you refer to myRange.Offset(1), for example, because there is no Offset method of Word Range Object. So in this case, it's both necessary and user-friendly.

可能无法正常工作,因为VBA会将其解析为Word范围对象(因为您在Word中编写 - 请参阅MatMug的答案以获得更好的解释),当您引用myRange时,这将导致代码行中的错误进一步发生.Offset(1),例如,因为没有Word范围对象的偏移方法。所以在这种情况下,它既有必要又方便用户使用。