Excel에서 워크시트 이벤트 이름 바꾸기
엑셀 시트의 이름을 바꿀 때 VBA 코드를 실행하는 가장 좋은 방법은 무엇입니까?
응용 프로그램 개체를 사용하더라도 이를 처리할 이벤트가 없는 것 같습니다.짜증나.
워크시트의 시작 값을 저장하고 가능한 한 많은 이벤트를 확인하여 캡처하려고 합니다. 이는 명백한 해킹입니다.
다음은 저에게 효과가 있는 것 같습니다. 도움이 되길 바랍니다.
이 워크북 모듈에서:
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
한 가지 접근법이 있습니다.이 방법은 전용 클래스를 통해 응용 프로그램 수준에서 이벤트를 트랩하는 것입니다.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
위의 예제는 사용자가 다른 워크시트를 선택한 경우에만 트리거됩니다.보다 세분화하려면 시트 변경 이벤트도 모니터링합니다.
오래된 질문인 것은 알지만 최근에 엑셀을 사용하기 시작했습니다.CELL("filename")
파일 및 시트 이름에 대한 세부 정보를 반환하는 함수입니다.
다음과 같은 잘 알려진 공식을 사용하여 시트 이름을 구문 분석할 수 있습니다.
=MID("파일명", A1), FIND("]", CELL("파일명", A1)+1,255)"
숨겨진 워크시트에 이 함수를 쓴 다음 모니터링합니다._Calculate
해당 시트에 이벤트가 있으면 워크시트 이름의 변경 사항을 확인할 수 있습니다.
고객과 VBA 코드를 공유해야 했기 때문에 이 방법을 사용해야 했습니다. 이를 통해 고객은 특정 워크시트 이름을 프로그래밍 방식으로 변경할 수 있을 뿐만 아니라 탭에 입력할 수도 있었습니다.이 메서드는 코드로 작성된 경우에도 시트 이름 변경 이벤트를 캡처합니다.
아래의 스켈레톤 코드에서 활성 워크시트의 이름 변경을 캡처했지만 대상 워크시트 목록을 추가하고 그에 따라 처리 코드를 조정하는 것을 막을 수 있는 것은 없습니다.
아래 코드는 워크북 코드 뒤에 있습니다.
Option Explicit
Private mSheetNamesWS As Worksheet
Private mOldSheetName As String
Private Sub Workbook_Open()
'Find or create the hidden worksheet
'containing the sheet reference.
On Error Resume Next
Set mSheetNamesWS = Me.Worksheets("SheetNames")
On Error GoTo 0
If mSheetNamesWS Is Nothing Then
'Disable events so that the _calculate event
'isn't thrown.
Application.EnableEvents = False
Set mSheetNamesWS = Me.Worksheets.Add
With mSheetNamesWS
.Name = "SheetNames"
.Visible = xlSheetVeryHidden
End With
Application.EnableEvents = True
End If
'Update the sheet reference.
If TypeOf ActiveSheet Is Worksheet Then
UpdateCellFormula
End If
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
'Active sheet has changed so update the reference.
If TypeOf ActiveSheet Is Worksheet Then
UpdateCellFormula
End If
End Sub
Private Sub UpdateCellFormula()
Dim cellRef As String
'Sense check.
If mSheetNamesWS Is Nothing Then Exit Sub
'The CELL function returns details about
'the file and sheet name of any
'specified range.
'By adding a formula that extracts the
'sheet name portion from the CELL function,
'we can listen for any changes
'of that value in the _calculate event method.
'Disable events to avoid a spurious
'_calculate event.
Application.EnableEvents = False
cellRef = ActiveSheet.Name & "!A1"
With mSheetNamesWS.Range("A1")
.Formula = _
"=MID(CELL(""filename""," & _
cellRef & _
"),FIND(""]"",CELL(""filename""," & _
cellRef & _
"))+1,255)"
mOldSheetName = .Value
End With
Application.EnableEvents = True
End Sub
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
'Disregard any sheet that isn't our reference sheet.
If Not Sh Is mSheetNamesWS Then Exit Sub
'The reference sheet has recalculated.
'It means the value of the cell containing
'the current sheet name has changed.
'Ergo we have a sheet name change.
'Handle the event here ...
MsgBox "You can't change the name of this sheet!"
Application.EnableEvents = False
ActiveSheet.Name = mOldSheetName
Application.EnableEvents = True
End Sub
시트 이름 변경 후 발생하는 유일한 이벤트:Application.CommandBars_OnUpdate
이를 기반으로 시트 이름이 변경되었는지 빠르게 확인하는 코드를 만들 수 있습니다.분명히 그러한 접근법은 투박해 보이고, 그로 인해 약간의 간접비가 있습니다.OnUpdate
이벤트는 거의 모든 애플리케이션의 변경 사항에 대해 실행됩니다. 어쨌든 없는 것보다는 낫습니다.나는 그 후에 알아차렸습니다.Application_SheetSelectionChange
최대 초당 약 2회 작동하므로 애플리케이션을 중단해서는 안 됩니다.
은 래퍼 입니다.Application.CommandBars_OnUpdate
이벤트는 추가, 이름 바꾸기, 이동 및 삭제와 같은 추가 워크시트 이벤트를 추적하는 데 도움이 됩니다.
클래스 모듈을 만들고 이름을 지정cSheetEvents
다음 코드를 입력합니다.
Option Explicit
Public Event SheetAdd(ByVal wb As Workbook, ByVal sh As Object)
Public Event SheetRename(ByVal wb As Workbook, ByVal sh As Object, ByVal oldName As String)
Public Event SheetMove(ByVal wb As Workbook, ByVal sh As Object, ByVal oldIndex As Long)
Public Event SheetDelete(ByVal wb As Workbook, ByVal oldName As String, ByVal oldIndex As Long)
Public Event SheetAny()
Private WithEvents app As Application
Private WithEvents appCmdBars As CommandBars
Private skipCheck As Boolean
Private sheetData As Object
Private Sub Class_Initialize()
Set app = Application
Set appCmdBars = Application.CommandBars
Set sheetData = CreateObject("Scripting.Dictionary")
Dim wb As Workbook
For Each wb In app.Workbooks
Dim sh As Object
For Each sh In wb.sheets
sheetData(sh) = Array(sh.Name, sh.index, wb)
Next
Next
End Sub
Private Sub Class_Terminate()
Set sheetData = Nothing
End Sub
Private Sub app_NewWorkbook(ByVal wb As Workbook)
Dim sh As Object
For Each sh In wb.sheets
sheetData(sh) = Array(sh.Name, sh.index, wb)
Next
End Sub
Private Sub app_WorkbookOpen(ByVal wb As Workbook)
Dim sh As Object
For Each sh In wb.sheets
sheetData(sh) = Array(sh.Name, sh.index, wb)
Next
End Sub
Private Sub app_WorkbookNewSheet(ByVal wb As Workbook, ByVal sh As Object)
sheetData(sh) = Array(sh.Name, sh.index, wb)
RaiseEvent SheetAdd(wb, sh)
RaiseEvent SheetAny
skipCheck = True
End Sub
Private Sub app_SheetChange(ByVal sh As Object, ByVal Target As Range)
skipCheck = True
End Sub
Private Sub appCmdBars_OnUpdate()
If skipCheck Then
skipCheck = False
Else
Dim anyEvt As Boolean
Dim wb As Workbook
For Each wb In app.Workbooks
Dim sh As Object
For Each sh In wb.sheets
If Not sheetData.exists(sh) Then
sheetData(sh) = Array(sh.Name, sh.index, wb)
RaiseEvent SheetAdd(wb, sh)
anyEvt = True
End If
Next
Next
On Error Resume Next
For Each sh In sheetData
Set wb = sheetData(sh)(2)
If wb.Name = "" Then
sheetData.Remove sh
Set sh = Nothing
Set wb = Nothing
Else
Dim oldName As String
oldName = sheetData(sh)(0)
Dim oldIndex As Long
oldIndex = sheetData(sh)(1)
If sh.Name = "" Then
sheetData.Remove sh
Set sh = Nothing
RaiseEvent SheetDelete(wb, oldName, oldIndex)
anyEvt = True
Else
If sh.Name <> oldName Then
sheetData(sh) = Array(sh.Name, sh.index, wb)
RaiseEvent SheetRename(wb, sh, oldName)
anyEvt = True
ElseIf sh.index <> oldIndex Then
sheetData(sh) = Array(sh.Name, sh.index, wb)
RaiseEvent SheetMove(wb, sh, oldIndex)
anyEvt = True
End If
End If
End If
Next
If anyEvt Then
RaiseEvent SheetAny
End If
End If
End Sub
한 몇 가지 예를 들어보겠습니다.OnUpdate
직의사건 Application_SheetChange
플래그 변수를 추가하여 오버헤드를 줄이기 위해 건너뜁니다.당신은 다른 불필요한 이벤트를 건너뛸 수도 있습니다.참고, 그것은 예를 들어.Application_SheetSelectionChange
사용자가 입력하여 시트의 이름을 바꾼 후 시트의 셀을 클릭하면 이벤트가 발생합니다.Application_SheetCalculate
이벤트는 시트의 이름이 변경되고 휘발성 공식이 어딘가에 존재할 때 발생합니다.
오브젝트 모듈이라도 할 수 를 들어, 테트를위객모사수있다습니용할듈을체같은스해다음과,▁for▁module,다▁any▁let▁use있▁you▁object니습'.ThisWorkbook
모듈에 다음 코드를 입력합니다.
Option Explicit
Private WithEvents sheetEvents As cSheetEvents
Private Sub Workbook_Open()
Set sheetEvents = New cSheetEvents
End Sub
Private Sub sheetEvents_SheetAdd(ByVal wb As Workbook, ByVal sh As Object)
MsgBox _
"Sheet added" & vbCrLf & _
Now & vbCrLf & vbCrLf & _
"Workbook: " & wb.Name & vbCrLf & _
"Name: " & sh.Name
End Sub
Private Sub sheetEvents_SheetRename(ByVal wb As Workbook, ByVal sh As Object, ByVal oldName As String)
MsgBox _
"Sheet renamed" & vbCrLf & _
Now & vbCrLf & vbCrLf & _
"Workbook: " & wb.Name & vbCrLf & _
"Old name: " & oldName & vbCrLf & _
"New name: " & sh.Name
End Sub
Private Sub sheetEvents_SheetMove(ByVal wb As Workbook, ByVal sh As Object, ByVal oldIndex As Long)
MsgBox _
"Sheet renamed" & vbCrLf & _
Now & vbCrLf & vbCrLf & _
"Workbook: " & wb.Name & vbCrLf & _
"Name: " & sh.Name & vbCrLf & _
"Old index: " & oldIndex & vbCrLf & _
"New index: " & sh.Index
End Sub
Private Sub sheetEvents_SheetDelete(ByVal wb As Workbook, ByVal oldName As String, ByVal oldIndex As Long)
MsgBox _
"Sheet deleted" & vbCrLf & _
Now & vbCrLf & vbCrLf & _
"Workbook: " & wb.Name & vbCrLf & _
"Name: " & oldName & vbCrLf & _
"Index: " & oldIndex
End Sub
한 후. 각각의 워크북은SheetRename
그리고.SheetDelete
이벤트가 경고됩니다.
저는 이것에 대한 답변을 기다리고 있습니다. 왜냐하면 저는 많은 검색 끝에 그것을 알아내지 못했기 때문입니다.찾은 워크시트에 이름 바꾸기 이벤트가 없으므로 다른 방법을 사용해야 합니다.
제가 본 가장 좋은 방법은 (끔찍한 일이지만) 시트의 이름을 읽기 전용 또는 보이지 않게 만들어 이름을 바꾸는 것을 금지한 다음 이름을 변경하는 자체 도구 모음이나 단추를 제공하는 것입니다.매우 못생겼고 사용자들은 그것을 싫어합니다.
사무실 도구 모음에서 이름 바꾸기 메뉴 항목을 비활성화하는 응용 프로그램도 보았지만, 그렇다고 해서 탭을 두 번 클릭하고 이름을 바꾸는 것을 막을 수는 없습니다.또한 매우 못생겼고 사용자들은 그것을 싫어합니다.
행운을 빌어요, 누군가 더 좋은 답을 찾아냈으면 좋겠어요.
언급URL : https://stackoverflow.com/questions/1939919/rename-worksheet-event-in-excel
'programing' 카테고리의 다른 글
산점도:오른쪽의 lib-axis (0) | 2023.09.01 |
---|---|
Angular 4에서 모듈 'typescript'를 찾을 수 없음을 해결하는 방법은 무엇입니까? (0) | 2023.09.01 |
세 개의 하위 쿼리를 결합하고 교차점을 올바르게 세는 방법은 무엇입니까? (0) | 2023.09.01 |
요소가 화면 밖에 있는지 확인하는 방법 (0) | 2023.09.01 |
MariaDB 예기치 않은 토큰이 반환될 것 같습니다. (0) | 2023.09.01 |