#excel #vba
#excel #vba
Вопрос:
У меня есть простой код, который перемещает данные рабочего листа на лист после активации.
Sub Workbook_SheetActivate(ByVal Sh As Object)
Worksheets("Data").Move After:=Worksheets(Sh.Name)
Worksheets(Sh.Name).Activate
End Sub
Я использую
Worksheets(Sh.Name).Activate
потому что без этой строки «Данные» рабочего листа остаются выбранными после перемещения, что не является намерением.
Проблема, с которой я сталкиваюсь, заключается в том, что при запуске этого кода Excel требуется около 2-3 секунд, чтобы подумать об этом, прежде чем увидеть результат.
Я не понимаю, почему. Без объединения этих 2 операций вместе это занимает миллисекунды. Не мог бы кто-нибудь объяснить, как это улучшить и почему это происходит?
Комментарии:
1. Причин такого поведения может быть несколько, например: другой макрос, который используется для вычисления некоторых значений. Я бы проверил, активен ли
Data
лист, а затем изменил порядок листов. Кстати: можете ли вы уточнить, почемуData
лист должен быть неактивным?2. Или почему вам нужно, чтобы Sh был активным? Если у вас используется другой код
ActiveSheet
, вы можете заменить его различными способами…3. Ваш код войдет в бесконечный цикл — более 2-3 секунд, я бы подумал. Перед его запуском необходимо отключить события.
4. Кстати
Worksheets(Sh.Name)
, эквивалентноsh
.
Ответ №1:
Это должно быть быстрее:
Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim nam As String
nam = Sh.Name
Application.EnableEvents = False
Worksheets("Data").Move After:=Worksheets(nam)
Worksheets(nam).Activate
Application.EnableEvents = True
End Sub
Ответ №2:
Это происходит из-за рекурсивного вызова: когда вы используете .Activate
, ваш Sub
Workbook_SheetActivate
вызывается снова, и вы застреваете в бесконечном цикле.
Если вы просто хотите отменить выбор диапазона данных, вы можете использовать Cells(1,1).Select
, и вы можете напрямую использовать Sh
вместо использования Worksheets(Sh.Name)
, поскольку они эквивалентны.
Итак, ваш окончательный код будет:
Sub Workbook_SheetActivate(ByVal Sh As Object)
Worksheets("Data").Move After:=Sh
Cells(1,1).Select
End Sub
Надеюсь, это поможет.
Ответ №3:
Спасибо за ваш вклад, ребята. Отключение / включение событий помогло выйти из цикла.
Application.EnableEvents = False
Worksheets("Data").Move After:=Sh
sh.Activate
Application.EnableEvents = True
Вероятно, я должен был объяснить, для чего использовался код в моем вопросе.
У пользователя было более 50 листов в рабочей книге (пожалуйста, не спрашивайте меня, почему :)). У них был один конкретный («Данные»), который они хотели иметь возможность нажимать и выключать во время работы с другими листами. Итак, этот код просто заставлял «Данные» рабочего листа «следовать за ними»
Строка:
sh.Activate
Использовался для возврата к рабочему листу, на который они только что нажали, так как в противном случае они застревали на листе «Данные».