Skip to main content

Testing values

Velox integrations frequently move database, JSON, XML, file and script values through Variant. A Variant carries both a value and a type/state. Test that state before conversion; do not collapse Null, unassigned, empty text, zero and False unless the business rule explicitly treats them alike.

Core tests

The embedded PascalScript runtime directly registers the Delphi System.Variants routines VarIsNull, VarIsEmpty and VarIsClear:

TestTrue whenImportant distinction
VarIsNull(V)V contains the database/Automation Null valueNull is assigned but represents no value
VarIsEmpty(V)V is Unassigned (varEmpty)It has not been assigned a typed value
VarIsClear(V)V is undefined, including unassigned, a nil dispatch/interface value or a custom clear stateBroader than VarIsEmpty
V = ''A compatible value compares equal to an empty stringCan coerce and can fail or propagate Null for uncertain Variants
V = 0A compatible numeric/Boolean value compares equal to zeroZero can be a valid value
Boolean(V)V can be converted to BooleanIncompatible, Null or unassigned input can fail
procedure ScriptEvent(var Value: Variant);
begin
if VarIsNull(Value) or VarIsEmpty(Value) or VarIsClear(Value) then
Value := ''
else
Value := Trim(VarToStr(Value));
end;

The example is source-reviewed. It checks state before converting the assigned value to text. VarIsStr is a Delphi/Free Pascal routine but is not registered in the current Velox scripting surface, so do not use it as a guard unless a future Code Library entry exposes it.

Velox also registers convenience functions. IsNullorEmpty returns true for Null, Empty or Clear; for strings it trims before checking; it deliberately treats numeric zero as non-empty; for other types it converts to text and tests the trimmed result. IsNullorZero and field-specific helpers use different rules. Read their individual pages rather than substituting one name for another.

Database fields

Prefer a field's IsNull/Null capability when you are testing database null state. A field's empty text and its database NULL are not interchangeable. A required numeric field can validly contain zero, and a date value of zero has a defined Delphi date representation rather than automatically meaning “missing”.

When reading Field.Value, the result is a Variant and the core tests above apply. When writing, the dataset field type performs its own conversion and validation during assignment or posting.

Boolean control values

Map record events store their control flag in a Variant and the engine calls Boolean(Value). Assign an actual True or False. Avoid returning text such as 'false', an integer sentinel or Null; implicit conversion is runtime-dependent and can raise a Variant error.

The Velox helper CheckBoolean currently compares its Variant with Null and otherwise assigns the Variant to a Boolean result. For uncertain values, the explicit VarIsNull/VarIsEmpty/VarIsClear pattern is clearer and avoids relying on Variant comparison rules.

Common mistakes

  • Testing Value = Null. Variant Null comparisons do not behave like ordinary Boolean equality; use VarIsNull.
  • Using only VarIsEmpty when a nil interface/custom clear Variant is possible; VarIsClear is broader.
  • Treating 0 as absent without confirming the field/business rule.
  • Calling Trim, Length, Boolean or numeric conversion before excluding Null/unassigned states.
  • Assuming IsNullorEmpty treats zero as empty; its implementation explicitly does not.

Edge cases and quirks

  • VarIsClear differs slightly between Delphi and Free Pascal for interface/dispatch and custom Variant cases. Velox runs the Delphi routine; the Free Pascal pages are compatibility references.
  • Null can propagate through Variant expressions instead of producing a Boolean, which is why explicit tests are required.
  • An empty array or dataset is not an Empty Variant. Use its own length/count/EOF API.
  • Empty whitespace text is not equal to '', but Velox's IsNullorEmpty trims strings before testing.
  • ScriptEvent — general mutable Variant contract.
  • BeforeMap and AfterMap (Record) — Boolean control carried in a Variant.
  • Datasets — field null state and cursor emptiness.

External references