How to Use Script UI Helpers
Tabular Editor provides helper methods for user interaction in scripts: displaying output, showing messages, prompting for object selection, evaluating DAX and building custom dialogs. In the desktop UI, these show graphical dialogs. In the CLI, they write to the console.
Quick reference
// Messages
Info("Operation completed."); // informational popup
Warning("This might take a while."); // warning popup
Error("No valid selection."); return; // error popup + stop script
Output("Hello"); // simple dialog
// Object selection dialogs (capture returns for reuse below)
var table = SelectTable(); // pick a table
var column = SelectColumn(table.Columns); // pick from filtered columns
var measure = SelectMeasure(); // pick a measure
var ds = SelectObject<DataSource>(Model.DataSources); // generic selection
var items = SelectObjects(Model.AllMeasures); // multi-select (TE3 only)
// Evaluate DAX
var result = EvaluateDax("COUNTROWS('Sales')"); // run DAX on connected model
// Output (uses the variables assigned above)
Output(measure); // property grid for a TOM object
Output(items); // list view with property grid
Output(result); // sortable/filterable grid for a DataTable
Messages: Info, Warning, Error
Use these for simple communication. Error() does not stop script execution by itself -- follow it with return if you want to halt.
if (Selected.Measures.Count() == 0)
{
Error("Select at least one measure before running this script.");
return;
}
// ... do work ...
Info("Updated " + Selected.Measures.Count() + " measures.");
Output
Output() behaves differently depending on the argument type:
| Argument type | Behavior |
|---|---|
TOM object (e.g., Measure) |
Property grid allowing inspection and editing |
IEnumerable<TabularNamedObject> |
List view with property grid |
DataTable |
Sortable, filterable grid |
| String or primitive | Simple message dialog |
Note
String output uses Windows line endings. Use \r\n or Environment.NewLine to insert line breaks. A bare \n renders on one line. This catches users out with M expressions, which use \n and print as a single line in Output().
DataTable for structured output
using System.Data;
var result = new DataTable();
result.Columns.Add("Measure");
result.Columns.Add("Table");
result.Columns.Add("Token Count", typeof(int));
foreach (var m in Model.AllMeasures)
{
result.Rows.Add(m.DaxObjectName, m.Table.Name, m.Tokenize().Count);
}
Output(result);
Tip
Specify typeof(int) or typeof(double) for numeric columns to enable correct sorting in the output grid.
Object selection dialogs
Selection helpers show a list dialog and return the user's choice. They throw an exception if the user cancels. Wrap them in try/catch.
try
{
var table = SelectTable(Model.Tables, null, "Select a table:");
var column = SelectColumn(
table.Columns.Where(c => c.DataType == DataType.DateTime),
null,
"Select a date column:"
);
Info($"You selected {table.Name}.{column.Name}");
}
catch
{
Error("Selection cancelled.");
}
Multi-select (Tabular Editor 3 only)
Note
SelectObjects() is only available in Tabular Editor 3. In Tabular Editor 2, use a single-select dialog in a loop or filter the selection before running the script.
SelectObjects() allows the user to pick multiple objects.
try
{
var measures = SelectObjects(
Model.AllMeasures.Where(m => m.IsHidden),
null,
"Select measures to unhide:"
);
foreach (var m in measures)
m.IsHidden = false;
}
catch
{
Error("No selection made.");
}
Evaluating DAX
EvaluateDax() executes a DAX expression against the connected model and returns the result.
var rowCount = Convert.ToInt64(EvaluateDax("COUNTROWS('Sales')"));
Info($"Sales table has {rowCount:N0} rows.");
// Return a table result
var result = EvaluateDax("ALL('Product'[Category])");
Output(result);
Note
EvaluateDax() requires an active connection to an Analysis Services or Power BI instance. It does not work when editing a model offline.
Guard clause patterns
Validate preconditions before the script runs.
// Require at least one column or measure
if (Selected.Columns.Count() == 0 && Selected.Measures.Count() == 0)
{
Error("Select at least one column or measure.");
return;
}
// Smart single-or-select pattern
DataSource ds;
if (Selected.DataSources.Count() == 1)
ds = Selected.DataSource;
else
ds = SelectObject<DataSource>(Model.DataSources, null, "Select a data source:");
Custom WinForms dialogs
For input scenarios beyond what the built-in helpers provide, build custom WinForms dialogs directly in the script. See How to Build Custom WinForms Dialogs in Scripts for patterns covering simple prompts, multi-field forms with validation and reusable dialog classes.