...
Note: A XBRL table might be designed such way to facilitate multiple ZAxis members, thus, a statement as model.ZAxesNodes.FirstOrDefault() will lead to dispersancy with underlying taxonomy.
Generate a table with predefined explicit Z-axis values
If a TableStructureModel has open Z axis members, the TableModelGenerator's PredefinedOpenAspectMembers property can be used to define values for each open Z axis node. The code snippet below demonstrates how to add such predefined values for a table with two open explicit Z-axis nodes.
Code Block | ||||
---|---|---|---|---|
| ||||
// Load the 3.0 Renumeration High Earners taxonomy.
string entryPoint = "http://www.eba.europa.eu/eu/fr/xbrl/crr/fws/rem/gl-2014-07/2021-02-28/mod/rem_he.xsd";
var processor = new Processor();
XbrlTaxonomy taxonomy = processor.ReadXbrlTaxonomy(entryPoint);
// Get the role for table R 04.00, which contains the data for generating the table.
string roleUri = "http://www.eba.europa.eu/xbrl/crr/role/fws/REM/gl-2014-07/2021-02-28/tab/R_04.00.a";
AbstractXbrlResolvedRoleType role = taxonomy.GlobalResolvedRoleTypesByUri[roleUri];
// Get the table hierarchy for table R 04.00, which defines the structure of the table.
TableResolvedTableHierarchy hierarchy = role.ResolvedTableHierarchies().First();
// Generate a table structure model based on the table hierarchy which is used as a template for actual tables.
TableStructureModel structureModel = hierarchy.GetResolvedStructureModels(null).First();
// Create a TableModelGenerator, which is responsible for generating actual tables based on table structure models.
var generator = new TableModelGenerator(taxonomy);
// The generator's GenerateTableLayoutModels method generates table models based on a fact container (usually an XBRL instance).
// Based on the fact container, cells/nodes with values for open nodes within the table structure model are added to the table model.
// In case of tables with open z axes, no table will be generated if no fact container is passed,
// because no value for the open z axes are present.
// However, it is possible to define values that should be added for open nodes on a specific axis.
// To do so, a set of predefined values is added to the generator's PredefinedOpenAspectMembers property.
// To identify the open nodes, their dimension names are used.
var paymentBandDimensionName = new XmlQualifiedName("PYB", "http://www.eba.europa.eu/xbrl/crr/dict/dim");
var eeaStateDimensionName = new XmlQualifiedName("HEL", "http://www.eba.europa.eu/xbrl/crr/dict/dim");
// Also the values have names which can be used to identify them.
// Below are the names of the values which should be added to the z axes.
var paymentBandDimensionMembers = new List<string> {"x5", "x6"};
var eeaStateDimensionMembers = new List<string> {"DE", "FR", "IT"};
// To get all open nodes on each z axis breakdown, iterate through each z axis breakdown.
foreach (Breakdown breakdown in structureModel.ZAxesBreakdowns)
{
// Now iterate through each open node in this breakdown.
// Usually there is only one open node per breakdown.
foreach (OpenAspectStructuralNode openNode in breakdown.OpenStructuralNodes)
{
// Each open node has a specific aspect type which defines what kind of value can be used for this open node.
// In case of table R 04.00, the node type is explicit dimension, i.e. there is a predefined list of valid values.
// Each valid value is an element within a certain dimension.
if (openNode.AspectType == AspectType.ExplicitDimension)
{
List<string> zAxisValuesToAdd;
if (openNode.Dimension == paymentBandDimensionName)
zAxisValuesToAdd = paymentBandDimensionMembers;
else if (openNode.Dimension == eeaStateDimensionName)
zAxisValuesToAdd = eeaStateDimensionMembers;
else
continue;
// Use GetAllExplicitMemberValueElementsWithDefault
// to get all valid values for an explicit dimension open aspect node.
List<Element> validValueElements = TableModelGenerator.GetAllExplicitMemberValueElementsWithDefault(openNode).ToList();
// Each predefined value is a structural node.
// All predefined values are be added to this list.
var predefinedValues = new List<StructuralNode>();
// Fill the predefinedValues list.
foreach (string valueToAdd in zAxisValuesToAdd)
{
// Try to find the element for the predefined value.
Element valueElement = validValueElements.FirstOrDefault(element => element.Name == valueToAdd);
if (valueElement == null)
continue;
// Each structural node has a constraint representing the value for a certain dimension.
var constraint = new ExplicitDimensionConstraint(
dimension: openNode.Dimension,
member: valueElement.QualifiedName,
isDefaultMember: taxonomy.GetDefaultMembersOfDimensions(openNode.Dimension).Contains(valueElement.QualifiedName));
// Create the node for the value and add it to the list of predefined values.
var node = new ExpandedExplicitDimensionNode(
openAspectNode: openNode,
parent: null,
constraints: new ConstraintList {constraint},
labels: valueElement.Labels);
predefinedValues.Add(node);
}
// Add the combination of open node and it's predefined values to the generator.
generator.PredefinedOpenAspectMembers.Add(openNode, predefinedValues);
}
}
}
// When generating the table models, there should be a table for each combination of all predefined z axis members.
// So six tables are generated in total (2 Payment Bands * 3 EEA States)
TableModelList tables = generator.GenerateTableLayoutModels(
breakdownModel: structureModel,
factContainer: null); |
Edit and View Modes
Ich denke, man müsste hier genauer erläutern, was die Table Modes bewirken. Einmal werden Typed Dimension Values nicht mehr gemerged (sodass die Zellen einzeln bearbeitbar sind) und die Header Cells werden ggf. anders dargestellt: es gibt einen HeaderRenderingMode der bestimmt, ob über den Typed Dimension Zeilen noch Header Zellen angezeigt werden sollen, die beschreiben, worum genau es sich bei diesem Typed Value handelt, z.B. "Lei Code" über der Spalte mit LEI-Codes.
...