Как определить, что событие запускается конечным пользователем? (игнорировать триггер события по коду) - PullRequest
2 голосов
/ 09 мая 2020

Это вопрос от одного из моих клиентов, который разрабатывает веб-надстройку для Excel, он хотел бы определить, запускается ли событие конечным пользователем или запускается кодом.

Они зарегистрировались обработчик события Worksheet.onChanged.

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

Сценарий: надстройка прослушивает событие sheetChange. пользователь надстройки для ввода значений в перекрестные таблицы, которые надстройка отправит sh на сервер. Однако API надстройки также может вносить некоторые изменения в перекрестные таблицы, например, надстройка может разрешить пользователю один щелчок и развернуть, чтобы получить больше данных, их API logi c будет извлекать данные из службы и записывать к перекрестным таблицам. однако событие sheetChanged также будет инициировано.

Решения, которые опробовал заказчик:

Первая попытка: мы попытались отменить регистрацию обработчика событий перед изменением значений. Затем мы снова зарегистрировались после изменения значений. Это не сработало, так как отмена регистрации выполняется asyn c, и мы не смогли дождаться отмены регистрации.

Вторая попытка: context.runtime.enableEvents = false Это невозможно, поскольку есть другие события, которые мы все еще продолжаем интересует.

Текущая попытка: Мы сохраняем адрес измененного диапазона перед изменением значений. В обработчике onChanged мы сравниваем адрес. Если то же самое не делаем логи c. После этого мы снова удаляем хранилище адреса.

Я также пробовал использовать глобальный флаг и проверял его в обработчике событий, он не работает. вот моя суть: https://gist.github.com/lumine2008/2b51d94d20cdca9ac9a0e97029dfd95c

Ответы [ 2 ]

1 голос
/ 24 мая 2020

Office. js пока не предоставляет такую ​​функциональность.

Некоторые обходные пути, включая a) context.runtime.enableEvents API, b) глобальный флаг или c) событие отмены регистрации перед изменением диапазоны и перерегистрировать событие позже, кроссплатформенность не работает. Они будут чрезмерно подавлять события в некоторых сценариях ios, что означает, что некоторые события, инициированные операциями пользователя, также будут подавлены.

Самый надежный способ - это ваша «текущая попытка»

  1. Запишите адрес изменяемого диапазона перед изменением значений.
  2. В обработчике события onChanged сравните аргументы события с адресом, который вы записали ранее. Если он совпадает, очистите запись и выйдите из обработчика событий.
0 голосов
/ 22 мая 2020

Вы можете создать переменную, которая проверяет, редактирует ли пользователь.

например:


Private Sub Worksheet_Activate()

    Static programChanging As Boolean

    programChanging = False

End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

    If programChanging = False Then MsgBox("The User Is Changing")'*Do your code here*

End Sub

Private Sub Worksheet_SelectionChange(ByVal As Range)

    programChanging = True

    Range("A1").Value = "The Program Is Changing"

    programChanging = False

End Sub

Вы можете использовать переменную programChanging, чтобы проверить, меняет ли пользователь вместо этого если программа меняется, но принцип остается прежним.

~~ Edit ~~

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


Private Sub Worksheet_Change(ByVal Target As Range)

    If Range("A1").Value = "False" Then MsgBox("The User Is Changing")'*Do your code here*

End Sub

Private Sub Worksheet_SelectionChange(ByVal As Range)

    Range("A1").Value = "True"

    Range("B5").Value = "The Program Is Changing"

    Range("A1").Value = "False"

End Sub
...