Skip to content

raknakae/TDataSetVisualizer4Delphi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

74 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TDataSetVisualizer4Delphi

🌐 English · Português (BR)

Delphi IDE Debug Visualizer to view a TDataSet descendant within a DBGrid.

📖 Full manual: MANUAL.en.md (English) · MANUAL.md (Português).

Installation (compile from source)

This project is distributed as source only — open the package for your Delphi version, Build and Install it (right-click the package in the Project Manager > Install):

Delphi version Package
Delphi 11 Alexandria, 12 Athens and newer Packages\D11Plus\dxIDEPackage.TDataSetVisualizer.dproj (uses {$LIBSUFFIX AUTO}, so one package serves all 11+ versions)
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 visualizer follows the IDE theme (light/dark) on Delphi 10.2+ when IDE theming is enabled. On older IDEs, or with theming disabled, it keeps its classic light palette with zebra striping, null-cell highlight and filter state colors.

Usage note: When this visualizer is used on a TDataSet expression, the debugger calls {Expression}.SaveToFile() to save the dataset to a temporary file, then creates a TDataSet descendant dataset based on the supported expression type (currently FireDAC and ClientDataSet) and then calls TempDataset.LoadFromFile() to retrieve the data.

ADO (dbGo) is not officially supported. ADO expressions fall back to the ClientDataSet loader, which cannot read ADO's persisted format, so the dataset may fail to load. Support is experimental at best — use FireDAC or ClientDataSet for reliable results.

This obviously means that you likely shouldn't use this visualizer on very large datasets, or those datasets which may contain privileged information. Perhaps less obvious, this also means for FireDAC applications, the dataset within your debugged executable needs to be able to support the .SaveToFile method which is enabled in FireDAC by including a unit that supports a particular TFDStanStorageXxxLink component within your application. In other words, if you get an error viewing a FireDAC dataset, a simple work around is to include "FireDAC.Stan.StorageBin" within a Uses clause of a unit within your debugged applcation. You likely will also have to include a call to the .SaveToFile method within your executable so the linker doesn't exclude it. When saving fails, the visualizer surfaces this exact guidance in an error message, so you don't have to recall it.

To keep the IDE responsive, the visualizer warns and asks for confirmation before loading a dataset whose temporary snapshot is larger than 10 MB, since materializing and scanning a very large dataset can freeze the IDE for a while.

Toolbar and tabs

The window has three tabs — DataSet Visualizer (the data grid), FieldDefs (the dataset's field definitions) and SQL (the originating command text, when available). 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) jump 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.

  • Record view shows the current row as a vertical Field/Value list (one field per line), DBeaver-style — handy for 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 show the current mode. Only visible columns are listed, NULLs show the (null) marker and binary BLOBs are summarized as (BLOB: n bytes).

  • Find searches within the active grid. On the data grid it offers two modes — Fields (match column names/labels) and Values (match cell contents) — and you step through matches with the ▲/▼ buttons or Enter / Shift+Enter; in Fields mode the located column's title is shown in bold. On the FieldDefs tab the same button opens a floating bar that narrows the field list by name.

  • Filter 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 live dataset arrives already filtered, the button starts pressed and the expression is reapplied so the grid mirrors the debugged rows.

  • Export names the file after the dataset expression (FieldDefs exports are tagged _FieldDefs). CSV uses the system list separator with RFC 4180 quoting; Markdown emits a GitHub-flavored table; JSON renders numbers, booleans and dates with appropriate types. On the SQL tab, Export saves the command text as a .txt file.

Inspecting and copying data

  • NULL vs empty string — null cells are drawn with a muted italic (null) marker, so you can tell a real NULL apart from an empty string at a glance. The (null) marker is display-only; it is never included when you copy or export. (The separate Highlight Null Cells toggle additionally tints the whole cell background.)
  • Current record marker — the row the live (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 live dataset is filtered, the mapping can be approximate, since the saved snapshot includes all records.)
  • Multi-row selection — the data grid allows multi-selection (Ctrl+click / Shift+click). The row-copy commands below copy the selected rows in dataset order; with no explicit selection they copy the current row.

Right-click the data grid to copy:

  • Copy cell (Ctrl+C) — the focused cell value.
  • Copy row(s) — a submenu that copies the selected (or current) rows in one of four formats: as CSV, as CSV (with headers), as Markdown, or as Markdown (with headers). CSV values are escaped per RFC 4180 and use the system list separator, so they paste cleanly into Excel; Markdown is handy for pasting into chats/issues or feeding data to an AI for inspection.
  • Copy column — every value of the selected column.

NULL values are copied as empty cells in every format.

The same right-click menu offers a few more actions:

  • Filter by this value — filters the grid to rows where the clicked column equals the clicked cell's value, revealing the filter box with the generated expression. Toggle the Filter button off (or press Esc in the grid) to clear it.
  • Column statistics... — pops 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/integer columns.
  • Show/hide columns — the Columns submenu lists every field with a checkmark to toggle its visibility, with Show All / Hide All shortcuts; Hide this column hides the clicked one, and Hide empty columns drops every column that has no data in any row. (Hiding all columns hides the grid until at least one is shown again.)

Saving and loading column layouts

The visualizer is recreated from scratch every time it opens, so any column tweaks you make (which columns are visible, how wide they are) are lost when the window closes. Because a debug session is transient — you might inspect a dataset of the same name in a completely different scenario next time — layouts are not persisted automatically. Instead, you save and load them on demand.

Right-click the data grid and use the Column Layout submenu:

  • Save Layout As... — saves the current column layout (visible fields and column widths) to a .dsvlayout file you name.
  • Load Layout... — applies a previously saved .dsvlayout file 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 not present in 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 as 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.

Demo

A sample project lives in Demo\DataSetDemonstration.dpr. It builds a random in-memory TClientDataSet (cdsData) you can inspect with the visualizer.

  1. With the visualizer package installed, open and run Demo\DataSetDemonstration.dpr from the IDE.
  2. 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.
  3. Optionally type a filter expression in the Filter box and tick Filtered to apply it to cdsData (the filter is re-applied after each Generate). This lets you exercise the visualizer's behavior when the inspected dataset arrives already filtered. Field names are randomized per generation, so write the expression against the names currently shown.
  4. To try the debugger visualizer, set a breakpoint on the cdsData.First; line in the btnRunClick method (unit uMain), then click Run!.
  5. When the breakpoint hits, inspect cdsData — for example add it to the Watch List (or hover over it) and choose TDataSet visualizer... from the debug-visualizer dropdown — to open the visualizer on the live dataset.

Icons

Toolbar icons from Material Design Icons by Pictogrammers, licensed under the Apache License 2.0.

Adding or changing a toolbar icon (developer note)

Toolbar glyphs are PNGs under Resources\Icons\, registered as RCDATA entries in Resources\icons.rc and compiled into Resources\icons.res, which is linked into the package by this directive in Source\dxTDataSetVisualizer.pas:

{$R '..\Resources\icons.res' '..\Resources\icons.rc'}

At runtime each glyph is loaded by its resource name with TResourceStream.Create(HInstance, '<NAME>_PNG', RT_RCDATA) (see LoadToolbarIcons). To add a new icon:

  1. Drop the PNG into Resources\Icons\.
  2. Add a line to Resources\icons.rc, e.g. FILTER_PNG RCDATA "Icons\Filter.png".
  3. Reference it from LoadToolbarIcons (AddFromResource('FILTER_PNG')) and set the new TToolButton's ImageIndex to match the load order.

⚠️ You must regenerate icons.res after editing icons.rc. The two-argument {$R res rc} form does not reliably recompile the .rc on an incremental build, so the package can link a stale .res and fail at runtime with Resource <NAME>_PNG not found even though the .rc looks correct. The committed .res is the source of truth at link time.

Regenerate it with the resource compiler that ships with Delphi (run from the Resources folder so the relative Icons\... paths resolve):

brcc32 -foicons.res icons.rc

brcc32.exe lives in the RAD Studio bin folder (e.g. C:\Program Files (x86)\Embarcadero\Studio\<ver>\bin\). Then do a full Build of the package (not just Compile) and reinstall. Commit the updated icons.res alongside the .rc change.

About

Delphi IDE debug visualizer to inspect any TDataSet descendant (ClientDataSet / FireDAC) in a rich DBGrid while stopped at a breakpoint.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors