+ Reply to Thread
Results 1 to 5 of 5

Issue with sequence of events: Workbook_open, Workbook_sheetActivate, and custom Ribbon

Hybrid View

  1. #1
    Registered User
    Join Date
    01-23-2013
    Location
    Repentigny, Québec
    MS-Off Ver
    Excel 2013
    Posts
    15

    Issue with sequence of events: Workbook_open, Workbook_sheetActivate, and custom Ribbon

    Hi all,

    I created a custom ribbon which changes based on the worksheet based on information I got from Ron de Bruin. It took me sometime to figure it out as I kept getting an error which not directly related to the Ribbon customization per se.

    When the workbook is opened, everything works fine. The issue occurs when I open the workbook. Upon opening the workbook, I use Workbook_open to perform some actions in the workbook but I also use Workbook_SheetActivate to change the customized Ribbon on the fly.

    I believe the issue is that when workbook_open() is executed, the customized ribbon is not loaded yet. Upon opening the workbook, Rib = Nothing. Thus, my question is how can I handle the Workbook_SheetActivate to be executed after the workbook_open or similarly is there a way to force loading the customized ribbon as a first set in workbook_open().


    In This.Workbook:


    
    Private Sub Workbook_Open()
        Application.Calculation = xlAutomatic
        Application.TransitionNavigKeys = True
    
        ' SetZoom is simple macro for resetting the workbook sheets to 100% and to reset all sheets position to A1
        
        Call SetZoom
        
    End Sub
    
    
    Private Sub Workbook_SheetActivate(ByVal Sh As Object)
            
        Select Case Sh.name
            Case "Overview": Call ShowOverviewToC
            Case "Inputs - Gen, Efficacy, Safety": Call ShowGenInputsToC
            Case "Inputs - Utilities and Costs": Call ShowHUCostsToC
            Case "Inputs - PSA": Call ShowPSAInputsToC
            Case "Incremental Analysis": Call ShowIncAnalysisToC
            Case Else: Call HideEveryTabGroupControl
        End Select
        
        
    End Sub

    
    'Ribbon module code
    
    Option Explicit
    
    Dim Rib As IRibbonUI
    Public MyTag As String
    
    'Callback for customUI.onLoad
    Sub RibbonOnLoad(ribbon As IRibbonUI)
        Set Rib = ribbon
    End Sub
    
    Sub GetVisible(control As IRibbonControl, ByRef visible)
        If MyTag = "show" Then
            visible = True
        Else
            If control.Tag Like MyTag Then
                visible = True
            Else
                visible = False
            End If
        End If
    End Sub
    
    Sub RefreshRibbon(Tag As String)
        MyTag = Tag
        If Rib Is Nothing Then
            MsgBox "Error, Save/Restart your workbook"
        Else
            Rib.Invalidate
        End If
    End Sub
    
    'Note: Do not change the code above
    
    
    '*************************************************************************************************
    'Examples to show only the Tab, Group or Control you want with getVisible and tag in the RibbonX.
    '*************************************************************************************************
    
    
    Sub ShowDSAToC()
    
        Call RefreshRibbon(Tag:="ToC_DSA")
    End Sub
    
    
    Sub ShowOverviewToC()
    
        Call RefreshRibbon(Tag:="ToC_Overview")
    End Sub
    
    
    Sub ShowGenInputsToC()
    
        Call RefreshRibbon(Tag:="ToC_GenInputs")
    End Sub
    
    
    Sub ShowHUCostsToC()
    
        Call RefreshRibbon(Tag:="ToC_HUCosts")
    End Sub
    
    Sub ShowPSAInputsToC()
    
        Call RefreshRibbon(Tag:="ToC_PSAInputs")
    End Sub
    
    
    Sub ShowIncAnalysisToC()
    
        Call RefreshRibbon(Tag:="ToC_IncAnalysis")
    End Sub
    
    
    'Note: in this example every macro above will show you the custom tab.
    'If you add more custom tabs this will be different
    
    Sub HideEveryTabGroupControl()
    'Hide every Tab, Group or Control(we use Tag:="")
        Call RefreshRibbon(Tag:="")
    End Sub

    
    Public Sub SetZoom()
        
        Application.ScreenUpdating = False
        
        Dim ws As Worksheet
        
        For Each ws In Worksheets
            On Error Resume Next
            ws.Select
            ActiveWindow.Zoom = 100
            ActiveWindow.ScrollRow = 1
            ActiveWindow.ScrollColumn = 1
        Next ws
        
        Call tab_cover
        
    End Sub


    Kindest regards,

    Dominic.

  2. #2
    Forum Expert JLGWhiz's Avatar
    Join Date
    02-20-2011
    Location
    Florida, USA
    MS-Off Ver
    Windows 10, Excel 2013
    Posts
    2,070

    Re: Issue with sequence of events: Workbook_open, Workbook_sheetActivate, and custom Ribbo

    If you think it is a timing issue, have you tried inserting a delay at the begiinning of your ribbon code?
    w = Timer + 2
    Do While Timer < w
        DoEvents
    Loop
    This would give a 2 second delay before executing the rest of the code.

    Or as you alluded to in your post, call the ribbon sub from your Workbook_Open event.
    Last edited by JLGWhiz; 09-11-2020 at 03:54 PM.
    Any code provided by me should be tested on a copy or a mock up of your original data before applying it to the original. Some events in VBA cannot be reversed with the undo facility in Excel. If your original post is satisfied, please mark the thread as "Solved". To upload a file, see the banner at top of this page.
    Just when I think I am smart, I learn something new!

  3. #3
    Registered User
    Join Date
    01-23-2013
    Location
    Repentigny, Québec
    MS-Off Ver
    Excel 2013
    Posts
    15

    Re: Issue with sequence of events: Workbook_open, Workbook_sheetActivate, and custom Ribbo

    Quote Originally Posted by JLGWhiz View Post
    If you think it is a timing issue, have you tried inserting a delay at the begiinning of your ribbon code?
    w = Timer + 2
    Do While Timer < w
        DoEvents
    Loop
    This would give a 2 second delay before executing the rest of the code.

    Or as you alluded to in your post, call the ribbon sub from your Workbook_Open event.

    Thank you for your response! I will try this to check if it would have solved the problem. However, what I ended up doing was to create a global variable to control whether Workbook_open() is executed. This appears to be doing the trick.




    
    Option Explicit
    Public OpenWkb As Integer
    
    'General task at opening/closing of workbook
    
    Private Sub Workbook_BeforeClose(Cancel As Boolean)
        Application.Calculation = xlAutomatic
        
        'Call hideheadings
        'Call show_sheets_interface
        Call tab_cover
        
    End Sub
    
    Private Sub Workbook_Open()
        Application.Calculation = xlAutomatic
        Application.TransitionNavigKeys = True
        OpenWkb = 1
        
       
       Call ModelColorScheme
       Call SetZoom
           
       OpenWkb = 0
         
    End Sub
    
    
    
    
    Private Sub Workbook_SheetActivate(ByVal Sh As Object)
        If OpenWkb = 1 Then
            
            GoTo SheetExit
            
        Else
            
            Select Case Sh.name
                Case "Overview": Call ShowOverviewToC
                Case "Inputs - Gen, Efficacy, Safety": Call ShowGenInputsToC
                Case "Inputs - Utilities and Costs": Call ShowHUCostsToC
                Case "Inputs - PSA": Call ShowPSAInputsToC
                Case "Incremental Analysis": Call ShowIncAnalysisToC
                Case Else: Call HideEveryTabGroupControl
            End Select
            
        End If
        
    SheetExit:
        
    End Sub


    Kindest regards,

    Dominic.

  4. #4
    Forum Expert JLGWhiz's Avatar
    Join Date
    02-20-2011
    Location
    Florida, USA
    MS-Off Ver
    Windows 10, Excel 2013
    Posts
    2,070

    Re: Issue with sequence of events: Workbook_open, Workbook_sheetActivate, and custom Ribbo

    Thanks for the feedback,
    Regards, JLG

  5. #5
    Registered User
    Join Date
    01-23-2013
    Location
    Repentigny, Québec
    MS-Off Ver
    Excel 2013
    Posts
    15

    Re: Issue with sequence of events: Workbook_open, Workbook_sheetActivate, and custom Ribbo

    Hi all,

    This is a follow up on the issue which I is now fixed (so I believe). I wanted to create a ribbon that would update based on the worksheet activated. I faced two problems:
    1. 1. Upon opening the workbook, there were actions prior loading the ribbon which was issue
    2. 2. Any VBA code error caused an issue with the customized ribbon because Excel was losing the ribbon id


    I was able to fix first problem by creating a global variable as a flag. Nevertheless, this fix was not general enough. However, I was able to find a fix for the second one that was developed by RoryA (MrExcel MVP. Moderator) with a workbook made available by WernerGg. I cannot paste the link, but you can find the discussion by conducting a search for "How to preserve or regain the Id of my custom ribbon UI?"

    The basic idea is that Excel some times loses the ribbon id. The approach uses a cell in the workbook to store the ribbon id which can be used to refresh the ribbon. However, the solution proposed needed some tweaking because it requires to be updated for 64 bit version of Excel.


    Module ObjectStore


    Option Explicit
    Private Const C_OBJ_STORAGENAME As String = "thisWorkbook_IRibbonUI_Ptr"
    
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32" _
        Alias "RtlMoveMemory" (destination As Any, source As Any, ByVal length As Long)
    
    Public Function StoreObjRef(obj As Object) As Boolean
    ' Serialize and savely store an object reference
    
        StoreObjRef = False
        
        ' Serialize
        Dim longObj As LongPtr
        longObj = ObjPtr(obj)
        
        ' Store into a defined name
        If IsNumeric(Range(C_OBJ_STORAGENAME)) Then
            Range(C_OBJ_STORAGENAME) = longObj
            Debug.Print "Save storage """; C_OBJ_STORAGENAME; """ stored the object reference"; longObj
        End If
        
        ' Return
        StoreObjRef = True
    End Function
    
    Public Function RetrieveObjRef() As Object
    ' Retrieve from save storage, deserialize and return the object reference
    ' stored with StoreObjRef
    
        Set RetrieveObjRef = Nothing
        
        ' Retrieve from a defined name
        Dim longObj As LongPtr
        If IsNumeric(Range(C_OBJ_STORAGENAME)) Then
            longObj = Range(C_OBJ_STORAGENAME)
            MsgBox "Let's see if we are now ok with the ribbon."
            
            Debug.Print "Object reference"; longObj; "retrieved from save storage """; C_OBJ_STORAGENAME; """"
            
            ' Deserialize
            Dim obj As Object
            CopyMemory obj, longObj, 16
            
            ' Return
            Set RetrieveObjRef = obj
            Set obj = Nothing
        End If
    End Function
    
    Private Sub use_NameWithoutRef()
    ' Just demonstrate how a name with no reference would be used
    
        Const C_OBJ_STORAGENAME_NOREF As String = "foo"
        Dim aName As name, longObj As Long
    
        ' On each access check if the name exists.
        ' If not, create it with no reference to a cell and value 0
        With ThisWorkbook
            On Error Resume Next
            Set aName = .Names(C_OBJ_STORAGENAME_NOREF)
            On Error GoTo 0
            If aName Is Nothing Then
                Set aName = .Names.Add(name:=C_OBJ_STORAGENAME_NOREF, RefersTo:=0)
            End If
        End With
    
        ' store some Long under that Name
        longObj = Timer
        aName.Value = longObj   ' Value is "=4711"
        Debug.Print "Save storage """; C_OBJ_STORAGENAME_NOREF; """ stored the object reference"; longObj
        
        ' retrieve some Long from that Name
        longObj = Mid(aName.Value, 2)
        Debug.Print "Object reference"; longObj; "retrieved from save storage """; C_OBJ_STORAGENAME_NOREF; """"
    End Sub


    
    
    Option Explicit
    
    Dim Rib As IRibbonUI
    Public MyTag As String
    Public OpenWkb As Integer
    
    Private Const C_INTERRUPT As String = "thisWorkbook_Interrupt"
    
    
    'Callback for customUI.onLoad
    Sub RibbonOnLoad(ribbon As IRibbonUI)
        Set Rib = ribbon
        If Not StoreObjRef(Rib) Then Beep: Stop
    End Sub
    
    Sub GetVisible(control As IRibbonControl, ByRef visible)
        If MyTag = "show" Then
            visible = True
        Else
            If control.Tag Like MyTag Then
                visible = True
            Else
                visible = False
            End If
        End If
        
        
    End Sub
    
    Sub RefreshRibbon(Tag As String)
        MyTag = Tag
        
        ReloadRibbon
    
    End Sub
    
    
    
    Private Function ReloadRibbon(Optional id As String = "") As Boolean
    ' Force the ribbon UI to reload so that states are refreshed.
    ' This is done by an Invalidate or InvalidateControl(id)
    ' Returns True if successful
           
        
        ReloadRibbon = False
        
        ' Invalidate the ribbon UI so that everything gets reloaded
        If Not (Rib Is Nothing) Then
            ' Invalidate will force the UI to reload and thereby ask for current states
            If Len(id) > 0 Then
                Rib.InvalidateControl id ' Note: This does not work reliably
            Else
                Rib.Invalidate
            End If
            ReloadRibbon = True
            Exit Function
        Else
            ' The static guiRibbon-variable was meanwhile lost.
            ' We try to retrieve it from save storage and retry Invalidate.
            On Error GoTo GiveUp
            Set Rib = RetrieveObjRef()
            If Len(id) > 0 Then
                Rib.InvalidateControl id ' Note: This does not work reliably
            Else
                Rib.Invalidate
            End If
            On Error GoTo 0
            ReloadRibbon = True
            Exit Function
    GiveUp:
            MsgBox "Due to a design flaw in the architecture of the MS ribbon UI you have to close " & _
                "and reopen this workbook """ & ThisWorkbook.name & """." & vbNewLine & vbNewLine & _
                "Very sorry about that." & vbNewLine & vbNewLine & _
                "Clear the colored cell H2 on sheet IRibbonUI, save and close the workbook and try again. " & _
                "You will then have no problems anymore." _
                , vbExclamation + vbOKOnly, ThisWorkbook.name & ".ReloadRibbon"
            ' Note: In the help we can find
            ' Rib.Refresh
            ' but unfortunately this is not implemented.
            ' It is exactly what we should have instead of that brute force reload mechanism.
        End If
        
    End Function

    Kindest regards,

    Dominic.
    Last edited by dommit64; 10-26-2020 at 05:44 PM. Reason: The code did not appear properly tagged

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. [SOLVED] Worksheet_Activate & Workbook_SheetActivate events error 1004 when several sheets selected
    By Daishiknyte in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 04-05-2019, 05:39 PM
  2. [SOLVED] Application.Enable Events Property stopping Workbook_Open() Event
    By Sc0ut in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 02-07-2016, 05:09 PM
  3. Issue with Workbook_SheetActivate
    By KiwiRickToo in forum Excel Programming / VBA / Macros
    Replies: 5
    Last Post: 01-27-2016, 08:27 AM
  4. [SOLVED] An alternative to the Add-Ins ribbon tab - Global Custom Ribbon Tab by Ken Puls
    By mc84excel in forum Excel Programming / VBA / Macros
    Replies: 7
    Last Post: 09-16-2014, 10:01 PM
  5. Excel 2007 workbook_open events are not working
    By ljoseph in forum Excel General
    Replies: 1
    Last Post: 05-11-2010, 01:51 PM
  6. Using Workbook_AddinInstall -vs- Workbook_Open Events
    By Bill Schanks in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 12-23-2005, 12:25 AM
  7. Workbook_Open - Multiple Events not all working
    By Punsterr in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 10-06-2005, 03:05 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1