1. Home
  2. /
  3. Docs
  4. /
  5. Articles Report Writer
  6. /
  7. Report Functions
  8. /
  9. Cached Value Functions

Cached Value Functions

GetCachedValue

Looks up a value from a cached query. The query runs once per report and is stored in memory — subsequent calls use the cached result with no database round-trip. Use this for any denormalized or unpivoted data that multiple rows need to reference.


Function Signature

function GetCachedValue(
  QueryName    : String;   // TfrxFDQuery component name on the report
  KeyField     : String;   // field name to search on
  ValueField   : String;   // field name to return
  KeyValue     : Variant;  // value to search for — any type
  ConnDef      : String;   // FDManager connection definition name
  DefaultValue : Variant   // returned if key not found
): Variant;
ParameterTypeDescription
QueryNameStringExact name of the TfrxFDQuery component on the report (case-sensitive)
KeyFieldStringThe field to search on — must exist in the query result
ValueFieldStringThe field whose value is returned when a match is found
KeyValueVariantThe value to search for — can be String, Integer, Date, etc.
ConnDefStringFDManager connection definition name (e.g. ‘Sage50_Live’)
DefaultValueVariantReturned if no matching row is found

How It Works

  • On the first call for a given QueryName and ConnDef, the function opens the TfrxFDQuery, copies the results into a memory table, and caches it.
  • On every subsequent call it uses the cached memory table — no SQL is executed again.
  • The cache is shared across all rows in the report, so even if GetCachedValue is called thousands of times, the database query only runs once.
  • The cache is automatically cleared when the report is saved in the designer, ensuring SQL changes take effect on the next run.

Setting Up the Query Component

  1. In the Articles designer, drop a TfrxFDQuery component onto the report.
  2. Give it a clear name — e.g. QTaxFlags, QShippers, QPeriods.
  3. Enter the SQL in the SQL property. The query should return two columns: a key column and a value column.
  4. Leave the component inactive (Active = False) — GetCachedValue opens it automatically.
  5. Save the report before running — the function reads the SQL from the saved report file.

Examples

Example 1 — Sales Tax Flags

Sage 50 stores tax authority flags as columns (Taxable1 through Taxable27) in General_AR. The query unpivots them into rows so you can look up whether a given tax authority is taxable.

Query SQL on component QTaxFlags:

SELECT 1 AS TaxNum, Taxable1 AS Taxable FROM General_AR WHERE AcctgModule = 1
UNION ALL SELECT 2,  Taxable2  FROM General_AR WHERE AcctgModule = 1
UNION ALL SELECT 3,  Taxable3  FROM General_AR WHERE AcctgModule = 1
-- continue through 27
UNION ALL SELECT 27, Taxable27 FROM General_AR WHERE AcctgModule = 1

Articles script — OnBeforePrint of detail band:

var V: Variant;
V := GetCachedValue('QTaxFlags', 'TaxNum', 'Taxable',
                     <JrnlRow."TaxAuthorityCode">, 'Sage50_Live', -1);
if V = -1 then
  MemoTax.Text := 'Unknown'
else if Integer(V) <> 0 then
  MemoTax.Text := 'Taxable'
else
  MemoTax.Text := 'Non-Taxable';

Example 2 — Shipper Names

Sage 50 stores shipper names as columns (Shipper1 through ShipperN). Unpivot them the same way to get a name from a numeric code.

Query SQL on component QShippers:

SELECT 1 AS ShipCode, Shipper1 AS ShipName FROM General_AR WHERE AcctgModule = 1
UNION ALL SELECT 2, Shipper2 FROM General_AR WHERE AcctgModule = 1
UNION ALL SELECT 3, Shipper3 FROM General_AR WHERE AcctgModule = 1

Articles script:

var V: Variant;
V := GetCachedValue('QShippers', 'ShipCode', 'ShipName',
                     <JrnlRow."ShipCode">, 'Sage50_Live', 'Unknown');
MemoShipper.Text := VarToStr(V);

Example 3 — Period End Dates

Look up a fiscal period end date by period number. Returns the date as a Variant — use VarToDateTime to format it.

Query SQL on component QPeriods:

SELECT 1 AS PeriodNum, PeriodEnd1 AS PeriodEnd FROM FiscalYear WHERE Year = :Year
UNION ALL SELECT 2, PeriodEnd2 FROM FiscalYear WHERE Year = :Year
UNION ALL SELECT 3, PeriodEnd3 FROM FiscalYear WHERE Year = :Year

Articles script:

var V: Variant;
V := GetCachedValue('QPeriods', 'PeriodNum', 'PeriodEnd',
                     <JrnlRow."Period">, 'Sage50_Live', Now);
MemoDate.Text := FormatDateTime('mm/dd/yyyy', VarToDateTime(V));

Example 4 — String Key Lookup

The key does not have to be numeric. You can look up by any string value — for example a department code.

Query SQL on component QDepartments:

SELECT DeptCode, DeptName FROM Departments

Articles script:

var V: Variant;
V := GetCachedValue('QDepartments', 'DeptCode', 'DeptName',
                     <Employee."DeptCode">, 'Sage50_Live', 'No Department');
MemoDept.Text := VarToStr(V);

Choosing a DefaultValue

Use caseSuggested DefaultValue
Numeric flag (0/1)-1 — clearly not a valid flag value
Name or description‘Unknown’ or ‘Not Found’
Date0 or Now
BooleanFalse
Amount or quantity0

Important Notes

  • Save the report before running. The function reads the SQL from the saved .fr3 file. If you change the SQL and do not save, the old SQL will be used.
  • Leave the query component inactive. Set Active = False on the TfrxFDQuery. The function opens and closes it automatically.
  • QueryName is case-sensitive. It must exactly match the component name in the Articles designer.
  • Multiple connections are supported. The same query component can be used with different ConnDef values — each combination is cached separately.
  • The cache is per report run. It starts fresh each time the report runs and is cleared when the report is saved in the designer.
  • Key matching is case-insensitive for string keys — ‘fedex’ and ‘FedEx’ will match the same row.

Quick Reference

TopicDetail
Function nameGetCachedValue
ParametersQueryName, KeyField, ValueField, KeyValue, ConnDef, DefaultValue
Return typeVariant — any type
Query runsOnce per QueryName + ConnDef combination per report run
Query component typeTfrxFDQuery — must be on the report, set inactive
Key matchCase-insensitive for strings
Not foundReturns DefaultValue
Multiple connectionsSupported — cached separately per ConnDef