🌐 English · Português (BR)
What it is: a Delphi IDE debug visualizer that lets you inspect any
TDataSetdescendant (includingTClientDataSetandTFDMemTable/FireDAC) in a rich DBGrid window while execution is paused at a breakpoint.It is a design-time-only package (BPL). There is no runtime component to install in your application.
Questions, suggestions or bug reports: open an issue on GitHub
- Installation
- How to use
- Tools (toolbar and tabs)
- Features
- Keyboard shortcuts
- Limitations and notes
- Demo project
- Contact
The project is distributed as source only. Installation is done entirely inside the Delphi IDE — there is no command-line build.
- Open the
.dproj(or.dpk) matching your Delphi version (see the table below). - In the Project Manager, right-click the package → Build.
- Then right-click again → Install.
After installation, the "TDataSet visualizer..." entry appears in the debugger's visualizer dropdown (Watch List / evaluation tooltip).
| Delphi version | Package |
|---|---|
| Delphi 11 Alexandria, 12 Athens and newer | Packages\D11Plus\dxIDEPackage.TDataSetVisualizer.dproj |
| Delphi 10.1 Berlin | Packages\D101Berlin\dxIDEPackage.TDataSetVisualizer.D240.dproj |
| Delphi 10 Seattle | Packages\D10Seattle\dxIDEPackage.TDataSetVisualizer.D230.dproj |
| Delphi XE7 | Packages\XE7\dxIDEPackage.TDataSetVisualizer.D210.dpk |
The D11Plus package uses
{$LIBSUFFIX AUTO}, so a single build serves all Delphi 11+ versions.
From Delphi 10.2 Tokyo onward (with IDE theming enabled), the visualizer follows the IDE theme (light/dark). On older IDEs, or with theming disabled, it keeps the classic light palette — with zebra striping, null-cell highlighting and filter-state colors.
| Define | Meaning |
|---|---|
DSV_IDE_THEMING |
Set automatically on Delphi 10.2+; enables the IOTAIDEThemingServices calls. |
SUPPORT_FIREDAC_DATASETS |
Includes FireDAC.Stan.StorageBin to register FireDAC's binary storage format. |
SUPPORT_ADO_DATASETS |
Includes the ADO units (experimental — ADO's persisted format is not readable by the CDS loader). |
SUPPORT_DATASNAP_DATASETS |
Includes DataSnap support. |
- With the visualizer package installed, set a breakpoint at a point where the dataset you want to inspect is open and populated.
- Run the application until it stops at the breakpoint.
- Inspect the dataset expression in one of these ways:
- Add it to the Watch List, or
- Hover over the variable to open the evaluation tooltip.
- In the debug visualizer dropdown, choose "TDataSet visualizer...".
- The visualizer window opens docked in the IDE, already showing the data in a grid, positioned on the current record of the debugged dataset.
When you trigger the visualizer on a TDataSet expression, the debugger calls {Expression}.SaveToFile() to write the dataset to a temporary file. The visualizer then creates a local dataset (a TClientDataSet by default, or TFDMemTable for FireDAC) and calls LoadFromFile() to load the copy (snapshot). The temporary file is deleted right afterwards.
Important: because the data is copied, avoid using the visualizer on very large datasets or ones that contain sensitive/privileged information.
The window has three tabs:
- DataSet Visualizer — the data grid.
- FieldDefs — the dataset's field definitions.
- SQL — the command text that produced the dataset, when available (the tab only appears if SQL is present).
A single toolbar at the top adapts to the active tab:
| Button | DataSet Visualizer | FieldDefs | SQL |
|---|---|---|---|
| Refresh (F5) | reloads the dataset | reloads the dataset | — |
| Auto-fit | fits the data grid columns | fits the FieldDefs columns | — |
| Find (Ctrl+F) | find bar over the data grid | filter bar over the FieldDefs grid | — |
| Filter | toggles the dataset filter box | hidden | hidden |
| Go to (Ctrl+G) | jumps to a record number | hidden | hidden |
| Record (Tab) | toggles grid ↔ single-record view | hidden | hidden |
| Highlight Nulls | tints null cells | hidden | hidden |
| Export | data → CSV/JSON/XML/Markdown | FieldDefs → CSV/JSON/XML/Markdown | command text → TXT |
A dash (—) means the button is disabled on that tab. Grid-only actions (Filter, Go to, Record, Highlight Nulls) are hidden away from the data grid; on the SQL tab the whole bar is disabled except Export.
Shows the current row as a vertical Field/Value list (one field per line), DBeaver-style — handy for very wide datasets. Toggle it with the Record button or by pressing Tab in the grid (Tab again, or the button, returns to the grid). The button's icon flips (grid ⇄ detail) to indicate the current mode. Only visible columns are listed; NULLs show the (null) marker and binary BLOBs are summarized as (BLOB: n bytes).
Searches within the active grid. On the data grid there are two modes:
- Fields — matches column names/labels (the located column's title is shown in bold).
- Values — matches cell contents.
Step through matches with the ▲/▼ buttons or with Enter / Shift+Enter. On the FieldDefs tab, the same button opens a floating bar that filters the field list by name.
Toggles the Search by Filter box: type a filter expression and press Enter to apply it (e.g. ESTAB = 1). Turning the button off deactivates the filter but keeps the text for next time. If the debugged dataset arrives already filtered, the button starts pressed and the expression is reapplied so the grid mirrors the same rows.
The row the debugged dataset is positioned on is tinted gold, and the grid opens scrolled to it. The marker is matched by record identity, so it keeps following that record even after you re-sort the grid by clicking column headers. (If the debugged dataset is filtered, the mapping can be approximate, since the saved snapshot includes all records.)
Null cells are drawn with a muted italic (null) marker, so you can tell a real NULL apart from an empty string. The (null) marker is display-only — it is never included when you copy or export. The Highlight Null Cells button additionally tints the whole cell background.
The grid allows multi-selection (Ctrl+click / Shift+click). Right-click the grid to copy:
- Copy cell (Ctrl+C) — the focused cell value.
- Copy row(s) — a submenu that copies the selected rows (or the current one) in one of four formats: CSV, CSV (with headers), Markdown or Markdown (with headers). CSV values are escaped per RFC 4180 and use the system list separator, pasting cleanly into Excel; Markdown is ideal for pasting into chats/issues or feeding an AI.
- Copy column — every value of the selected column.
In every format, NULL values are copied as empty cells.
- Filter by this value — filters the grid to rows where the clicked column equals the clicked cell's value, showing the filter box with the generated expression. Turn the Filter button off (or press Esc in the grid) to clear it.
- Column statistics... — opens a summary for the clicked column: total and null counts, plus type-appropriate stats — min/max/average for numbers, earliest/latest for dates, true/false tallies for booleans, and the most frequent value for text/integers.
- Show/hide columns — the Columns submenu lists every field with a checkmark to toggle visibility, with Show All / Hide All shortcuts; Hide this column hides the clicked one and Hide empty columns drops every column with no data in any row.
The file name is based on the dataset expression (FieldDefs exports get the _FieldDefs suffix). CSV uses the system list separator with RFC 4180 quoting; Markdown emits a GitHub-flavored table; JSON renders numbers, booleans and dates with the appropriate types. On the SQL tab, Export saves the command text as a .txt file.
The visualizer is recreated from scratch every time it opens, so column tweaks (which are visible, widths) are not persisted automatically. Instead, you save and load them on demand. Right-click the grid and use the Column Layout submenu:
- Save Layout As... — saves the current layout (visible fields and widths) to a
.dsvlayoutfile you name. - Load Layout... — applies a previously saved
.dsvlayoutfile to the current dataset. - Recent layouts — the last 10 saved/loaded files are listed for one-click reuse.
A layout is matched to the dataset by field name, so loading a layout still works when the field order differs between sessions; fields absent from the saved layout keep their current state. The recent-files list is stored in the Windows registry under HKEY_CURRENT_USER\Software\dxIDEPackage TDataSetVisualizer\RecentLayouts.
Note: column widths are saved in absolute pixels, so loading a layout on a monitor with a different DPI than the one it was saved on may scale the widths slightly.
When you select a memo or image (BLOB) field cell, a preview panel shows the text or the decoded image (JPEG, PNG, BMP and GIF are detected). The preview update is debounced, avoiding stalls when scrolling quickly between rows.
| Shortcut | Action |
|---|---|
| F5 | Reloads the dataset (Refresh) |
| Ctrl+F | Opens the find bar in the active grid |
| Ctrl+G | Jumps to a record number (Go to) |
| Tab | Toggles between grid and single-record view |
| Ctrl+C | Copies the focused cell |
| Enter / Shift+Enter | Next / previous match in the find bar |
| Esc | Clears the active filter in the grid |
The IDE consumes Ctrl+F, Ctrl+G and F5 before they reach the frame. The visualizer intercepts these keys at the message pump level and re-routes them — but only while focus is inside the visualizer frame.
-
Large datasets: above 10 MB in the temporary snapshot, the visualizer warns and asks for confirmation before loading, since materializing and scanning a very large dataset can freeze the IDE.
-
Sensitive data: because the data is copied to a temporary file, avoid using the visualizer on datasets with privileged information.
-
FireDAC: the debugged executable must support
.SaveToFile. If you get an error viewing a FireDAC dataset:- Include
FireDAC.Stan.StorageBinin ausesclause of your application. - Make sure there is a
.SaveToFilecall linked into the executable, so the linker does not strip the method.
When saving fails, the visualizer surfaces exactly this guidance in the error message.
- Include
-
ADO (dbGo): not officially supported. ADO expressions fall back to the ClientDataSet loader, which cannot read ADO's persisted format. Use FireDAC or ClientDataSet for reliable results.
A sample project lives in Demo\DataSetDemonstration.dpr. It builds a random in-memory TClientDataSet (cdsData) you can inspect with the visualizer.
- With the visualizer package installed, open and run
Demo\DataSetDemonstration.dprfrom the IDE. - Set the number of Records and Columns; optionally tick Add Memo Field, Add Image Field and/or Add random NULLs, then click Generate to (re)build the dataset. "Add random NULLs" scatters NULL values through the rows, so you can see the
(null)display and the null-cell highlight. - Optionally type a filter expression in the Filter box and tick Filtered to apply it to
cdsData(the filter is reapplied after each Generate). This exercises the visualizer's behavior when the inspected dataset arrives already filtered. Field names are randomized on each generation, so write the expression against the names currently shown. - To try the debug visualizer, set a breakpoint on the
cdsData.First;line in thebtnRunClickmethod (unituMain), then click Run!. - When the breakpoint hits, inspect
cdsData— for example add it to the Watch List (or hover over it) and choose TDataSet visualizer... from the visualizer dropdown — to open the visualizer on the live dataset.
Suggestions and bug reports are welcome: