Как превратить ячейки в командные кнопки с помощью VBA и Excel - PullRequest
0 голосов
/ 11 января 2019

Как можно превратить ячейки электронной таблицы в кнопки и выполнить код VBA, не вставляя кнопки, фигуры или другие объекты active-X?

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Используя предложение @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

Нажатие на URL-адрес в A2 увеличивает значение, отображаемое в A1, - одно приращение за клик.

Чтобы наблюдать эффект парения:

  1. Закомментируйте «Задать оператор»
  2. удалить кавычки и знак фунта вокруг ссылки UDF. В ячейке теперь будет отображаться «asdf» вместо «Test».
  3. Прокрутите URL-адрес, и ячейка A1 будет увеличиваться при перемещении / наведении курсора.

Чтобы вся ячейка вызывала выполнение UDF (и возрастающее значение), включите перенос слов для ячейки.

Обратите внимание, что при наведении указатель часто выполняется при перемещении в ячейке. Для меня код не выполняется, если я перестаю двигаться, находясь в камере.

0 голосов
/ 11 января 2019

Альтернатива «помещению кнопки в ячейку»

Выберите ячейку для выполнения кода, используя событие рабочего листа: Worksheet_SelectionChange

Поместите код в модуль конкретного листа, а не в модуль WorkBook. Цвет / Граница / Текст ячейки, как вам удобно; Ячейка на любом компьютере или экране. Я использую это для ссылки на справку, загруженную в пользовательскую форму, из поиска на листе справки, когда пользователь нажимает на короткую метку / описание. Это работает на объединенные ячейки как кнопки. Использование ячеек / кнопок позволяет избежать жалоб на объекты Active-X от ИТ-специалистов.

Что нужно продумать, с примером кода, следующим:

  1. Target.Address возвращает абсолютные адреса, используя символ "$"
  2. Используйте Select Case в своем коде, даже если у вас есть одна ячейка / кнопка. Это облегчает путь к добавлению ячейки / кнопок, позже
  3. рассмотрите возможность использования именованных диапазонов в электронной таблице и ссылки на них в коде. Таким образом, VBA не будет заботиться о перемещении ячейки / кнопки
  4. Если у вас есть объединенные ячейки, для которых вы создаете именованный диапазон, помните, что именованный диапазон в электронной таблице указывает только на верхнюю левую ячейку
    • Однако Target.Address для объединенной области возвращает полный диапазон, а не только одну ячейку. Если ваш Select Case ссылается на адрес верхней левой ячейки Target, вы избежите этой проблемы.
    • использовать Target.Cells(1,1).Address
  5. Неправильный выбор для объединенных ячеек: не используйте MergeArea.Address (MergeArea не будет работать для объединенных ячеек [работает только для отдельных ячеек); возвращает объединенный диапазон, в котором живет ячейка.

* Пример кода *

'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

...