VBA Excel - вызов макроса с помощью кнопок - PullRequest
0 голосов
/ 13 декабря 2018

Я написал следующий макрос, который вызывает Private Sub Worksheet_Calculate (), если я подтверждаю, что хочу его запустить.Ниже приведена первая часть кода:

Sub test()
Dim result As VbMsgBoxResult

result = MsgBox("Run Macro?", vbYesNo, "Excel VBA")

If result = vbYes Then
    Call Worksheet_Calculate
End If

End Sub

Второй код, который является Private Sub Worksheet_Calculate (), должен скопировать результат вычисления, выполненного в B2, и вставить его в C2, а также добавитьвременная метка для D2.Столбцы C и D заполняются как значения в изменении B2, так что я получаю список результатов и меток времени в C3 и D3, C4 и D4 и т. Д. Вот код:

Private Sub Worksheet_Calculate()
Dim lastrow As Long

lastrow = Worksheets(1).Cells(Rows.Count, 2).End(xlUp).Row

    With Worksheets(1).Cells(lastrow, 2)
        .Offset(1, 0) = Cells(2, 1).Value
        .Offset(1, 1) = FormatDateTime(Now, vbLongTime)
    End With

End Sub

Проблема, которую яЯ сталкиваюсь с тем, что мой Public Sub Worksheet_Calculate () вызывается только один раз, и всякий раз, когда я пересчитываю значение B2, ничего не происходит.

Есть ли способ а) сохранить второй код активированным или б) иметькнопка (кнопки) или флажок, который активирует / деактивирует второй код?

Надеюсь, это имеет смысл, заранее спасибо!

1 Ответ

0 голосов
/ 15 декабря 2018

Событие расчета рабочего листа

Это то, что вы положили в Module1 , или как вы будете называть свой Модуль.Это обычный модуль, созданный с помощью Add Module.Я оставил имя тестовой программы без изменений, но изменил другое, потому что оно используется для событий рабочего листа, в частности для события Worksheet Calculate .Программа test и переменная blnCalculation включают или отключают все это, поэтому вначале ничего не произойдет, прежде чем вы включите его.Вы можете создать для нее кнопку и в ее событии Click просто добавить Module1.test или просто запустить ее из Макросы .

Option Explicit

Public TargetValue As Variant
Public blnCalculation As Boolean

Sub test()
    Dim result As VbMsgBoxResult
    result = MsgBox("Run Macro?", vbYesNo, "Excel VBA")
    If result = vbYes Then
        blnCalculation = True
        ActiveSheet.Calculate
      Else
        blnCalculation = False
    End If
End Sub

Sub SheetCalculate()
    Dim lastrow As Long
    With ActiveSheet
    lastrow = .Cells(Rows.Count, 2).End(xlUp).Row
        With .Cells(lastrow, 2)
            .Offset(1, 0) = .Parent.Cells(2, 1).Value
            .Offset(1, 1) = FormatDateTime(Now, vbLongTime)
        End With
    End With
End Sub

И вот чтоВы вставляете в каждый листовой код, также известный как объектный модуль, дважды щелкнув по нему в VBE.Событие Расчет рабочего листа происходит каждый раз, когда Excel «решает» рассчитать рабочий лист, что в вашем случае, вероятно, гарантировано, потому что вы говорите, что в B2 есть формула, поэтому событие произойдет каждый раз B2 вычисляется .Но он не будет запускать программу SheetCalculate, если только значение не изменилось , что проверяется переменной TargetValue.Событие Активация рабочего листа происходит на рабочем листе, например, каждый раз, когда вы выбираете его на вкладке.В этом случае он используется для передачи нового значения B2 из вновь выбранного рабочего листа в переменную TargetValue.

Option Explicit

Private Sub Worksheet_Activate()
    If Module1.blnCalculation Then _
    Module1.TargetValue = Me.Range("B2").Value
End Sub

Private Sub Worksheet_Calculate()
    If Module1.blnCalculation Then
        If Me.Range("B2").Value <> Module1.TargetValue Then
            Module1.SheetCalculate
        End If
    End If
End Sub
...