Sachkonten, die in der Bilanz saldoabhängig dem Vermögen (Aktiva) oder den Schulden (Passiva) zugeordnet werden, nennt man Wechselkonten. Beispiele hierfür sind Bankkonten oder Konten für Krankenkassen. Dieser Beitrag zeigt eine Lösung zur dynamischen Abbildung von Wechselkonten in Microsoft Analysis Services zur Auswertung mit DeltaMaster.
Neulich im Neukunden-Workshop: Kurz nach der Mittagspause sind die Sachposten aus dem Vorsystem geladen, die Bilanzstruktur sauber dargestellt und die Salden einzelner Positionen in Stichproben positiv validiert. Der kaufmännische Leiter des Kunden lobt: „Das sieht schon sehr gut aus! Ah, da fällt mir noch ein Detail ein: Wir müssen die Wechselkonten berücksichtigen und entsprechend ihrem Saldo auf der Aktiv- oder Passivseite zeigen. Können Sie das noch einbauen?“ Aber natürlich!
Aufgabenstellung und Rahmenbedingungen
Aus dem ERP-System, einem Dynamics-NAV-Derivat, werden die Sachpostenbuchungen pro Tag, Kostenart/Sachkonto und Kostenstelle extrahiert und die ebenfalls im Vorsystem definierte Standard-Bilanzstruktur, die sich durch Verdichtung der Sachkonten ergibt, abgebildet. Die Buchung erfolgt stets auf dem ursprünglichen Konto (Basiskonto). Glücklicherweise führt das Vorsystem pro Sachkonto eine Eigenschaft „Wechselkonto“, sodass zumindest die Grundmenge bekannt ist, auf die die fachlich klar definierte Logik anzuwenden ist: Ist der Saldo von Wechselkonten, die grundsätzlich den Aktiva zugeordnet werden, negativ, wandern sie mit gedrehtem Vorzeichen in die Passiva. Beispielsweise stehen Bankkonten dann nicht mehr im Umlaufvermögen, sondern in den Verbindlichkeiten. Umgekehrt wandern Passivkonten mit negativem Saldo mit gedrehtem Vorzeichen in die Aktiva. Konten für Krankenkassen stellen dann nicht mehr Sonstige Verbindlichkeiten, sondern Forderungen und Sonstige Vermögensgegenstände dar. Diese im Kern simple Logik muss im BI-System zur Laufzeit, d. h. abhängig von der aktuell eingestellten Sicht/Filterung, angewendet werden.
Darüber hinaus ist in unserem Praxisfall zu beachten, dass die Bilanzsalden sich aufgrund der Speicherung im Vorsystem nur durch „Ewigkeitskumulation“ ergeben, also rückwirkende jahresübergreifende Aggregation aller Buchungen bis zum eingestellten Zeitpunkt/-raum. Eine relationale Vorberechnung per SQL im Data Warehouse kommt also nicht in Frage. Natürlich könnten zur Performanceoptimierung relational jahres- oder monatsweise Salden vorberechnet und vorzeichenabhängig dem Konto auf der Aktiv- oder Passivseite zugeschrieben werden; dadurch ginge jedoch die geforderte Dynamik eines Bilanzabrufs zum beliebigen Stichtag verloren. Außerdem müssten im Cube zusätzlich Sonderbehandlungen für Aggregation und Kumulation implementiert werden.
Lösungsansatz
Zunächst „doppeln“ wir die Wechselkonten in der Dimension Sachkonto/Kostenart. Hierzu selektieren wir in der V_IMPORT_DIM per UNION die betroffenen Konten basierend auf der oben genannten Eigenschaft erneut und versehen die ID mit einem Suffix (z. B. „-w“). In der Bilanzstruktur, in unserem Fall als separate Dimension modelliert, sortieren wir die Wechselkonten ebenfalls redundant, d. h. einmal mit und einmal ohne Suffix, und davon einmal auf der Aktiv- und einmal auf der Passivseite, an die jeweils gemäß Stammdaten korrekte Stelle ein. Um saldoabhängig – auch bei Aggregation/Kumulation – zu bestimmen, an welcher Position die Werte der betroffenen Wechselkonten anzuzeigen sind, dienen drei Berechnungsschritte per SCOPE im MDX-Cubeskript
Schritt 1: Ewigkeitskumulation/Bestand
CALCULATE;
SCOPE ( [Kumulation].[Kumulation].[Kumulation].&[2]
);
THIS = Aggregate( PeriodsToDate( [Periode].[Periode].[(All)],
[Periode].[Periode].CurrentMember
),
[Kumulation].[Kumulation].[Kumulation].&[1]
);
END SCOPE;
Schritt 2: Übernahme der Werte von den betroffenen Basiskonten (ohne Suffix) auf die Dummy-Konten (mit Suffix) inklusive Vorzeichendrehung
-- Wechselkontenlogik
-- 1) Dummy-Konto mit vorzeichengedrehtem Saldo beschreiben
SCOPE ( [Measures].[BilanzBetrag],
[Kumulation].[Kumulation].[Kumulation].&[2],
FILTER( [Kostenart].[Kostenart].[Sachkonto].Members,
RIGHT([Kostenart].[Kostenart].Properties("KEY"), 1) = "w")
);
THIS = IIF ( ( [Measures].[BilanzBetrag],
StrToMember('[Kostenart].[Kostenart].[Sachkonto].&[' + LEFT([Kostenart].[Kostenart].CurrentMember.Properties("KEY"), 6) + ']')
) < 0,
( [Measures].[BilanzBetrag],
StrToMember('[Kostenart].[Kostenart].[Sachkonto].&[' + LEFT([Kostenart].[Kostenart].CurrentMember.Properties("KEY"), 6) + ']')
) * -1,
null
);
END SCOPE;
Schritt 3: Ausnullen der betroffenen Basiskonten
-- 2) Ursprünglich bebuchtes Wechselkonto nullen
SCOPE ( [Measures].[BilanzBetrag],
[Kumulation].[Kumulation].[Kumulation].&[2],
FILTER([Kostenart].[Kostenart].[Sachkonto].Members,
[Kostenart].[Kostenart].Properties("Wechselkonto") = "1")
);
THIS = IIF ( ([Measures].[BilanzBetrag],
[Kostenart].[Kostenart].CurrentMember) > 0,
([Measures].[BilanzBetrag],
[Kostenart].[Kostenart].CurrentMember),
null
);
END SCOPE;
Vorteil der Lösung ist, dass die Bilanz so nicht zu definierten Stichtagen korrekt ausgewiesen wird, sondern volldynamisch mit beliebigen Filtereinstellungen (Jahr, Quartal, Monat, Tag) darstellbar ist. Etwas knifflig ist dabei einzig das Zerschneiden/Zusammensetzen der SachkontoIDs auf der Basis ihrer Properties.