AgentSkillsCN

c-sharp-macros

当用户提出“创建宏”、“编写 Tabular Editor 宏”、“将脚本保存为宏”、“编辑 MacroActions.json”、“自动化 TE3 动作”或提及 Tabular Editor C# 宏时,应运用此技能。为在 Tabular Editor 3 中创建、编辑和管理 C# 宏提供指导。

SKILL.md
--- frontmatter
name: c-sharp-macros
description: This skill should be used when the user asks to "create a macro", "write a Tabular Editor macro", "save a script as macro", "edit MacroActions.json", "automate TE3 actions", or mentions Tabular Editor C# macros. Provides guidance for creating, editing, and managing C# macros in Tabular Editor 3.

Tabular Editor C# Macros

Expert guidance for creating and managing C# macros in Tabular Editor 3 for Power BI semantic model development.

When to Use This Skill

Activate automatically when tasks involve:

  • Creating new macros from C# scripts
  • Editing or organizing existing macros
  • Understanding MacroActions.json structure
  • Setting up macro contexts and enabling conditions
  • Sharing macros across teams

Critical

  • Macros execute C# code with full model access - ensure scripts are safe before saving
  • Test scripts thoroughly in the C# Script pane before saving as macros
  • ValidContexts determines where macros appear in right-click menus
  • MacroActions.json is stored in %LocalAppData%\TabularEditor3

About Macros

  • Macros are saved C# scripts that can be reused across semantic models
  • They appear in right-click context menus based on ValidContexts
  • Macros can automate repetitive tasks like formatting DAX, creating measures, etc.
  • The Enabled expression controls when a macro is available

File Location

PlatformPath
Windows%LocalAppData%\TabularEditor3\MacroActions.json
ExpandedC:\Users\<Username>\AppData\Local\TabularEditor3\MacroActions.json

Note: There is only one macro file per user. Macros are not stored per-model or per-machine.

Sharing macros: To share macros across a team, export MacroActions.json and distribute via version control. Team members merge into their local file. Consider using symlinks for synchronized sharing.

Cross-Platform Access (macOS/Linux)

When working on macOS or Linux with Tabular Editor installed in a Windows VM:

Parallels on macOS:

code
/Users/<macUser>/Library/Parallels/Windows Disks/{VM-UUID}/[C] <DiskName>.hidden/

Full path to MacroActions.json:

  • <ParallelsRoot>/Users/<WinUser>/AppData/Local/TabularEditor3/MacroActions.json

Other platforms:

  • VMware Fusion - Check /Volumes/ for mounted Windows drives
  • WSL on Windows - /mnt/c/Users/<username>/AppData/Local/TabularEditor3/

Note: The VM must be running for the filesystem to be accessible.

Quick Reference

Macro JSON Structure

Macros are stored in MacroActions.json with an Actions array:

FieldRequiredTypeDescription
IdNointUnique identifier (use -1 for auto-assignment)
NameYesstringDisplay name (use \ for folder paths: Formatting\Format DAX)
EnabledNostringC# expression returning bool for when macro is enabled (default: "true")
ExecuteYesstringC# script code to execute
TooltipNostringTooltip text shown on hover
ValidContextsNostringContext(s) where macro appears in menus
json
{
  "Actions": [
    {
      "Id": 0,
      "Name": "Formatting\\Format DAX",
      "Enabled": "Selected.Measures.Any()",
      "Execute": "foreach(var m in Selected.Measures) { m.FormatDax(); }",
      "Tooltip": "Formats DAX for selected measures",
      "ValidContexts": "Measure"
    }
  ]
}

Valid Contexts

Contexts control where macros appear in the UI:

ContextDescription
ModelRoot model object
TableSingle table selected
TablesTables collection
MeasureSingle measure selected
ColumnSingle column selected
CalculatedColumnCalculated column
CalculatedTableCalculated table
HierarchyHierarchy object
LevelHierarchy level
PartitionTable partition
RelationshipRelationship object
RelationshipsRelationships collection
DataSourceData source object
DataSourcesData sources collection
RoleSecurity role
RolesRoles collection
RoleMemberRole member
PerspectivePerspective object
PerspectivesPerspectives collection
TranslationTranslation/culture
TranslationsTranslations collection
KPIKPI object
CalculationGroupCalculation group table
CalculationItemCalculation item
ExpressionNamed expression
ExpressionsExpressions collection
TablePermissionRLS table permission
PartitionCollectionPartitions of a table
FunctionsDAX UDFs
SingularObjectsAny single object
FolderOrSingularObjectFolder or single object

Multiple contexts: Use comma-separated values: "Table, Measure, Column"

Enabled Expressions

Common patterns for the Enabled field:

csharp
// Always enabled
"true"

// Only when measures are selected
"Selected.Measures.Any()"

// Only when a single table is selected
"Selected.Table != null"

// Only when columns exist
"Selected.Columns.Any()"

// Only for hidden measures
"Selected.Measures.Any(m => m.IsHidden)"

// Only when connected to a workspace
"Model.Database.Server != null"

Execute Script Patterns

Common Script Objects

csharp
// Selected object(s)
Selected.Measure      // Single measure (null if multiple/none)
Selected.Measures     // All selected measures
Selected.Table        // Single table
Selected.Tables       // All selected tables
Selected.Columns      // All selected columns

// Model access
Model                 // Root model object
Model.Tables          // All tables
Model.AllMeasures     // All measures in model
Model.Relationships   // All relationships

// Scripting helpers
Info("Message")       // Show info dialog
Warning("Message")    // Show warning
Error("Message")      // Show error
Output("text")        // Output to console

Example Scripts

Format all selected measures:

csharp
foreach(var m in Selected.Measures) {
    m.FormatDax();
}

Create SUM measures for selected columns:

csharp
foreach(var c in Selected.Columns) {
    var measure = c.Table.AddMeasure(
        "Sum of " + c.Name,
        "SUM(" + c.DaxObjectFullName + ")"
    );
    measure.DisplayFolder = "Auto-generated";
}

Hide all columns not used anywhere:

csharp
foreach(var c in Model.AllColumns.Where(c =>
    !c.IsHidden &&
    c.ReferencedBy.Count == 0 &&
    !c.UsedInRelationships.Any())) {
    c.IsHidden = true;
}

File Locations

FileLocationPurpose
MacroActions.json%LocalAppData%\TabularEditor3\Stores all macro definitions

Workflow

Creating a Macro

  1. Write and test your C# script in the Script pane
  2. Click "Save as Macro" in the toolbar
  3. Enter name (use \ for folders: Category\Name)
  4. Add tooltip description
  5. Select appropriate context(s)
  6. Save

Sharing Macros

  1. Export MacroActions.json from %LocalAppData%\TabularEditor3\
  2. Share with team via version control
  3. Team members merge into their MacroActions.json
  4. Consider using symlinks for synchronized sharing

Additional Resources

Reference Files

  • schema/macros-schema.json - JSON Schema for validating MacroActions.json (temporary location)

Scripts

  • scripts/validate_macros.py - Validate macro files for schema compliance

External References

Example Macros

Format Numeric Measures

json
{
  "Id": 0,
  "Name": "Formatting\\Format Numeric Measures",
  "Enabled": "Selected.Measures.Any()",
  "Execute": "foreach(var m in Selected.Measures.Where(m => string.IsNullOrEmpty(m.FormatString))) { m.FormatString = \"#,##0\"; }",
  "Tooltip": "Applies #,##0 format to measures without a format string",
  "ValidContexts": "Measure"
}

Create Calculation Group

json
{
  "Id": 1,
  "Name": "Create\\New Calculation Group",
  "Enabled": "true",
  "Execute": "var cg = Model.AddCalculationGroup(\"New Calculation Group\"); cg.AddCalculationItem(\"Default\", \"SELECTEDMEASURE()\");",
  "Tooltip": "Creates a new calculation group with a default item",
  "ValidContexts": "Model, Tables"
}