Что лучший способ состоит в том, чтобы заставить некоторый код VBA выполнять, когда лист Excel переименован?
Вот один подход. Уловка состоит в том, чтобы уловить события на уровне приложения с помощью специального класса. Используя событие SheetActivate, сохраните ссылку на активный лист, а также его имя. Когда лист деактивирован (и активирован другой), сравните имя ссылки на лист с сохраненной строкой. Вот класс (названный CExcelEvents):
Option Explicit
Private WithEvents xl As Application
Private CurrSheet As Worksheet
Private CurrSheetName As String
Private Sub Class_Initialize()
Set xl = Excel.Application
Set CurrSheet = ActiveSheet
CurrSheetName = CurrSheet.Name
End Sub
Private Sub Class_Terminate()
Set xl = Nothing
End Sub
Private Sub xl_SheetActivate(ByVal Sh As Object)
If CurrSheetName <> CurrSheet.Name Then
Debug.Print "You've renamed the sheet: " & CurrSheetName & " to " & CurrSheet.Name
' Do something here - rename the sheet to original name?
End If
Set CurrSheet = Sh
CurrSheetName = CurrSheet.Name
End Sub
Создайте его экземпляр с помощью глобальной переменной, используя событие открытия рабочей книги:
Public xlc As CExcelEvents
Sub Workbook_Open()
Set xlc = New CExcelEvents
End Sub
Приведенный выше пример сработает только тогда, когда пользователь выберет другой рабочий лист. Если вы хотите большей детализации, отслеживайте также событие Sheet Change.
Очевидно, нет события для обработки этого, даже с использованием объекта Application. Как досадно.
Я бы, вероятно, попытался зафиксировать это, сохранив стартовое значение рабочего листа и проверив его на как можно большем количестве событий - что, по общему признанию, является взломом.
Следующее, казалось, сработало для меня, Надежда это помогает.
В модуле ThisWorkbook:
Private strWorksheetName As String
Private Sub Workbook_Open()
strWorksheetName = shtMySheet.Name
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call CheckWorksheetName
End Sub
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Call CheckWorksheetName
End Sub
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
Call CheckWorksheetName
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Call CheckWorksheetName
End Sub
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Call CheckWorksheetName
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Call CheckWorksheetName
End Sub
Private Sub CheckWorksheetName()
'If the worksheet has changed name'
If shtMySheet.Name <> strWorksheetName Then
DoSomething
End If
End Sub
Я с нетерпением жду ответа на этот вопрос, потому что не понял его после долгих поисков. На рабочем листе, который я нашел, нет события переименования, поэтому вы вынуждены использовать альтернативный подход.
Лучшее, что я видел (что ужасно ), - это запретить переименование листов, сделав их невидимыми или доступными только для чтения, а затем предоставить собственную панель инструментов или кнопку, которая выполняет переименование. Очень уродливо, и пользователи его ненавидят.
Я также видел приложения, которые отключали пункт меню переименования на панели инструментов офиса, но это не мешало двойному щелчку по вкладке и переименованию там. Также очень уродливый, и пользователи его ненавидят.
Удачи, я надеюсь, что кто-то придумает лучший ответ.