Skip to content

Template — Instance-Level Rule

Use this template as a starting point for rules that validate data on FamilyInstance objects: Mark, Level, Comments, and shared parameters that may live on either the instance or the type.

Copy the template, then adapt the configuration section at the top.


Template

(
  /* ── Configuration ─────────────────────────────────────── */

  $CategoryInclusion := ["OST_Doors", "OST_Windows"];

  $paramGuids := {
    "FireRating": "8fe8f5ce-4979-4679-b5e0-ccfb362b9059"
  };

  /* ── Parameter metadata index ───────────────────────────── */

  $paramMetaByGuid := $merge(
    $[type = "Parameter" and values.guid in $paramGuids.*].{
      $string(values.guid): {
        "guid": values.guid,
        "name": values.name
      }
    }
  );

  /* ── Shared parameter helper ────────────────────────────── */

  $getSharedParam := function($object, $logicalName) {(
    $guid := $lookup($paramGuids, $logicalName);
    $meta := $guid ? $lookup($paramMetaByGuid, $string($guid)) : undefined;
    $sp   := $guid and $exists($object.values)
             ? $lookup($object.values, "p_" & $guid)
             : undefined;
    {
      "paramExist": $exists($sp),
      "value":      $exists($sp) ? $sp.value : null,
      "hasValue":   $exists($sp) ? $sp.hasValue : false,
      "guid":       $meta ? $meta.guid : $guid,
      "name":       $meta ? $meta.name : $logicalName
    }
  )};

  /* ── Scope: loadable, non-in-place, model families ─────── */

  $familyIds := $[
    type = "Family"
    and values.isEditable = true
    and values.isInPlace = false
  ].id;

  /* ── Symbol scope ───────────────────────────────────────── */

  $symbolIds := $[
    type = "FamilySymbol"
    and parent.id in $familyIds
    and values.category.type = "Model"
    and values.category.label in $CategoryInclusion
  ].id;

  /* ── Build symbol lookup index ──────────────────────────── */

  $symIndex := $merge(
    $[type = "FamilySymbol" and id in $symbolIds].{
      $string(id): $
    }
  );

  /* ── Main query: FamilyInstances ────────────────────────── */

  $[type = "FamilyInstance" and parent.id in $symbolIds].(
    $sym := $lookup($symIndex, $string(parent.id));
    $sym ? {
      "id":          id,
      "type":        type,
      "name":        name,
      "mark":        values.mark,
      "assemblyCode": $sym.values.assemblyCode,
      "FireRating":  $getSharedParam($, "FireRating")
    } : ()
  )
)

What to adapt

Part What to change
$CategoryInclusion The categories this rule applies to
$paramGuids Add or remove shared parameters by logical name and GUID
Output fields Replace mark, assemblyCode, parameter calls with what the validator needs

What not to change

  • The Family scope conditions — correct defaults for all loadable family rules
  • The symbol index pattern ($symIndex) — this is the performant way to resolve type data per instance
  • The $sym ? { ... } : () guard — this skips instances whose type was not in scope, avoiding noise

If you do not need shared parameters

Remove $paramGuids, $paramMetaByGuid, and $getSharedParam. Keep the rest of the structure intact.


If you need Assembly Code scoping

Add to the FamilySymbol filter:

and $string(values.assemblyCode) ~> /^32\./

The symbol index will automatically carry only the in-scope symbols to the instance step.