VBA:如何使用对象浏览器? [英] VBA: How to use the Object Browser?
问题描述
我不知道这是否是我提出问题的正确地方,但是:如何使用对象和浏览器?在帮助自己方面,我感到无能为力.我知道我可以使用Google的东西(而且可以做很多事情),但是我希望能够使用手头的所有资源.
I don't know if this is the right place for my question, but: how do I use the object and the browser? I feel so inept when it comes to helping myself. I know I can google stuff (and I do, a lot), but I want to be able to use all resources at hand.
让我们以图表的边框为准. Google再次帮助我,并告诉我可以这样更改它:
Let's take the border of a chart. Google helped me out once again and told me I can change it like this:
Sheets("Sheet1").ChartObjects(1).Chart.ChartArea.Border.LineStyle = xlContinuous
但是如何使用对象浏览器解决这个问题?假设我输入图表".我得到了很长的清单,经过这之后,可能不是我想出的那样,因为我必须知道我在寻找ChartArea
.仍然有一个问题:
But how do I figure this out with the object browser? Let's say I type in "chart". I get a long list and after going through this, it's probably not how I figure it out because I'd have to know that I'm looking for ChartArea
. Still, one question:
-
我找到了ChartArea,该条目的库为Excel,类为Chart,成员为空-成员为空是否告诉我一些东西,这是我应该寻找的东西吗?
I found ChartArea for an entry where the Library is Excel, Class is Chart and Member is empty - does member being empty tell me something, is this something I should look for?
无论如何,我继续输入"border".我本来希望在类"中找到一些与图表有关的东西.但是我没有.那么我应该怎么知道如何找到想要的东西呢?
Anyway, moving on, I type in "border". I would've expected to find something in "class" that has something to do with chart. But I don't. So how am I supposed to know how to find what I'm looking for?
在我讨论的同时,让我问一下有关Microsoft的帮助.我用Google搜索了 Border.LineStyle属性.显然,有一个代码示例告诉我有关如何将其与Charts().ChartArea一起使用的方法,但是我又可以更系统地进行此操作吗?在左侧,您可以看到LineStyle是Border的属性.从那里,我如何上移一个级别?我如何看到Border是ChartArea的财产,或者可以是ChartArea的财产?
And while I'm at it, let me ask about the Microsoft help. I googled my way to the Border.LineStyle property. Obviously there's the code example that tells me about using it with Charts().ChartArea, but again, can I do this more methodically? On the left hand side, you can see LineStyle is a property of Border. From there, how do I move up one level? How do I see that Border is/can be a property of ChartArea?
推荐答案
TL; DR:
ChartArea.Border
属性是隐藏的,您需要在对象浏览器"中打开显示隐藏的成员"才能看到它.
TL;DR:
The ChartArea.Border
property is hidden, you need to toggle "show hidden members" on in the Object Browser to see it.
下面基本上是关于对象浏览器的所有知识.
Below is essentially everything there is to know about the Object Browser.
顶部看起来像这样:
该下拉列表包含所有引用的类型库,这些名称库通过其程序名称进行标识:
That dropdown contains all referenced type libraries, identified by their programmatic name:
-
Excel
:Excel类型库,定义诸如Worksheet
,Range
等的内容. -
Office
:Excel类型库的依赖项;定义诸如CommandBars
之类的东西. -
stdole
:另一个依赖项;定义了诸如StdFont
和StdPicture
之类的较低层次的东西. -
VBA
:VBA标准库,定义了MsgBox
,Collection
等之类的内容. -
VBAProject
:已编译的VBA项目的类型库.
Excel
: the Excel type library, defines things likeWorksheet
,Range
, etc.Office
: a dependency of the Excel type library; defines things likeCommandBars
.stdole
: another dependency; defines lower-level things likeStdFont
andStdPicture
.VBA
: the VBA standard library, defines things likeMsgBox
,Collection
, etc.VBAProject
: the type library of your compiled VBA project.
您将要使用该下拉列表将您要查看的内容限制为要浏览的特定类型库-例如,Excel
.在下拉菜单下,有一个搜索框,可用于搜索出现在标识符一部分中的字符串并填充搜索结果"视图-但您已经知道了.
You'll want to use that dropdown to limit what you're looking at to the specific type library you're exploring - for example, Excel
. Under the dropdown, there's a search box you can use to search for strings that appear in part of an identifier and populate the "search results" view - but you know that already.
右键单击工具栏中的空白区域;选择显示隐藏的成员"-现在对象浏览器和InteliSense 将列出否则隐藏的成员,您将很快发现Excel类型库比看起来大得多.
Right-click an empty area in the toolbar; select "Show hidden members" - now the object browser and InteliSense will be listing members that are otherwise hidden, and you'll quickly discover that the Excel type library is much larger than it seems.
导航到您的VBAProject
库,并在左窗格中找到您的模块之一;右窗格将列出该模块的成员.右键单击该模块或其成员之一,然后选择属性"-弹出成员选项"对话框,让您输入描述:
Navigate to your VBAProject
library, and find one of your modules in the left pane; the right pane will be listing the members of that module. Right-click either the module or one of its members, and select "Properties" - the "Member Options" dialog pops up and lets you enter a description:
当模块和成员描述存在时,它们将显示在底部窗格中:
Module and member descriptions show up in the bottom pane when they exist:
如果您导出了该模块,则会看到它现在具有一个隐藏的VB_Description
属性,该属性的字符串值与您为描述输入的内容相匹配.
If you exported that module, you would see that it now has a hidden VB_Description
attribute with a string value that matches what you entered for a description.
如果您使用的是橡胶,则可以使用特殊注释(注释")来也可以控制这些隐藏的属性:
If you're using Rubberduck, you can use special comments ("annotations") to control these hidden attributes, too:
'@ModuleDescription("This module contains some boring recorded macros.")
Option Explicit
'@Description("Does something...")
Public Sub Macro1()
'...
End Sub
Rubberduck注释还可以控制/同步其他隐藏属性, 对象浏览器没有公开,但我离题了.
Rubberduck annotations can also control/synchronize other hidden attributes that the Object Browser isn't exposing, but I digress.
左窗格(类")显示所选库中的所有类型;右窗格列出了按类型(属性,方法,事件等)分组的所选类型的成员;您必须牢记的是,无论有多少个成员的名称与类型/类/接口的名称相同,一个成员就是一个成员,而不是一个类型.
The left pane ("classes") displays all the types in the selected library; the right pane lists the members of the selected type, grouped by kind (properties, methods, events, etc.); what you must keep in mind, is that no matter how many members are named the same as types/classes/interfaces, a member is a member, not a type.
使用此表达式:
Sheets("Sheet1").ChartObjects(1).Chart.ChartArea.Border.LineStyle = xlContinuous
我们可以从查找Sheets
成员调用所属的对象类型开始.如果我们过滤Excel
库并搜索Sheets
,则会发现2个有趣的结果,其中成员名为Sheets
:
We can start with finding what object type the Sheets
member call belongs to. If we filter for the Excel
library and search for Sheets
, we find 2 interesting results where a member is named Sheets
:
-
Application.Sheets
-
Workbook.Sheets
Application.Sheets
Workbook.Sheets
这意味着除非该行代码位于ThisWorkbook
的代码后面,否则我们所调用的内容不能为Workbook.Sheets
-但我们也不会使用Application
对其进行限定!如果我们揭示隐藏的成员,我们会发现隐藏的Global
类和_Global
接口,它们都暴露了Sheets
成员!从那里我们可以推断出Excel对象模型正在将我们不合格的Sheets
调用重定向"到Application
对象,这看起来像是为我们提供了ActiveWorkbook
成员的Sheets
成员一样.无论如何,_Global
和Global
之间的关系令人困惑:我们选择_Global.Sheets
,底部面板告诉我们正在查看Excel.Global
的成员:
This means unless that line of code is in the code-behind of ThisWorkbook
, what we're calling can't be Workbook.Sheets
- but we're not qualifying it with Application
either! If we reveal hidden members, we discover a hidden Global
class and a _Global
interface that both expose a Sheets
member! From there we can infer that the Excel object model is "redirecting" our unqualified Sheets
call to the Application
object, which looks like it's giving us the Sheets
member of whatever the ActiveWorkbook
is. In any case, the relationship between _Global
and Global
is confusing: we select _Global.Sheets
and the bottom panel tells us we're looking at a member of Excel.Global
:
请注意,该属性没有任何参数:它只是产生对Sheets
对象的引用.因此,我们查看返回的Sheets
类型-通过单击底部面板中的超链接,或通过浏览左侧面板以找到Sheets
集合类型(通常恰好与Sheets
属性具有相同的名称) Global
,Application
和Workbook
类).
Notice the property doesn't have any parameters: it simply yields a reference to a Sheets
object. So we look at the returned Sheets
type - either by clicking the hyperlink in the bottom panel, or by browsing the left panel to find the Sheets
collection type (which conveniently happens to have the same name as the Sheets
property of the Global
, Application
, and Workbook
classes).
请注意,Workbook.Worksheets
属性还会产生一个Sheets
集合对象.
Note that the Workbook.Worksheets
property also yields a Sheets
collection object.
与所有其他集合类一样,Sheets
类具有一个默认成员,并且该成员已隐藏,其名称为_Default
,并返回一个Object
.我们可以猜测该属性会将调用转发给Item
索引器,因为集合类通常公开了一种通过索引或名称/键(按惯例将其命名为Item
)访问其项的方法,但有时它是其他名称,例如Recordset.Fields
)...但现在该属性还返回了Object
.
Like all other collection classes, the Sheets
class has a default member, and this one is hidden, it's named _Default
, and it returns an Object
. We can guess that the property is forwarding the call to the Item
indexer, because collection classes normally expose a way to access their items by index or by name/key (by convention it's named Item
but sometimes it's something else, like Recordset.Fields
)... but now that property also returns an Object
.
默认成员
VBA中的类可以具有一个成员(只有一个!),当将对象强制转换为值时,可以隐式调用该成员.该成员具有一个隐藏的VB_UserMemId
属性,其值为0
,并且对象浏览器在该成员的图标上使用蓝色/青色点标识该属性.这就是编写Debug.Print Application
时Application.Name
的输出方式;这也是当您不使用Set
关键字将Let
-Range
对象强制转换为Variant
或任何其他非对象类型时得到Range.Value
的原因.这就是为什么Set
关键字分配对象引用时是必需的:没有它,编译器将无法告诉您是要分配对象本身还是其默认成员值...这很可能是另一个对象引用.
通常,最好避免隐式的默认成员调用并进行显式的调用,以使代码陈述其作用,并按其言行.
Default Members
Classes in VBA can have a member (only one!) that can be implicitly invoked when the object is coerced into a value. This member has a hiddenVB_UserMemId
attribute with a value of0
, and the object browser identifies it with a blue/cyan dot on the member's icon. That's howApplication.Name
gets output when you writeDebug.Print Application
; that's also how you getRange.Value
when youLet
-coerce aRange
object into aVariant
or any other non-object type without using theSet
keyword... and it's why theSet
keyword is required when assigning object references: without it the compiler wouldn't have a way to tell whether you mean to assign the object itself or its default member value... which can very well be another object reference.
In general, it's best to avoid implicit default member calls and be explicit, so that the code says what it does, and does what it says.
在这一点上,我们很困惑,就像编译器一样:该行代码上的每个其他成员调用只能在运行时解决-它们都是后期绑定的,并且当您键入它时,您不会得到 IntelliSense ,没有自动完成功能,没有编译时验证:即使Option Explicit
也无法将您从错别字中救出来,而且如果您输入错字,您也会知道,因为VBA会抛出错误438我找不到该成员".
At this point we're stumped, just like the compiler is: every further member call on that line of code is only resolvable at run-time - it's all late-bound, and when you type it you get no IntelliSense, no autocompletion, no compile-time validation: even Option Explicit
can't save you from a typo, and if you make one you'll know because VBA will throw error 438 "I can't find that member" at you.
Sheets._Default
返回一个Object
:并非所有工作表都是Worksheet
对象-Chart
也可以是工作表!这就是为什么我们通常更喜欢使用Workbook.Worksheets
属性,以便我们确定要获得Worksheet
对象.正确的? "Sheet1"是一个Worksheet
,我们知道很多!
Sheets._Default
returns an Object
: not all sheets are Worksheet
objects - a Chart
could be a sheet as well! That's why we usually prefer to use the Workbook.Worksheets
property instead, so that we're certain to get a Worksheet
object. Right? "Sheet1" is a Worksheet
, we know as much!
我们可以通过声明Worksheet
变量来恢复早期绑定:
We could restore early binding by declaring a Worksheet
variable:
Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Worksheets("Sheet1")
sheet.ChartObjects(1).Chart.ChartArea.Border.LineStyle = xlContinuous
因此,我们在左侧窗格中浏览到Worksheet
类型,找到其ChartObjects
方法(它是Function
),该方法还返回了Object
.在属性类型是Excel类型库中的常规约定之后,看起来就像在命名属性一样-左窗格中有一个ChartObjects
对象集合,我们可以假定其项是ChartObject
对象;因此我们再次在左窗格中找到ChartObject
类,并看到它具有返回Chart
对象的Chart
属性:
So we browse to the Worksheet
type in the left pane, find its ChartObjects
method (it's a Function
), which also returns an Object
. Looks like naming properties after their type is a common convention in the Excel type library - there's a ChartObjects
object collection in the left pane, and we can probably assume its items are ChartObject
objects; so we find the ChartObject
class again in the left pane, and see that it has a Chart
property that returns a Chart
object:
这时,我们可以通过提取另一个变量来恢复成员调用链中更早的绑定:
At this point we can restore early binding further down the chain of member calls, by extracting another variable:
Dim targetChartObj As ChartObject
Set targetChartObj = sheet.ChartObjects(1)
targetChartObj.Chart.ChartArea.Border.LineStyle = xlContinuous
ChartArea
属性产生一个ChartArea
对象,因此我们在左侧面板中找到了ChartArea
类,...并且看到它具有 hidden Border
属性!
The ChartArea
property yields a ChartArea
object, so we find the ChartArea
class in the left panel, ...and see that it has a hidden Border
property!
ChartArea.Border
属性返回一个Border
对象,再次在左侧面板中找到该对象,它具有LineStyle
属性...类型为Variant
.那我们怎么应该知道xlContinuous
呢?没有希望吗?
The ChartArea.Border
property returns a Border
object, which again we find in the left panel to see that it has a LineStyle
property... of type Variant
. How are we supposed to know xlContinuous
is even a thing then? Is there no hope?
这时,我们可以搜索Border.LineStyle
并查看文档是否为我们提供了有关法律价值的线索,...或者我们可以尝试在搜索框中搜索LineStyle
...
At this point we could google up Border.LineStyle
and see if the docs give us a clue about the legal values, ...or we could try to search for LineStyle
in the search box...
...,然后看到有一个名为xlContinuous
的成员的XlLineStyle
枚举,以及在该枚举下定义的所有其他常量.快速的在线搜索显示了官方文档,并确认 Border .LineStyle 想要一个XlLineStyle
枚举值!
...and see that there's an XlLineStyle
enum with a member named xlContinuous
, alongside all other constants defined under that enum. A quick online search brings up the official docs and confirms that Border.LineStyle wants an XlLineStyle
enum value!
现在,这是从左向右移动.从右到左,您可以利用搜索框向上移动;搜索带有可见隐藏成员的边界",在搜索结果中列出ChartArea.Border
成员.
Now, this was moving left-to-right. Going right-to-left, you can work your way up by leveraging the search box; searching for "Border" with hidden members visible, lists the ChartArea.Border
member in the search results.
这篇关于VBA:如何使用对象浏览器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!