79541162

Date: 2025-03-28 10:27:15
Score: 3.5
Natty:
Report link

Thank you for your comment and link, Timothy Rylatt. I couldn't get it to work with the link that you sent, but through it and some other searching I got to a solution that seems to work.

This is the new onLoad. It saves variable connected to the document. The delete is necessary for opening multiple times (based this on this page: MS guide for document varialbles)

Sub OnLoad(ribbon As IRibbonUI)
  Set myRibbon = ribbon
  Logic.OnLoad

  Dim lngRibPtr As Long
  lngRibPtr = ObjPtr(ribbon)

  ThisDocument.Variables("RibbonRef").Delete
  ThisDocument.Variables.Add Name:="RibbonRef", Value:=lngRibPtr
  MsgBox ThisDocument.Variables("RibbonRef").Value
  
End Sub

This is the refresh-function, I just call it when I want to invalidate anywhere.

Public Sub RefreshRibbon()
    If myRibbon Is Nothing Then
        If Not ThisDocument.Variables("RibbonRef") Is Nothing Then
            Set myRibbon = GetRibbon(ThisDocument.Variables("RibbonRef"))
            myRibbon.Invalidate
        End If
    Else
        myRibbon.Invalidate
    End If
End Sub

It calls on a special GetRibbon function that transforms the Long back to a IRibbonUI reference.

Public Function GetRibbon(ByVal lRibbonPointer As Long) As Object
    Dim objRibbon As Object
    CopyMemory objRibbon, lRibbonPointer, LenB(lRibbonPointer)
    Set GetRibbon = objRibbon
    Set objRibbon = Nothing
End Function

I based my solution mostly on this article: Lost state handling, Excel

It is however made for Word so I based my modifications on the comments in that article. It did not work since the "CopyMemory" that was used is not something inbuilt in VBA (at least my VBA was completely ignorant of it). So therefore I had to add a declaration of it at the top of my module. I found that here: CopyMemory-Function

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
            (lpDest As Any, lpSource As Any, ByVal cbCopy As Long)

Further sources that helped me along that could be of interest for someone still struggling:

https://answers.microsoft.com/en-us/msoffice/forum/all/ribbon-customization-invalidate-generates-error/7f202365-33b7-4c9c-a1ea-7ce8fe27c017

https://learn.microsoft.com/en-us/office/vba/api/office.documentproperties.add

What happens to the Word session ribbon after closing and reopening a document with a custom ribbon?

There is still an issue however in that every time I refresh, the "invalidate" line(s) generate the message "Argument not optional" (but since the ribbon gets invalidated and correctly updated, it clearly is optional... whatever it is). All examples that I have seen so far just use it on its own like I do here, so I have not been able to figure out what argument I am supposed to use.

Reasons:
  • Blacklisted phrase (0.5): Thank you
  • Blacklisted phrase (1): this article
  • Blacklisted phrase (1): did not work
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Oscar Danielsson