【问题标题】:Excel VBA: Click two buttons (shapes) that run two separate VBA scripts on spreadsheet openExcel VBA:单击两个按钮(形状)在电子表格打开时运行两个单独的 VBA 脚本
【发布时间】:2018-05-07 14:18:01
【问题描述】:

我有一个完全锁定的电子表格,并通过 VBA 控制所有排序和过滤。我还有另一个脚本可以在关闭时隐藏工作表并自动保存文件以隐藏该工作表。

我一直在试图弄清楚如何使用 VBA “单击”一个按钮(形状),这将清除任何已过滤的内容,然后“单击”另一个按钮(形状),该按钮将按字母顺序对电子表格进行排序.按钮(形状)已经与用户交互完美配合,但我也希望这些按钮(形状)在工作表打开时自动触发。

第一个按钮分配给宏SearchBox,与以下VBA相关联-

Sub SearchBox()

Dim myButton As OptionButton
Dim SearchString As String
Dim ButtonName As String
Dim sht As Worksheet
Dim myField As Long
Dim DataRange As Range
Dim mySearch As Variant

  Set sht = ActiveSheet

  On Error Resume Next
    sht.ShowAllData
  On Error GoTo 0

  Set DataRange = sht.ListObjects("DataTable").Range

  mySearch = sht.Shapes("UserSearch").TextFrame.Characters.Text

  If IsNumeric(mySearch) = True Then
    SearchString = "=" & mySearch
  Else
    SearchString = "=*" & mySearch & "*"
  End If

  For Each myButton In sht.OptionButtons
    If myButton.Value = 1 Then
      ButtonName = myButton.Text
      Exit For
    End If
  Next myButton

  myField = Application.WorksheetFunction.Match(ButtonName, DataRange.Rows(1), 0)

  DataRange.AutoFilter _
    Field:=myField, _
    Criteria1:=SearchString, _
    Operator:=xlAnd

  sht.Shapes("UserSearch").TextFrame.Characters.Text = ""

End Sub

第二个更简单,它只是按特定列对数据表进行排序 -

Sub Sort_Name()

Dim oneRange As Range
Dim aCell As Range

Set oneRange = Range("A4:H1162")
Set aCell = Range("A4")

oneRange.Sort Key1:=aCell, Order1:=xlAscending, Header:=xlYes

End Sub

基本上,我还在学习,我觉得可以通过脚本触发这些按钮,但我还没有弄清楚。任何帮助将不胜感激。

【问题讨论】:

  • 不需要点击按钮。您可以在另一个代码中使用Call SeachBox直接调用代码
  • 你像人一样思考。只需在代码中直接调用按钮链接到的子例程即可。按钮是为人类设计的。
  • 因此,在Workbook_Open 事件中,您将有两行代码:SearchBox /n SortCode(/n 代表新行,实际代码中不包含)。
  • 太棒了,谢谢大家 - 当@JNevill 说我像人类一样思考时,我查看了按钮本身正在进行的调用,我的问题是主脚本在 Sheet2 中,所以它不会工作,因为这是一个无效的电话。它现在运行良好,我的杰作已经完成。

标签: vba excel


【解决方案1】:

ThisWorkbook 的代码隐藏中,您将能够处理工作簿事件,包括工作簿打开时触发的Open 事件。

导航到模块(在 VBE 的 项目浏览器 [Ctrl+R] 中双击 ThisWorkbook),然后找到编辑器代码窗格顶部的下拉菜单。从左侧下拉列表中选择Workbook;然后,从右侧下拉列表中选择Open 事件; VBE 会自动为您创建具有正确签名的方法存根:

Private Sub Workbook_Open()

End Sub

注意下划线在VBA中有着非常特殊的含义;在命名您的程序时(尤其是隐式或显式Public ),始终坚持使用PascalCase 并避免使用Snake_Case;这可能现在无关紧要,但是随着您作为开发人员的进步,您将开始欣赏命名的一致性,并且当您开始使用接口时,下划线在- public-members 的事情将开始在有效的代码和甚至不能编译的代码之间产生差异:尽早养成好习惯可以避免以后的麻烦。

现在,您需要在该处理程序中调用两个过程。

当你这样做时:

oneRange.Sort Key1:=aCell, Order1:=xlAscending, Header:=xlYes

你正在调用oneRangeobjectSort方法,它是Range类的instance .

当你这样做时:

MsgBox "Hi!"

您正在调用VBA 库中Interaction 模块下的MsgBox 函数(在对象浏览器中找到它 [F2] )。这将是等效的:

VBA.Interaction.MsgBox "Hi!"

所以,调用你的SearchBox然后你的SortName方法,你需要做的就是:

Private Sub Workbook_Open()
    SearchBox
    SortName  'formerly known as Sort_Name
End Sub

Procedures do 某事 - 它们的名称应始终以动词开头,它们是 actions。 “SearchBox”看起来像一个名字,而不是一个动作。在编程中,名字更像是classes——一个Range,一个Workbook,等等;考虑重命名SearchBox 以更好地传达它的作用。如果这很难做到,可能是因为您的过程做了太多事情 - 比如获取用于过滤的名称,然后将过滤器应用于特定的表格,然后清除一些形状的文本

您还需要注意隐含的ActiveSheet 引用;目前SortName 假设ActiveSheet 是什么,这很可能会导致问题。

【讨论】:

    【解决方案2】:

    因此,解释我是如何完成我想做的事情的最佳方式是通过右键单击按钮并再次单击分配宏来查看按钮本身正在调用的内容。你会看到它看起来像这样 -

    'YourSpreadSheetName.xlsm'!Sheet2.SearchBox

    对我来说,让我失望的是我没有包括 Sheet2,这是我试图调用代码的地方。

    通过将此代码放在带有 Workbook_Open 脚本的 ThisWorkbook 部分中,我能够让它按照我想要的方式工作 -

    调用 Sheet2.SearchBox

    再次感谢所有评论者的帮助。

    【讨论】:

    • Call 关键字是多余的,已经过时了 20 年。此外,如果SearchBox 意味着针对Sheet2,那么它应该针对Sheet2,而不是ActiveSheet。预计会出现问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    相关资源
    最近更新 更多