I wouldn't expect 50 seconds for 46 controls, that is for sure.
I would suspect that the time is going on all of that initialisation stuff, down to GetObject.
I would suggest to set wsht and wksheet as public variables,having that code in a separate procedure, and have another Boolean variable that is tested to see whether the initialisation is done.
Something like, but not necessarily all of, this ...
Option Explicit
Public wsht As Excel.Workbook
Public wksheet As Excel.Worksheet
Public ExcelInitialised As Boolean
Sub RDB_getLabel(control As IRibbonControl, ByRef returnVal)
If Not ExcelInitialised Then Call ExcelConnect
returnVal = wsht.Application.VLookup(control.ID, wksheet.Range("rdbLabels"), 3, 0)
If Err.Number > 0 Then
returnVal = "Error"
Err.Clear
End If
On Error GoTo 0
End Sub
Sub RDB_getScreentip(control As IRibbonControl, ByRef returnVal)
If Not ExcelInitialised Then Call ExcelConnect
'etc.
End Sub
Public Function ExcelConnect()
Dim inifileloc2 As String
'Reads the location of the Office Details spreadsheet
VarPathLocal = Options.DefaultFilePath(wdUserTemplatesPath)
VarPathNetwork = Options.DefaultFilePath(wdWorkgroupTemplatesPath)
FullPath = VarPathLocal + "\" + "Office Details.xls"
FullPathNet = VarPathNetwork + "\" + "Office Details.xls"
If Dir(FullPath) <> "" Then
inifileloc2 = FullPath
ElseIf Dir(FullPathNet) <> "" Then
inifileloc2 = FullPathNet
Else
End If
On Error Resume Next
Set wsht = GetObject(inifileloc2)
Set wksheet = wsht.Worksheets("Letterhead")
ExcelInitialised = True
End Function
The other option would be to read them all into an array on that first connect and access the array, avoid the inter-op aside from the initial time.