从我的角度来看,除了少数例外,您唯一应该使用的时间Select
是作为用户输入,并且只有在仔细考虑了替代设计/UI 要求之后。
例如,我会说Selection
当此方法在代码中继续执行时,通常不建议依靠让用户定义 Range 对象:
Dim myRange as Range
Set myRange = Application.InputBox("Select your range", Type:=8)
但是,如果您需要提示用户选择工作表上的特定形状或对象,那么最好让他们制作一个Selection
(但是,如果没有良好的错误处理和逻辑来防止不受欢迎的用户操作...)。
这是我在 PowerPoint 中遇到的一个此类异常的示例。我有一些 RibbonUI XML 和 VBA,它们将按钮添加到Shapes
PowerPoint 的右键单击上下文菜单中,并将类似的按钮添加到功能区本身。这些是无缝的 UI,可以为最终用户提供更“原生”的应用程序体验——用户希望能够右键单击图表,然后针对选定的图表或表格运行一些宏程序等。他们没有不想按下按钮打开用户表单并滚动浏览通用形状名称或 GUID 的列表框。
过程代码需要检查Selection
以正确处理它,因此我可以使用如下所示的内容,其中
Sub UpdateOrEditSelection(update As Boolean)
'This procedure invoked when user edits/updates a chart.
Dim uid As Variant
Dim sel As Selection
Dim s As Integer
Dim chartsToUpdate As Object
Dim multipleShapes As Boolean
Dim sld As Slide
Set sel = ppPres.Windows(1).Selection
If update Then
Set chartsToUpdate = CreateObject("Scripting.Dictionary")
Select Case sel.Type
Case ppSelectionShapes
For s = 1 To sel.ShapeRange.count
uid = sel.ShapeRange(s).Name
'....
'...
'..
'.
Next
Case ppSelectionSlides
For Each sld In sel.SlideRange
For s = 1 To sld.Shapes.count
uid = sld.Shapes(s).Name
'....
'...
'..
'.
Next
Next
Case ppSelectionText
s = 1
If sel.ShapeRange(s).HasTable Or sel.ShapeRange(s).HasChart Then
uid = sel.ShapeRange(s).Name
'....
'...
'..
'.
End If
End Select
'....
'...
'..
'.
它从何而来?
宏记录器。从本质上讲,此功能记录了每个文字用户输入:滚动、选择、查看、激活、默认属性等,到了矫枉过正的地步。虽然这有时会有所帮助,但它确实鼓励那些不知道它很糟糕的人编写糟糕的代码,但我不会在这里强调这一点:
如何避免在 Excel VBA 宏中使用 Select
从概念上讲,什么更好?
直接对对象进行编程。如果您只是使用 VBA 来模拟击键和鼠标点击,那么您做错了。
例外:
我发现在将格式应用于图表中的系列数据时,Select
有时是必要的。这似乎 IMO 是 Excel 的一个错误,而不是设计功能。
其他应用程序(因为 VBA不仅仅是Excel):
- Word 是一种不同的动物,它更多地依赖于 Selection 对象
- 在 PowerPoint 中,有些操作只能在应用程序和幻灯片/形状可见或以其他方式显示时才能执行。虽然您通常不需要“选择”任何东西,但它确实需要更繁琐的代码。
我在我的应用程序中找到了这个片段:
Set tb = cht.Shapes.AddTextbox(msoTextOrientationHorizontal, ptLeft, tBoxTop, ptWidth, ptHeight)
tb.Select '<--- KEEP THIS LINE OTHERWISE TEXTBOX ALIGNMENT WILL NOT WORK ## ## ##
和这个:
'PPT requires selecting the slide in order to export an image preview/jpg
sld.Select
ppPres.Windows(1).View.GotoSlide sld.SlideIndex
sld.Shapes(1).Chart.Export imgPath, ppShapeFormatJPG
而这个,处理单个Point
对象:
pt.Select
pt.format.Line.Visible = msoTrue
pt.format.Line.Visible = msoFalse
pt.MarkerSize = pt.MarkerSize + 2
这不是一个详尽的列表,只是我发现的一些例外示例。虽然这些来自 PowerPoint,但 PowerPoint 中的图表使用与 Excel 相同的对象模型,因此如果其中一些也需要在 Excel 和 Word 中被破解,我不会感到惊讶。
- Outlook:我对 Outlook 做的不多,它很像 Word,实际上在 Inspector 中使用 Word 对象模型,但我对 Outlook 所做的很少依赖于 ActiveInspector 等。
Word 或 PowerPoint 都不再有“宏记录器”(实际上,我认为 Word 可能会,但它太无能以至于无用),当大多数人在其他应用程序中进行任何开发时,他们已经弄清楚了大部分.