---
id: object/codeunit/9665
type: object
title: Codeunit 9665 "Composite Layout Lookup Helper"
summary: Codeunit 9665 "Composite Layout Lookup Helper" in Base Application (Microsoft.Foundation.Reporting). 15 public procedures. Introduced in BC29, still in BC30.
tier: official
language: en
tags:
  - codeunit
  - base application
versions:
  introduced: "29"
  last_changed: null
  deprecated: null
review:
  state: derived
  by: null
  at: null
  flags: []
generated:
  at: "2026-10-11T00:31:51.816Z"
  pipeline: 0.2.0
  prompts: {}
  input_hash: ff0b314c3a06ea4e33b8d75f66094001e592a01e8f056754f611bd0f992b4e70
evidence:
  - kind: code
    url: https://github.com/microsoft/BCApps/blob/ea08af5ef2d6a9b5c5af4a029288abbe2c883220/src/Layers/W1/BaseApp/Foundation/Reporting/CompositeLayoutLookupHelper.Codeunit.al
    title: src/Layers/W1/BaseApp/Foundation/Reporting/CompositeLayoutLookupHelper.Codeunit.al (releases/29.x)
    date: null
    commit: ea08af5ef2d6a9b5c5af4a029288abbe2c883220
    t: null
    quote: null
links:
  learn: []
  objects: []
  features: []
  topics: []
  localizations: []
  videos: []
  posts: []
  guidelines: []
  changes:
    - change/bcapps/10134
object_type: codeunit
object_id: 9665
name: Composite Layout Lookup Helper
namespace: Microsoft.Foundation.Reporting
app: Base Application
extends: null
first_version: "29"
last_version: "30"
present_in:
  - "29"
  - "30"
changed_in: []
source_major: "29"
obsolete: null
countries: []
ms_search_form_ids: []
counts:
  fields: 0
  procedures: 17
  events: 0
  subscribers: 0
relations:
  out: 0
  referenced_by: 0
  pages: 0
  extended_by: 0
  event_subscribers: 0
  calls: 0
  called_by: 11
  implements: 0
---

# Codeunit 9665 "Composite Layout Lookup Helper"

> Codeunit 9665 "Composite Layout Lookup Helper" in Base Application (Microsoft.Foundation.Reporting). 15 public procedures. Introduced in BC29, still in BC30.

Base Application · Microsoft.Foundation.Reporting · BC29-30 · [source at ea08af5e](https://github.com/microsoft/BCApps/blob/ea08af5ef2d6a9b5c5af4a029288abbe2c883220/src/Layers/W1/BaseApp/Foundation/Reporting/CompositeLayoutLookupHelper.Codeunit.al) · facts from BC29

## Properties

| Property | Value |
|---|---|
| Access | Internal |
| Permissions | tabledata "Tenant Report Layout Cfg" = RIMD |

## Procedures

- `LookupCompositePart(Subtype: Enum "Report Layout Subtype"; var Composite: Text): Boolean`: Opens the Report Themes and Header/Footers registry as a lookup filtered to the given subtype. Non-approved parts (Draft, Pending Approval, Retired) are shown so they can be reviewed, but only an approved part may be picked: selecting a non-approved part raises an error and nothing is returned. On a...
- `DecodeLayoutName(CompositeName: Text): Text`: Returns the plain layout name embedded in a composite reference. Returns the input unchanged when no :: separator is present so legacy or hand-edited values still display sensibly.
- `DecodeAppId(CompositeName: Text): Guid` (internal): Returns the application ID embedded in a composite reference (the &lt;guid&gt; before the :: separator). Returns an empty GUID when there is no separator or the segment is not a valid GUID, so callers can fall back to matching by name alone.
- `CountPartAssignments(PartLayout: Record "Report Layout List"): Integer`: Counts how many Tenant Report Layout Cfg entries currently assign the given part (matched by its composite reference in the Header Part Name column for header/footer parts, or the Theme Part Name column for theme parts).
- `ClearPartAssignments(PartLayout: Record "Report Layout List"): Integer`: Clears every Tenant Report Layout Cfg assignment of the given part, blanking the composite reference in the Header Part Name column for header/footer parts, or the Theme Part Name column for theme parts. Call before deleting a part so no configuration is left pointing at — or able to silently re-bin...
- `EncodeCompositeName(AppId: Guid; LayoutName: Text): Text` (internal): Builds the canonical composite part reference (&lt;guid&gt;::&lt;layoutname&gt;) used to store and match header/footer and theme parts.
- `CompositeLayoutKey(LayoutRec: Record "Report Layout List"): Text`: Returns the platform Tenant Report Defaults report ID, under which reusable composite layout parts (themes and header/footer layouts) are stored so they can be assigned as defaults for any report.
- `IsBodyLayout(ReportID: Integer; LayoutName: Text): Boolean`
- `GetTenantReportDefaultsReportID(): Integer` (internal)
- `GetResolvedPartDisplays(ReportID: Integer; LayoutName: Text; var HeaderDisplay: Text; var HeaderSource: Text; var ThemeDisplay: Text; var ThemeSource: Text)`: Resolves the header/footer and theme parts that effectively apply to a report layout and reports both the part name and where it resolved from. Mirrors the platform resolver (Stage 2 of ReportLayoutSelection), walking the same six Tenant Report Layout Cfg precedence levels — most specific first — wi...
- `GetLayoutLevelPartDisplays(ReportID: Integer; LayoutName: Text; var HeaderDisplay: Text; var HeaderSource: Text; var ThemeDisplay: Text; var ThemeSource: Text; var HeaderResolved: Boolean; var ThemeResolved: Boolean)` (internal): Resolves the header/footer and theme parts assigned at the layout level (this report + this layout) — the two most specific precedence levels. Reports whether each part was resolved so the caller can fall back to the layout-independent report/global defaults only for the parts not assigned at the la...
- `GetReportLevelPartDisplays(ReportID: Integer; var HeaderDisplay: Text; var HeaderSource: Text; var ThemeDisplay: Text; var ThemeSource: Text)` (internal): Resolves the header/footer and theme parts from the layout-independent precedence levels: the report default (all layouts) and the company/global wildcard defaults. These do not depend on the body layout, so a page listing the layouts of a single report can resolve them once and reuse the result for...
- `GetCompanyDefaultDisplays(var HeaderDisplay: Text; var ThemeDisplay: Text)`: Returns the decoded company-default header/footer and theme part names (the Tenant Report Layout Cfg row with Report ID 0 and the current company), or empty when no company default is configured.
- `AssignCompanyDefaultPart(Subtype: Enum "Report Layout Subtype"; var Display: Text): Boolean`: Prompts the user to pick a part of the given subtype and stores it as this company's default (Report ID 0, empty layout, current company). Returns true and the decoded display name when a part was picked.
- `ClearCompanyDefaultPart(Subtype: Enum "Report Layout Subtype")`: Clears this company's default part of the given subtype, removing the configuration row when both parts are empty.

Plus 2 local procedures.

## Called by

From the extracted call graph of BC29 (graphify-al on the snapshot checkout): calls whose target is known from a declared type or an `Object::"Name"` argument. Interface dispatch and calls through events are not counted, so the list is not complete.

- [Page 9667 "Header/Footer Theme Assignment"](../page/9667.md) (9 calls: `DetectCompanyOverride → DecodeLayoutName`, `OnAfterGetCurrRecord → DecodeLayoutName`, `OnOpenPage → DecodeLayoutName`, …)
- [Page 9663 "Tenant Report Layout Cfg"](../page/9663.md) (8 calls: `OnAfterGetRecord → DecodeLayoutName`, `ScopeDescriptionFor → DecodeLayoutName`, `SetHeaderPart → DecodeLayoutName`, …)
- [Page 9666 "Report Theme and Header/Footer"](../page/9666.md) (6 calls: `CountAssignedInSelection → CountPartAssignments`, `CreateArtifact → GetTenantReportDefaultsReportID`, `DeleteSelectedArtifact → ClearPartAssignments`, …)
- [Page 9670 "Layout Theme and Header/Footer"](../page/9670.md) (4 calls: `ManageRow → CompositeLayoutKey`, `OnAfterGetRecord → CompositeLayoutKey`, `OnAfterGetRecord → GetLayoutLevelPartDisplays`, …)
- [Page 9652 "Report Layout Selection"](../page/9652.md) (3 calls: `ShowResolvedLayoutParts → CompositeLayoutKey`, `ShowResolvedLayoutParts → GetReportLevelPartDisplays`, `ShowResolvedLayoutParts → GetResolvedPartDisplays`)
- [Codeunit 9660 "Report Layouts Impl."](../codeunit/9660.md) (2 calls: `ValidatePartReference → DecodeAppId`, `ValidatePartReference → DecodeLayoutName`)
- [Page 9660 "Report Layouts"](../page/9660.md) (2 calls: `HasCompositePartReferences → EncodeCompositeName`, `OnDeleteRecord → ClearPartAssignments`)
- [Page 9669 "Report Layout FactBox"](../page/9669.md) (2 calls: `OnAfterGetRecord → CompositeLayoutKey`, `OnAfterGetRecord → GetResolvedPartDisplays`)
- [Page 1 "Company Information"](../page/1.md) (1 call: `OnOpenPage → GetCompanyDefaultDisplays`)
- [Page 9662 "Report Layout New Dialog"](../page/9662.md) (1 call: `OnOpenPage → GetTenantReportDefaultsReportID`)
- [Page 9664 "Tenant Report Layout Selection"](../page/9664.md) (1 call: `OnAfterGetCurrRecord → DecodeLayoutName`)

## Recent changes

- 2026-08-21 [#10134 [Bug 646487] Composite layout: focus fix, body-layout gating, and setup UI](../../changes/bcapps/10134.md) (main, BC30, fix)

## Across versions

- Present in: BC29-30
- Changed (declaration) in: none

Source: AL metadata extracted from the code (names, ids, signatures, properties); no code bodies (D10).

## Ask your agent

Procedure bodies are not stored here (D10). The call sections above are our own, per object, from the BC29 call graph. For a procedure body or the calls of one procedure, ask bc-code-atlas (external, by Stefan Maron, MIT; default corpus w1-28), which the bc-observatory plugin connects: `bcatlas_resolve_node(object_type: "codeunit", object_name: "Composite Layout Lookup Helper")`, then `bcatlas_get_procedure_body` or `bcatlas_get_neighbors` on the returned id.
