如何使用VBA和Excel使单元格成为命令按钮

时间:2019-01-11 01:38:29

标签: excel vba button named-ranges

如何在不插入按钮,形状或其他active-X对象的情况下将电子表格单元格转换为按钮并执行VBA代码?

2 个答案:

答案 0 :(得分:1)

基于@TimWilliams的建议和引用的URL,根据那里的阅读内容,进一步介绍一些演示代码,这些代码在Excel 2010中对我有用:IfError在早期版本中可能不起作用,我想知道是否在以后的版本中,它的行为有所不同。

注意:无法像使用普通VBA那样调试此代码 。这是因为它是作为用户定义的函数在“电子表格侧”执行的。

在单元格(此处为A2)中放置一个公式:

  1. =IFERROR(HYPERLINK("#MyUDF()","CellText"),"Junk")
  2. “ CellText”将显示在单元格A2中。
  3. "#...."指向UDF。结合代码中的Set语句,它会强制执行“单击”,并且仅在单击时执行一次,而不是在单元格上悬停和移动时执行的可重复事件
  4. =IFERROR(HYPERLINK(...),...)是#name或其他错误的解决方法。仅使用=HYPERLINK(....)即可看到。

将此代码放置在模块(尺寸和UDF)中:

Dim j as integer

Function MyUDF() ' this is a user-defined-function
    'NOTE: can't be traced when executed, 
        'so this creates debugging issues
Set MyUDF = Selection
Range("a1") = j
j = j + 1
End Function

单击A2中的URL将增加A1中显示的值-每次单击增加1。

要观察悬停效果:

  1. 注释掉“设置语句”
  2. 删除UDF参考周围的引号和井号。现在,该单元格将显示“ asdf”而不是“ Test”。
  3. 在URL上滚动,随着移动/悬停,单元格A1将增加。

要获取整个单元格以导致执行UDF(以及递增值),请打开该单元格的自动换行功能。

请注意,当您在单元格中移动时,如何将鼠标悬停在代码上经常执行。对我来说,如果我停止在单元格中移动,代码将不会执行。

答案 1 :(得分:0)

“在单元格中放置按钮”的替代方法

选择一个单元格以使用工作表事件执行代码:Worksheet_SelectionChange

将代码放在特定工作表的模块中,而不是在WorkBook模块中。根据需要为单元格设置颜色/边框/文本;任何计算机或屏幕上的单元都是单元。当用户单击简短的标签/说明时,通过查找帮助工作表,我使用它来引用加载到userForm中的帮助。这适用于合并的单元格作为按钮。使用单元格/按钮可以避免IT人员投诉Active-X对象。

带有示例代码的思考事项如下:

  1. Target.Address使用“ $”字符返回绝对地址
  2. 即使您只有一个单元格/按钮,也请在代码中使用Select Case。这样可以简化以后添加单元格/按钮的路径
  3. 考虑在电子表格上使用命名范围,并在代码中引用它们。这样,VBA不会在乎您是否移动单元格/按钮
  4. 如果已合并要为其创建命名范围的单元格,请记住,电子表格中的命名范围仅指向左上角的单元格
    • 但是,合并区域的Target.Address返回整个范围,而不仅仅是一个单元格。如果您的Select Case指向Target左上角单元格的地址,则可以避免此问题。
    • 使用Target.Cells(1,1).Address
  5. 合并单元格的错误选择:不要使用MergeArea.AddressMergeArea不适用于合并单元格[仅适用于单个单元格];它将返回单元格所处的合并范围。 / li>

*示例代码*

'How to Make Cells into Buttons that execute code
' place code in the specific Worksheet module of interest
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   ' in this example, I create named ranges on the spreadsheet '
            ' [complicated names, here, so you can read what's what]:
      ' one cell:  "Button_OneCellNameRange"
      ' one set of merged cells:  "Button_MergedCellNameRange"
         ' [the reference is the top-left cell, only]

   ' a VBA created cell/button location [not very useful for later sheet edits]
      Dim myVBACellButton As Range
      Set myVBACellButton = Range("B2")

         Debug.Print "Target Address: " & Target.Address
               'merged cells will return a range: eg "$A$1:$D$3"

         Debug.Print "Target.Cells(1,1).Address: " & Target.Cells(1, 1).Address
               'merged cells will return the top left cell, which would match
                  ' a named reference to a merged cell

   Select Case Target.Cells(1, 1).Address
        'if you have merged cells, you must use the ".cells(1,1).address"
        ' and not just Target.Address

      Case Is = "$A$1"
         MsgBox "Hello from: Click on A1"
         ' [execute a procedure/subroutine call, or more code, here...]

      Case Is = myVBACellButton.Address
         MsgBox "Hello from: Click on B2, a VBA referenced cell/button"
            ' "myCellButton" defined as range in VBA

      'using a range named on the spreadsheet itself ...
         ' named ranges allow one to move the cell/button freely,
         ' without VBA worries
      Case Range("Button_OneCellNameRange").Address
         MsgBox "Hello From: Button Click on Button_OneCellNameRange"

      Case Range("Button_MergedCellNamedRange").Address
         'note that the address for merged cells is ONE CELL, the top left
         MsgBox _
            "Hello from: Button_MergedCellNamedRange.Address: " _
                  & Range("Button_MergedCellNamedRange").Address _

      Case Else ' normally you wouldn't be using this, for buttons
         MsgBox "NOT BUTTONS"

   End Select
End Sub

Image of the Sheet