Skip to content

Instantly share code, notes, and snippets.

@goswinr
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goswinr/f178ccb2ca5e4e019f9b to your computer and use it in GitHub Desktop.
Save goswinr/f178ccb2ca5e4e019f9b to your computer and use it in GitHub Desktop.
Update for Ribbon menu with ExcelDna and F#
// typos fixed in:
// http://bramjochems.com/blog/2014/05/creating-ribbon-menu-exceldna-f/
module RibbonBuilder =
// http://bramjochems.com/blog/2014/05/creating-ribbon-menu-exceldna-f/
type RibbonButtonSize =
| Large
| Medium
| Small
type RibbonButtonCallbackType =
| AddinCallBack
| RunMacro of macroname : string
type RibbonButton =
{ id : string;
label : string;
size : RibbonButtonSize;
image : string Option;
callback : RibbonButtonCallbackType;
screentip : string option;
supertip : string option }
type RibbonGroup =
{ id : string;
label : string;
buttons : RibbonButton list }
//module RibbonBuilder =
[<Literal>]
let startString = @"<customUI xmlns='http://schemas.microsoft.com/office/2009/07/customui' loadImage='LoadImage'><ribbon><tabs>"
[<Literal>]
let endString = @"</tabs></ribbon></customUI>"
// Helper function to create a reoccuring string pattern
let private createHelperString field value =
match value with
| None -> " "
| Some(v) -> field + "='" + v + "' "
// Creates the xml required for a single button on the ribbon
let private createButtonXml (button : RibbonButton) =
let buttonOpeningString = @"<button "
let buttonCloseString = @"/>"
let idString = createHelperString "id" (Some(button.id))
let labelString = createHelperString "label" (Some(button.label))
let sizeString = match button.size with
| Large -> "large"
| Medium-> "medium"
| Small -> "small"
|> Some
|> createHelperString "size"
let imageString = createHelperString "image" button.image
let callBackString = match button.callback with
| AddinCallBack -> createHelperString "onAction" (Some("OnButtonPressed"))
| RunMacro(tag) -> createHelperString "onAction" (Some("RunTagMacro")) +
createHelperString "tag" (Some(tag))
let screentipString = createHelperString "screentip" button.screentip
let supertipString = createHelperString "supertip" button.supertip
buttonOpeningString + idString + labelString + sizeString + imageString + callBackString + screentipString + supertipString + buttonCloseString
// Creates the xml for a group on the ribbon
let private createGroupXml (group : RibbonGroup)=
let groupStartString = @"<group id='" + group.id + @"' label='" + group.label + @"'>"
let groupEndString = @"</group>"
let buttonString = group.buttons |> List.fold (fun acc el -> acc + createButtonXml el) ""
groupStartString + buttonString + groupEndString
// creates an xml string that defines a ribbon with a single tab
let buildRibbon (tabId, tabLabel) (ribbonGroups : RibbonGroup list)=
let tabStartString = @"<tab id='" + tabId + @"' label='" + tabLabel + @"'>"
let tabEndString = @"</tab>"
let groupString = ribbonGroups |> List.fold (fun acc el -> acc + createGroupXml el) ""
startString + tabStartString + groupString + tabEndString + groupString
//================================
// Usage :
//================================
module buttonsIds =
[<Literal>]
let First = "A"
[<Literal>]
let Second = "B"
open ExcelDna.Integration.CustomUI
open RibbonBuilder
//[<ComVisible(true)>] // not needed ??
type MyRibbonC() =
inherit ExcelRibbon()
member x.OnButtonPressed(control:IRibbonControl) =
match control.Id with
| buttonsIds.First -> System.Windows.Forms.MessageBox.Show "Hello from A!" |> ignore // Insert desired logic her
| buttonsIds.Second-> System.Windows.Forms.MessageBox.Show "Hello from B!" |> ignore // Insert desired logic here
|_ -> System.Windows.Forms.MessageBox.Show "Hello from FFail!" |> ignore // or fail...
override x.GetCustomUI(uiname) =
let buttonA = {
id="A";
label="A Lable";
size = Large;
image = None;
callback = AddinCallBack;
screentip = Some("Button A action");
supertip = None }
let buttonB = {
id="B";
label="Button B";
size = Medium;
image = None;
callback = AddinCallBack;
screentip = Some("Button B action");
supertip = None }
RibbonBuilder.buildRibbon ("myTab", "ExcelDna Ribbon Tab") [{ id = "group1"; label = "Group name"; buttons = [buttonA; buttonB] }]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment