October 22, 2026

YSR vs. SSRS vs. Power BI for Yardi Custom Reports: How to Choose

Ask three different Yardi admins how to build a custom report and you'll get three different answers: write a YSR script, build an SSRS report, or just pull it into Power BI. All three are legitimate answers. None of them are the right answer in every case — they're different tools built for different output shapes, and the choice that saves you an afternoon is the one that matches the tool to what the report actually needs to look like.

Here's what each one actually is, grounded in how Voyager's own report engine treats them.

YSR: script-driven, columnar by default

A Voyager custom report is a single plain-text script, registered under an rs_-prefixed name, built from a flat sequence of //Section ... //End Section blocks — //Notes, //Title, //Select, //Columns, //Filter, and a handful of others depending on what the report does. The section that actually decides what kind of report you're building is //Database: leave it empty and you get Voyager's built-in columnar grid, driven entirely by the //Columns section — one comma-delimited row per output column, with type codes, header labels, widths, totals, and drill-down links into Voyager entity screens.

This columnar style is the current, encouraged default for on-screen grid and export output — rent rolls, directories, aging reports, financial registers. It's the fastest path from "I need this data as rows and columns" to a working report, because the layout is the //Columns spec — there's no separate designer file to maintain, and the whole report lives in one script you can version and diff.

YSR isn't limited to grids, either. The same script format, with a different //Database value, drives document-style output: FillDocs for Word mail-merge documents (invoices, contracts, letters — with repeating //GRID blocks bound to merge-field tables in a .docx template), and an Excel-template engine for workbook output bound via &=DATASET.Field tokens in an .xlsx file. What ties all of this together is the authoring model: you write SQL in named //Select datasets, tokens like #conditions# get spliced in from whatever the user filtered on, and the rendering target is whichever engine //Database points at.

SSRS: a different authoring model, not just a different look

Set //Database to 'SSRS <name>.rdlc' and the whole authoring model shifts. The script's job changes from defining the layout to feeding data into a layout defined somewhere else — the .rdlc file. Each //Select [Name] block becomes a named dataset that binds to an identically-named dataset in the RDLC report, and it's common for a substantial document — a lease abstract report is a good example of the shape — to carry a dozen or more named datasets covering different sections of the layout (charges, schedules, options, clauses, contacts).

Once you're in SSRS mode, //Columns goes vestigial — it's no longer driving anything, because column placement, formatting, and pagination live in the .rdlc layout file, not the script. //Filter keeps doing exactly what it does in columnar reports: it owns all the runtime prompting and token generation, and one shared filter section can drive every dataset in the report through numbered condition slots. A lot of SSRS reports in a typical Voyager install are migrations from an older Crystal Reports generation, and you can usually tell — they still carry a //Crystal parameter block configuring renderer-level parameters and locale masks, a naming holdover from the engine they used to target.

The practical upshot: SSRS is what you reach for when the output has to be pixel-perfect and paginated — a formatted statement, a regulatory filing, a document where column widths, page breaks, and exact placement matter in a way a grid report doesn't need to care about. It costs you a second file to maintain (the .rdlc layout alongside the script) and a steeper authoring curve, in exchange for layout control a columnar grid was never built to give you.

Where Power BI fits — a different job entirely

Power BI (and similar BI/analytics layers some Voyager installs connect for dashboarding) isn't really competing with YSR or SSRS for the same job. Both YSR and SSRS are Voyager's native, per-report authoring surface: you write a script, it runs against live Voyager data, it produces one specific report — a rent roll, a statement, an aging analysis — usually on demand or on a schedule, usually for one property or one owner at a time.

A BI tool is typically pointed at a broader extract or feed and used for exploratory, cross-property analytics and dashboards — trend lines, portfolio-level rollups, self-serve slicing that isn't tied to a single predefined report shape. That's a genuinely different use case, not a fancier version of the same one. If what you need is "this specific formatted report, correct down to the column," a BI dashboard is usually the wrong tool even when it's technically capable of showing the numbers, because you'd be rebuilding report-specific formatting logic in a tool designed for open-ended exploration instead of using the engine built for exactly that shape of output.

How to choose

The decision comes down to what the output actually needs to be:

Getting this wrong doesn't usually mean the report fails outright — it means someone spends a week fighting a columnar grid into pixel-perfect submission, or hand-rolling pagination logic that SSRS gives you for free, or building a one-off dashboard for a report that a five-section YSR script would have produced in an afternoon.

Where PropETL fits

Picking the right engine is only half the job — the other half is knowing which tables and columns actually hold the data your report needs, and how they join. That's what the PropETL SQL Query Assistant carries: a queryable knowledge base of the standard Voyager schema — 9,793 tables, 137,000+ columns, 12,900+ relationships — alongside the report-writing knowledge itself, including the //Columns and //Filter grammars, #token# substitution, and sanitized script skeletons by category, all queryable in plain English inside Claude.

It's included in every tier, including the free 7-day trial. See what it knows about report authoring and schema discovery on the SQL Assistant page.

Featured on FoundrListFeatured & Verified on TrustMRRPropETL on PeerPushLaunchpadly Startup DirectoryPropETL — Featured on LaunchBuck