GetAttr(): Ribbon XML String-Building Helper Function
When you're building strings in code with lots of optional values--such as ribbon XML attributes--this simple function helps keep your code readable.
I build my custom Access ribbon interfaces by generating the ribbon XML entirely in code and then loading it at startup via Access's LoadCustomUI method.
To keep that approach manageable, I rely on several helper functions to build the XML strings. The GetAttr()
function is a simple function that handles the fact that ribbon XML nodes can have many attributes and most are optional.
For example, here is a list of available attributes for the button control:
description
/getDescription
enabled
/getEnabled
id
/idMso
/idQ
image
/imageMso
/getImage
/getImageMso
/showImage
/getShowImage
insertBeforeMso
/insertBeforeQ
/insertAfterMso
/insertAfterQ
keytip
/getKeytip
label
/getLabel
/showLabel
/getShowLabel
onAction
screentip
/getScreentip
size
/getSize
supertip
/getSupertip
tag
visible
/getVisible
Keeping Things Readable
Good programmers write computer-readable code.
Great programmers write human-readable code.
In my ribbon XML building class, I have a Button()
method with several optional parameters:
Public Sub Button(BtnImage As Variant, BtnCaption As String, _
CallbackFunction As String, _
Optional BtnSize As RibbonControlSize = RibbonControlSizeRegular, _
Optional getEnabledCallback As String = vbNullString, _
Optional getVisibleCallback As String = vbNullString, _
Optional IsToggleButton As Boolean = False, _
Optional KeyTip As String = vbNullString, _
Optional ScreenTip As String = vbNullString, _
Optional SuperTip As String = vbNullString)
'--== {unrelated code omitted for clarity} ==--
Const Delim As String = " "
Dim Attrs As String
Attrs = Conc(Attrs, GetAttr("getEnabled", getEnabledCallback), Delim)
Attrs = Conc(Attrs, GetAttr("getVisible", getVisibleCallback), Delim)
Attrs = Conc(Attrs, GetAttr("keytip", KeyTip), Delim)
Attrs = Conc(Attrs, GetAttr("screentip", ScreenTip), Delim)
Attrs = Conc(Attrs, GetAttr("supertip", SuperTip), Delim)
Debug.Print Attrs
'--== {unrelated code omitted for clarity} ==--
End Sub
Here's an example of how I might call this method (this is an excerpt from my standard report print preview ribbon):
Ribbon.Button "ExportExcel", "Excel", "rbExportToExcel", _
RibbonControlSizeRegular, _
KeyTip:="E", _
ScreenTip:="Export to Excel file", _
SuperTip:="(Requires Microsoft Excel)"
And here is the value of the Attrs
variable that gets output to the immediate window:
keytip="E" screentip="Export to Excel file" supertip="(Requires Microsoft Excel)"
What's most noteable about the above string is what's NOT there. The getEnabled
and getVisible
attributes are both missing from the above string, even though there were calls to both GetAttr("getEnabled", ...)
and GetAttr("getVisible", ...)
in the Button
method. That's because the getEnabledCallback
and getVisibleCallback
variables were both set to their default vbNullString
values.
The GetAttr()
function simply returns a null string if the attribute value passed to it is a zero-length string.
The Code
There's not much to see within the code for the GetAttr()
function itself. The real power is in how it combines with the Conc()
function to help generate highly-readable calling code as demonstrated above.
'---------------------------------------------------------------------------------------
' Procedure : GetAttr
' Author : Mike Wolfe
' Source : https://nolongerset.com/getattr-function/
' Date : 10/8/2015
' Purpose : Returns an attribute name=value pair if AttrVal is a non-zero-length string
' otherwise returns a null string.
'---------------------------------------------------------------------------------------
'
Function GetAttr(AttrName As String, AttrVal As String) As String
If Len(AttrName) = 0 Then Throw "Missing attribute name"
If Len(AttrVal) > 0 Then GetAttr = AttrName & "=" & Qt(AttrVal)
End Function
Dependencies
You'll need my Throw()
routine if you want to leave the guard clause in place as the first line of the function. You can always remove that line if you want, but I try to err on the side of programming defensively.
Image by Alfred Derks from Pixabay