A family of Microsoft spreadsheet software with tools for analyzing, charting, and communicating data.
Hi, Jasuja, Om
I can help with both points, though the record mapping has a gap I can't close from public sources.
Record 3072. I couldn't find a published record-number table entry that ties 3072 to BrtUid. The BrtUid page (section 2.4.857) only defines the payload, a 16-byte GUID whose meaning depends on the record sequence it's in, and it gives no type value or version note. Mapping 3072 to BrtUid is a common convention in open-source XLSB parsers, not something the spec states. The SheetJS project ran into this same "unexpected record 3072" case back in 2018. They treated it as BrtUid as a best guess and flagged the missing table entry as a spec gap. For a read-only comparator, it is recommended that you treat 3072 as "probably BrtUid," show it as an opaque GUID, and not flag GUID-only differences as content changes. If you need an official ruling, you can contact the Open Specifications support team through the Support section of the Open Specifications Dev Center on Learn. Mention section 2.3 (Record Enumeration) and section 2.4.857. That team handles spec corrections and can confirm or add the entry.
PtgAttrIfError offset. I couldn't find any documented version-specific exception or alternative encoding where the offset is 3. Both the PtgAttrIfError and PtgAttrIf pages only say the offset is an unsigned byte offset. The actual rules are in the Rgce grammar (section 2.5.98.88), which measures offsets as EXPRESSION_SIZE.
The 7-byte reading also follows from how the jump works. When the first expression isn't an error, the evaluator skips past the fallback and the GoTo token, so it lands right on the IFERROR function token. With an offset of 3, it would land on the GoTo instead, and the GoTo would then jump past the function token. In that case IFERROR would never run.
Here's a quick way to check with a real file. Save =IFERROR(A1,0) as .xlsb and look at the formula bytes. You should see the A1 reference (7 bytes), then PtgAttrIfError (4 bytes, offset 7), then the integer 0 (3 bytes), then PtgAttrGoTo (4 bytes, offset 2), and finally the IFERROR PtgFunc (3 bytes, function number 480). That gives 3 + 4 = 7 for the PtgAttrIfError offset, and 3 - 1 = 2 for the GoTo.