Vba .选择、.Activesheet、.Activecell等。。。

Vba .选择、.Activesheet、.Activecell等。。。,vba,excel,Vba,Excel,对于这个问题,我参考下面的帖子来澄清自己: 在我最近看到的很多帖子中,OP都被默默地允许使用。。。而它们为潜在的bug(通常由最终用户引起)敞开了大门。 有时甚至支持该代码 我的问题:是否存在一种有效的情况,即您可以使用这些语句中的任何一个,而不使用直接的替代方法来捕获这些STMT导致的典型错误? 我指的是动态解决方案,在我看来,在为Excel开发时,动态解决方案是必须的。 就我个人而言,在6年多的时间里,我记不起我在哪里需要它;这似乎总是最糟糕的选择之一。在我以前的公司里,从不使用它是一条沉

对于这个问题,我参考下面的帖子来澄清自己:

在我最近看到的很多帖子中,OP都被默默地允许使用。。。而它们为潜在的bug(通常由最终用户引起)敞开了大门。
有时甚至支持该代码

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

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

我之所以提出这个问题,是因为我认为,让VBA新手意识到他们在使用这些语句时所面临的风险(经验证明,当最终用户做了一些意想不到的事情时,他们会面临风险——最终他们对VBA没有任何影响),并提出直接的替代方案是值得的(我不会说我以前总是这么做,但我内心深处觉得,仅仅针对已经存在的bug怪物提供快速解决方案是有问题的)

我相信,当默默地允许时(在本例中它会自动增强),启动VBA开发人员将以错误的方式创建越来越多的工具(因此,新来者也将继承这种行为——他们也将从堆栈溢出中学习,因为谷歌返回了他们寻找的结果(!)。
如果开发人员不知道为什么他“可以”使用“select”,以及在什么情况下它是一个潜在的bug,那么他就不应该立即使用它。我个人可能会在即时窗口中使用select stmt来快速检查动态范围定义(bug模式),但不是在书面代码中

结果使VBA最终比现在更不受欢迎;一旦出现问题,这种语言将成为受害者(但它仍然是Excel和Access应用程序可用的“最佳”编程支持)。在一家VBA总是“狗屎”的大公司,这种情况我已经见过太多次了

这只是我自己的真实经历。

这不是一个对错的问题;我很想听听你对这个问题的看法。

Excel中有一些方法需要激活或ActiveSheet/ActiveWorkbook等,因为我有时会遇到一些问题。目前我唯一记得的是zoom属性。zoom只影响当前在窗口中处于活动状态,因此要缩放所有图纸,您需要

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

我同意选择和激活,但不同意ActiveWorkbook、ActiveSheet和ActiveCell(我同意它们被滥用,但不同意它们本身应该被避免)。它们肯定有合法的用途。我有一个自动“填充系列”的程序这是通过ActiveCell实现的。我的程序无法预测将使用哪些单元格;由用户选择。这是用户界面的一部分

然而,有三种情况我不得不使用Select(现在有四种情况我读到了关于zoom的文章,但我从来没有使用过它)

  • 条件格式。使用Application.ConvertFormula有一个解决方法,但它比只存储选择、选择正确的单元格、执行契约和重新选择以前的选择更糟糕
  • 数据验证。同样的原因
  • 形状。我希望我能记住细节,但我已经很久没有使用形状了。如果不先选择形状,我就无法完成一些事情

  • 清除代码的选择和激活是一场崇高的斗争。

    您可以使用
    。选择
    来确定运行代码后用户的视图-例如,如果您在代码中创建了一个新工作簿,而没有使用
    激活
    选择
    ,您的用户可能不知道会发生这种情况

    我经常在创建新工作簿或其他大规模数据操作时使用

    FinalViewWorkbook.FinalViewSheet.Range("A1").Select
    

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

    我认为在这件事上区分一些是很重要的:

    • Active
      -注意事项:仅当绝对有必要知道用户现在正在处理什么时才使用此选项。根据我的经验,这通常是数据验证或活动工作表检测(例如,“更新用户刚刚按下按钮的工作表”)
    • 选择
      :与
      活动
      稍有相同,仅在数据验证或“将单元格值解释为路径并在新的资源管理器窗口中打开”等噱头时使用。Userful
    • 选择
      激活
      :它与
      选择
      不同,因为它实际上改变了选定的单元格、工作表等。永远不要使用它来读取或写入数据,因为它使用户只需单击就可以搞乱程序。用户喜欢单击。只使用它来缩放(请参见@user3357963的答案)或者在代码完成工作后清理视图(参见@enderland的答案)。(我不确定,但我认为处理页面视图也需要ActiveSheet)
    • 选择
      激活
      第二条:如果您是VBA新手,正在通过宏录制器学习,您会发现大量生成的代码如下: 首先是
      范围(“A5”)。选择
      ,然后选择
      选项。Value=“NewValue”
      。将此连接到
      范围(“A5”)。Value=“NewValue”
    • Offset
      :就个人而言,我在使用
      .Offset()
      时没有遇到问题-我从未遇到过此命令的问题。相反,我认为这是一种方便的方式,可以说“此单元格旁边的单元格”,而不必在该单元格的位置查看“此单元格的工作表”
      Dim myRange as Range
      Set myRange = Application.InputBox("Select your range", Type:=8)
      
      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
       '....
       '...
       '..
       '.
      
          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
      
              pt.Select
              pt.format.Line.Visible = msoTrue
              pt.format.Line.Visible = msoFalse
              pt.MarkerSize = pt.MarkerSize + 2