|
1. Class ApplicationEventClass
========================================
Public WithEvents ExcelAppEvents As Application
Private Sub Class_Initialize()
Set ExcelAppEvents = Application
End Sub
Private Sub Class_Terminate()
Set ExcelAppEvents = Nothing
End Sub
Private Sub ExcelAppEvents_SheetActivate(ByVal Sh As Object)
dictNavigate.Add dictNavigate.Keys(dictNavigate.Count - 1) + 1, ActiveCell.Address(external:=True)
dictWbListCurrPos(Sh.Parent.Name) = dictNavigate.Count
lLastPosBeforeManualActive = 0
Call RefreshRibbonControl("btnBack")
Call RefreshRibbonControl("btnForward")
End Sub
Private Sub ExcelAppEvents_SheetDeactivate(ByVal Sh As Object)
Dim sRgAddr As String
Dim sLastRgAddr As String
Dim sWb As String
Dim sSheet As String
Dim sLastWb As String
Dim sLastSheet As String
Dim sActiveWbName As String
Dim i As Long
If lLastPosBeforeManualActive <= 0 Then Exit Sub
sActiveWbName = ActiveWorkbook.Name
sLastRgAddr = dictNavigate(lLastPosBeforeManualActive)
sLastWb = Replace(Replace(Split(sLastRgAddr, "]")(0), "[", ""), "'", "")
sLastSheet = Replace(Split(Split(sLastRgAddr, "]")(1), "!")(0), "'", "")
For i = lLastPosBeforeManualActive + 1 To dictNavigate.Keys(dictNavigate.Count - 1)
If Not dictNavigate.Exists(i) Then GoTo next_pos
sRgAddr = dictNavigate(i)
sWb = Replace(Replace(Split(sRgAddr, "]")(0), "[", ""), "'", "")
sSheet = Replace(Split(Split(sRgAddr, "]")(1), "!")(0), "'", "")
If sWb = sLastWb Then
dictNavigate.Remove i
End If
next_pos:
Next
End Sub
Private Sub ExcelAppEvents_WorkbookActivate(ByVal Wb As Workbook)
If Not dictWbListCurrPos.Exists(Wb.Name) Then dictWbListCurrPos.Add Wb.Name, 1
If dictNavigate.Count <= 0 Then
dictNavigate.Add 1, ActiveCell.Address(external:=True)
Else
dictNavigate.Add dictNavigate.Keys(dictNavigate.Count - 1) + 1, ActiveCell.Address(external:=True)
End If
End Sub
2. AddIn Thisworkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Set ApplicationClass = Nothing
Set dictNavigate = Nothing
Set dictWbListCurrPos = Nothing
Application.OnKey "%{LEFT}"
Application.OnKey "%{RIGHT}"
End Sub
Private Sub Workbook_Open()
Call sub_WorkBookInitialization
Application.OnKey "%{LEFT}", "subMain_NavigateBack"
Application.OnKey "%{RIGHT}", "subMain_NavigateForward"
ThisWorkbook.Saved = True
End Sub
Public Sub sub_WorkBookInitialization()
Set dictNavigate = New Dictionary
Set dictWbListCurrPos = New Dictionary
lLastPosBeforeManualActive = 0
Call fConnectEventHandler
End Sub
3. Module A (Main Function )
Public dictNavigate As Dictionary
Public dictWbListCurrPos As Dictionary
Public lLastPosBeforeManualActive As Long
Public ApplicationClass As ApplicationEventClass
Function fConnectEventHandler()
On Error Resume Next
Set ApplicationClass = New ApplicationEventClass
End Function
Function fNavigateStackNextPositionToMoveBack(Optional ByRef sWb As String, Optional ByRef sSheet As String) As Long
Dim lCurrPos As Long
Dim lNextPos As Long
Dim sRgAddr As String
Dim sActiveWbName As String
Dim i As Long
lNextPos = 0
If dictNavigate.Count <= 0 Then Exit Function
sActiveWbName = ActiveWorkbook.Name
lCurrPos = dictWbListCurrPos(sActiveWbName)
For i = lCurrPos - 1 To dictNavigate.Keys(0) Step -1
If Not dictNavigate.Exists(i) Then GoTo next_pos
sRgAddr = dictNavigate(i)
sWb = Replace(Replace(Split(sRgAddr, "]")(0), "[", ""), "'", "")
sSheet = Replace(Split(Split(sRgAddr, "]")(1), "!")(0), "'", "")
If sWb <> sActiveWbName Then GoTo next_pos
If fSheetExists(sSheet, , Workbooks(sWb)) Then
If sSheet = Workbooks(sWb).ActiveSheet.Name Then
dictNavigate.Remove (i)
GoTo next_pos
Else
lNextPos = i
Exit For
End If
Else
dictNavigate.Remove (i)
End If
next_pos:
Next
fNavigateStackNextPositionToMoveBack = lNextPos
End Function
Function fNavigateStackNextPositionToMoveForWard(Optional ByRef sWb As String, Optional ByRef sSheet As String) As Long
Dim lCurrPos As Long
Dim lNextPos As Long
Dim sRgAddr As String
Dim sActiveWbName As String
Dim i As Long
lNextPos = 0
If dictNavigate.Count <= 0 Then Exit Function
sActiveWbName = ActiveWorkbook.Name
lCurrPos = dictWbListCurrPos(sActiveWbName)
If lCurrPos >= dictNavigate.Keys(dictNavigate.Count - 1) Then Exit Function
For i = lCurrPos + 1 To dictNavigate.Keys(dictNavigate.Count - 1)
If Not dictNavigate.Exists(i) Then GoTo next_pos
sRgAddr = dictNavigate(i)
sWb = Replace(Replace(Split(sRgAddr, "]")(0), "[", ""), "'", "")
sSheet = Replace(Split(Split(sRgAddr, "]")(1), "!")(0), "'", "")
If sWb <> sActiveWbName Then GoTo next_pos
If fSheetExists(sSheet, , Workbooks(sWb)) Then
If sSheet = Workbooks(sWb).ActiveSheet.Name Then
dictNavigate.Remove (i)
GoTo next_pos
Else
lNextPos = i
Exit For
End If
Else
dictNavigate.Remove (i)
End If
next_pos:
Next
fNavigateStackNextPositionToMoveForWard = lNextPos
End Function
Sub subMain_NavigateBack()
Dim lNextPos As Long
Dim sWb As String
Dim sSheet As String
lNextPos = fNavigateStackNextPositionToMoveBack(sWb, sSheet)
If lNextPos > 0 Then
Application.EnableEvents = False
Workbooks(sWb).Activate
Workbooks(sWb).Worksheets(sSheet).Visible = xlSheetVisible
Workbooks(sWb).Worksheets(sSheet).Activate
Application.EnableEvents = True
dictWbListCurrPos(sWb) = lNextPos
lLastPosBeforeManualActive = lNextPos
End If
Call RefreshRibbonControl("btnBack")
Call RefreshRibbonControl("btnForward")
End Sub
Sub subMain_NavigateForward()
Dim lNextPos As Long
Dim sWb As String
Dim sSheet As String
lNextPos = fNavigateStackNextPositionToMoveForWard(sWb, sSheet)
If lNextPos > 0 Then
Application.EnableEvents = False
Workbooks(sWb).Activate
Workbooks(sWb).Worksheets(sSheet).Visible = xlSheetVisible
Workbooks(sWb).Worksheets(sSheet).Activate
Application.EnableEvents = True
dictWbListCurrPos(sWb) = lNextPos
lLastPosBeforeManualActive = lNextPos
End If
Call RefreshRibbonControl("btnBack")
Call RefreshRibbonControl("btnForward")
End Sub
|
|