。选择,。活动表,。活细胞等...

时间:2012-09-14 14:43:44

标签: vba excel-vba excel

对于这个问题,我参考下面的帖子来澄清自己:
Why is my conditional format offset when added by VBA?

在我看到的很多很多帖子中,OP默默地允许使用.Activate,.Select,.Offset等......虽然它们是潜在错误的开门(最常见的是由最终用户引起) 。
有时甚至支持代码。

我的问题:是否存在一种有效的情况,您可以使用这些语句中的任何一种语句而没有直接的替代方法来捕获这些stmts导致的典型错误?

我指的是动态解决方案,在我看来,在为Excel开发时,必须。 就个人而言,在6年多的时间里,我不记得我需要的一个案例;它似乎永远是最糟糕的选择之一。在我以前的公司中,这是一个永远不会使用它的静默规则,它只会使我的VBA生活(以及最终用户的生活)变得更好。

为什么我创建这个问题是因为我认为让新人进入VBA意识到他们在使用这些陈述时所冒的风险是值得的(当最终用户做出意想不到的事情时,经验证明风险 - 最终他们不会对VBA有任何感情)并提出直接替代方案(我不会说我总是在自己之前做过这样的事情,但我觉得在我的肠道中提供快速解决方案已经存在问题)。

我相信,当默默地允许(在这种情况下它自动增强)时,启动VBA开发人员将以错误的方式创建越来越多的工具(因此新手也会继承行为 - 他们也将从Stack Overflow中学习因为Google会返回他们寻找的结果(!)) 如果开发人员不知道为什么他“可以”使用“选择”,并且在哪种情况下这是一个潜在的错误,他应该永远不会使用它。就个人而言,我可能会使用即时窗口中的select stmt对动态范围定义(错误模式)进行快速检查,但不能在编写代码中进行快速检查。

结果使得VBA最终比现在更不受欢迎;如果麻烦出现,语言将成为受害者(但它仍然是Excel和Access应用程序可用的“最佳”编程支持)。我已经在一家大公司看到这种情况发生了太多次,其中VBA总是“糟糕”。

这只是我自己的诚实经历 这不是对或错的问题;我有兴趣听取你对这个问题的看法。

5 个答案:

答案 0 :(得分:3)

我同意Select和Activate,但不同意ActiveWorkbook,ActiveSheet和ActiveCell(我同意它们被滥用,但并不是说它们本身应该被避免)。这些肯定是合法的用途。我有一个程序可以自动化#34; fill series"这是从ActiveCell这样做的。我的程序无法预测将使用哪些细胞;它是用户选择它。这是用户界面的一部分。

然而,有三种情况我不得不使用Select(现在有四种我读过有关缩放的内容,但我还没有使用过它)。

  1. 条件格式。有一个使用Application.ConvertFormula的工作,但它比仅存储选择,选择正确的单元格,做行动以及重新选择先前的选择更糟糕。
  2. 数据验证。同样的原因。
  3. 形状。我希望我能记住细节,但是因为我和Shapes一起工作已经太久了。如果没有首先选择形状,我就无法做到。
  4. 选择和激活的Ridding代码是一场崇高的战斗。

答案 1 :(得分:2)

Excel中有一些方法需要Activate或ActiveSheet / ActiveWorkbook等,因为我偶尔会遇到陷阱。我目前唯一记得的是缩放属性。缩放仅影响窗口中当前活动的工作表,以便缩放所需的所有工作表(如

Sub SetZoom()
Dim ws As Worksheet
    Application.screenupdating = false

    For Each ws In Worksheets
        ws.Select
        ActiveWindow.Zoom = 80
    Next ws

    Application.screenupdating = true
End Sub

答案 2 :(得分:1)

您可以使用.Select确定运行代码后用户的视图 - 例如,如果您在代码中创建新工作簿,而不使用ActivateSelect您的用户可能不知道会发生这种情况。

我经常结束使用

创建新工作簿或其他大规模数据操作的长时间操作
FinalViewWorkbook.FinalViewSheet.Range("A1").Select

只是告诉最终用户一些事情 - “哦,这创建了一个新的报告工作簿!”等

答案 3 :(得分:0)

我认为在这个问题上区分一些是很重要的:

  • Active - 东西:只有在必须知道用户正在处理的内容时才使用此内容。根据我的经验,这通常是数据验证或活动工作表检测(例如“更新用户刚刚按下按钮的工作表”)。
  • Selection:与Active有些相同,只能阅读。用户可以使用数据验证,也可以使用“将单元格值解释为路径并在新的资源管理器窗口中打开”等噱头。
  • SelectActivate:Imho与Selection不同,因为它实际上更改了所选的单元格,工作表等。永远不会使用它来读取或写入数据,因为它使用户只需点击即可搞乱您的程序。用户喜欢点击。仅使用此缩放(请参阅@ user3357963的答案)或在代码完成工作后清理视图(请参阅@enderland的回答)。 (我不确定,但我认为处理PageView也需要ActiveSheet)。
  • SelectActivate第二个:如果您是VBA的新手并且正在通过Macro Recorder学习,您会发现很多代码都是这样生成的: 先是Range("A5").Select,然后是Selection.Value="NewValue"。加入此Range("A5").Value="NewValue"
  • Offset:就我个人而言,使用.Offset()时没有问题 - 我从未遇到过这个命令的问题。相反,我认为这是一种方便的方式来说“旁边的单元格”,而不必每次都经过“这个单元格的行和列+ 1”的单元格。
  

在我看到的许多帖子中,OP默默地允许使用.Activate,.Select,.Offset等......

我同意这一点。尽管为一段代码提供必要的答案更容易,但是不应该使用ActiveCell.Value之类的东西。如果有一个很好的解释线程链接到这将更容易,因为这有希望成为: - )

答案 4 :(得分:0)

从我的角度来看,除少数例外情况外,您应该使用Select的唯一时间是作为用户输入,然后才仔细考虑其他设计/ UI要求。

例如,我认为当这个方法在代码中执行时,依赖Selection来让用户定义一个Range对象通常是不可取的:

Dim myRange as Range
Set myRange = Application.InputBox("Select your range", Type:=8)

但是,如果您需要提示用户选择工作表上的特定形状或对象,那么可能最好让他们制作Selection(但是,这可以打开潘多拉的问题框没有良好的错误处理和逻辑,以防止不希望的用户操作......)。

以下是我在PowerPoint中遇到的一个此类例外的示例。我有一些RibbonUI XML和VBA,它向PowerPoint中的Shapes右键单击上下文菜单添加按钮,并向功能区本身添加类似的按钮。这些是无缝的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
 '....
 '...
 '..
 '.

它来自哪里?

宏记录器。本质上,此功能记录每个文字用户输入:滚动,选择,查看,激活,默认属性等,以至于过度杀伤。虽然这有时是有帮助的,但它确实鼓励那些不知道它不好的人写的坏代码,但我不会在这里提出这一点:

How to avoid using Select in Excel VBA macros

从概念上讲哪个更好?

直接编程对象。如果您只是使用VBA模仿击键和鼠标点击,那么你做错了。

<强>例外:

我在将格式应用于图表中的系列数据时发现,偶尔需要Select。这似乎IMO是Excel的一个错误,而不是一个设计功能。

其他应用程序(因为VBA不仅 Excel):

  • Word是一种不同的动物,它更多地依赖于选择对象
  • 在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可能但是它太无能为力了)并且当大多数人在其他应用程序中进行任何开发时,他们已经想到了大部分已经这样了。