CtrlK
BlogDocsLog inGet started
Tessl Logo

pyxll/pyxll-agent-skills

A curated collection of Agent Skills for working with PYXLL, to help AI agents write and understand code using the PyXLL Excel add-in.

99

1.56x
Quality

90%

Does it follow best practices?

Impact

100%

1.56x

Average score across 17 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

context-menus.mdskills/office-customui-xsd/resources/

Context Menus

PyXLL callback format: All callback values (onAction, getEnabled, etc.) must be module.function strings — e.g. onAction="context_menus.on_action". Examples below use abbreviated names for readability; use your actual module.function path.

Structure

<contextMenus>
  <contextMenu idMso="ContextMenuCell">
    <button id="myBtn" label="My Action" imageMso="RunMacro" onAction="OnMyAction"/>
    <menuSeparator id="sep1"/>
    <menu id="mySubMenu" label="More Options">
      <button id="opt1" label="Option 1" onAction="OnOpt1"/>
    </menu>
  </contextMenu>
</contextMenus>

contextMenu element

Each contextMenu targets a specific built-in context menu via idMso. You add controls to it; you cannot remove existing built-in items.

Attribute: idMso (required) — identifies which context menu to extend.

Common idMso values for Excel context menus:

idMsoWhen shown
ContextMenuCellRight-click on a cell
ContextMenuColumnRight-click on a column header
ContextMenuRowRight-click on a row header
ContextMenuSheetRight-click on a sheet tab
ContextMenuPivotReadRight-click in a pivot table
ContextMenuChartAreaRight-click on chart area
ContextMenuSeriesRight-click on a chart series
ContextMenuShapeRight-click on a shape
ContextMenuTextEditRight-click while editing text

Allowed controls in context menus

Context menus support a restricted set of controls (no editBox, comboBox, dropDown, box, buttonGroup, or labelControl):

ElementNotes
buttonStandard action button
checkBoxToggle state
toggleButtonToggle with image
galleryGrid picker
splitButtonButton + dropdown
menuSubmenu
dynamicMenuDynamically generated submenu
controlClone a built-in (by idMso or idQ only)
menuSeparatorHorizontal dividing line — no title attribute

Important: menuSeparator in context menus does NOT support a title attribute (unlike menuSeparator in ribbon menus which does). It only supports id, idQ, tag, and positioning attributes.

Positioning controls

Use insertAfterMso / insertBeforeMso to place your controls relative to existing items, or just append them (they appear at the bottom by default):

<contextMenu idMso="ContextMenuCell">
  <!-- Insert at top, before the built-in Cut -->
  <button id="myTop"
          label="My Action"
          insertBeforeMso="Cut"
          onAction="OnMyAction"/>

  <!-- Append at bottom with a separator -->
  <menuSeparator id="mySep"/>
  <button id="myBottom" label="My Bottom Action" onAction="OnMyBottom"/>
</contextMenu>

Example: cell context menu with submenu

<contextMenus>
  <contextMenu idMso="ContextMenuCell">
    <menuSeparator id="mySep"/>
    <menu id="myToolsMenu" label="My Tools" imageMso="ToolsMenu">
      <button id="tool1"
              label="Analyse Cell"
              imageMso="RunMacro"
              onAction="OnAnalyseCell"/>
      <button id="tool2"
              label="Format Cell Custom"
              imageMso="FormatCells"
              onAction="OnFormatCellCustom"/>
    </menu>
  </contextMenu>
</contextMenus>

Callbacks in context menus

All standard callbacks work in context menus. The control parameter passed to callbacks is the ribbon control object, which you can use to get the control's Id, Tag, etc.

def OnAnalyseCell(control):
    # do work using xl_app() to get context
    pass

def GetEnabled(control):
    # dynamically enable/disable based on current selection
    return True

README.md

tile.json