Business Planning and Consolidation – Tipps und Tricks

BW Bewegungsdaten ins BPC laden

Der von SAP BPC verwendete Daten-Manager führt die Datentransformation und Zuordnung mittels Transformations- und Konvertierungsdateien durch. Mit der Transformationsdatei legen Sie Regeln fest, um die Daten zu lesen und zu konvertieren. Transformationsdateien sind Excel-Dateien, die ein Arbeitsblatt mit der Bezeichnung INSTRUCTIONS enthalten. Dieses ist in drei Abschnitte gegliedert:

  • den Optionsabschnitt mit Definitionen für verschiedene Optionen, die Sie für die Transformation festlegen können
  • den Zuordnungsabschnitt, der die Zuordnung von Daten definiert
  • den Konvertierungsabschnitt, in dem definiert wird, welches Konvertierungsblatt mit welcher Dimension verwendet werden soll

Anschließend wird die Transformationsdatei dem Data Package zugeordnet.

Optionen

In diesem Abschnitt können Sie die Optionen wie FORMAT, DELIMITER oder SELECTION festlegen. Sie können auch BAdI Implementierungen für UJD_ROUTINE nutzen (START_ROUTINE und END_ROUTINE). Dieser BAdI wird während der Transformation ausgelöst, wenn Daten aus einer externen Quelle geladen werden. Mit diesem BAdI können Sie komplexe Datentransformationen ausführen, die mit einer Transformationsdatei nicht möglich sind. Einem Überblick über die Optionsparameter können Sie dem Benutzerhandbuch für das EPM-Add-In entnehmen.
Die Optionen könnten wie folgt aussehen:

*OPTIONS
FORMAT = DELIMITED
HEADER = YES
DELIMITER = 
SKIP = 0
SKIPIF =
VALIDATERECORDS=YES
CREDITPOSITIVE=YES
MAXREJECTCOUNT=
ROUNDAMOUNT=
SELECTION=0VERSION,000;0CURTYPE,10

Zuordnung

Im Zuordnungsabschnitt der Transformationsdatei wird festgelegt, wie Daten zur Planning and Consolidation-Datenbank zugeordnet werden. Zum Beispiel:

ZVERSION=0VERSION

In diesem Abschnitt findet auch die Umwandlung von Kennzahlen- zum Kontomodell. Das so genannte „Kippen“ von Daten. Die Syntax dafür sieht wie folgt aus:

Dimension=*MVAL(keyfigure1|member1||keyfigure2|member2)

Für die Member werden mit der Funktion *NEWCOL neue Felder erstellt.
Zum Beispiel:

ZACCOUNT=*MVAL(0BALANCE|*NEWCOL(ZBALANCE)||0QUANTITY|*NEWCOL(ZQUANTITY))

Die Zuordnung könnte wie folgt aussehen. Dabei wird Currency Type fix auf LC gesetzt und leere (nicht zugeordnet bzw #) Sales Offices auf I_NON gesetzt. Diese werden später in der Konvertierung übersprungen. Außerdem wird das Datenmodell gekippt.

*MAPPING
CATEGORY=0VERSION
CURTYPE=*NEWCOL(LC)
ENTITY=*IF(ZSALE_OFF=*STR() THEN *STR(I_NON); ZSALE_OFF )
PRODUCT=0PRODUCT
TIME=0FISCPER
INPUTCURRENCY=0CURRENCY
P_ACCT=*MVAL(REVENUE|*NEWCOL(CE0002100)||DISCOUNT|*NEWCOL(CE0002200)||NETREVEN|*NEWCOL(CE0002300))

Konvertierung

Im Abschnitt *CONVERSION der Transformationsdatei wird festgelegt, welches Konvertierungsblatt mit welchen Dimensionen verwendet werden soll. Die Syntax sieht wie folgt aus

Dimension=[COMPANY]WorkbookName.xls[!SheetName]

Dabei sind die Parameter in eckigen Klammern optional. WorkbookName steht für den Namen der Konvertierungsdatei. SheetName ist der Name des in der Konvertierungsdatei zu verwendenden Arbeitsblatts. Dabei sollten Sie den Arbeitsblatt nach der jeweiligen Dimension benennen. Falls der Name nicht angegeben wurde, geht das System davon aus, dass der Blattname CONVERSION lautet. Wenn [COMPANY] definiert ist, versucht der Datenmanager, die Konvertierungsdatei vom Daten-Manager-Hauptordner des Unternehmens abzurufen. Andernfalls sucht der Daten-Manager im Ordner des entsprechenden Remote-Servers.
Der Konvertierungsabschnitt könnte die folgende Struktur haben:

*CONVERSION
CATEGORY=CONVERSION.XLS!CATEGORY
TIME=CONVERSION.XLS!FISCALYEARPERIOD
ENTITY=CONVERSION.XLS!ENTITY

Anbei die Beispiele der Arbeitsblätter der Konvertierungsdatei.
Conversion Sheet Category
Conversion Sheet Fiscal year
Conversion Sheet Entity

Data Package starten

Starten Sie das EPM Add-In und wechseln Sie in den Reiter Data Manager.
Legen Sie zunächst die Transformations- und die Konvertierungsdateien an. Transformation FileNew Transformationfile bzw. Conversion FilesNew Conversion File.
Selektieren Sie danach das Data Package /CPMB/LOAD_INFOPROVIDER.
Data Package Bewegungsdaten aus SAP NW laden
Geben Sie anschließend den Quell-InfoProvider an sowie die Transformationsdatei an.

Quellen

SAP Hilfe – Unterstützte BAdIs
SAP – Benutzerhandbuch für das EPM-Add-In

Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.

Denis Reis ist Business Intelligence Consultant bei Dahlbeer und gibt als Buchautor sein Wissen rund um den SAP Projektalltag weiter. Des Weiteren unterrichtet er Projektmanagement und Controlling an der Wiesbaden Business School. Der aus Düsseldorf stammende Familienmensch zählt zu denjenigen, die auf komplizierte Darstellungen verzichten und das Ganze auf den Punkt bringen.

How To BPC – Variablenübergabe an ScriptLogic DataPackages aus Excel

Die DataPackages, auch Berichtspakete genannt, haben sehr viele Parameter. So muss der Benutzer jedes Mal, wenn er eine Kopier-Funktion aufruft, festlegen wie die Datensätze gehandhabt werden, ob nach der Kopie die Standard-Script Logic ausgeführt werden soll. Danach wird er gefragt ob eventuelle Datensperren (Work Status) berücksichtigt werden sollen. Anschließend muss er die Quell- und die Zielwerte eingeben.

DataPackage - Eingabe der Werte

Quell- und Zielwerte definieren

Schließlich muss der User entscheiden, ob das DataPackage sofort oder später ausgeführt werden soll. Obwohl SAP damit wirbt, dass BPC sehr benutzerfreundlich ist, ist der durchschnittliche Fachbereich schnell überfordert. Falsch gesetzte Parameter können leicht zu unerwünschten Ergebnissen führen.
Nun könnten Sie das Standardpaket kopieren und das Skript so anpassen, dass die User es leichter verstehen.

Skript eines Pakets anpassen

DataPackage Skript ändern

Allerdings muss sich der User dann trotzdem durch mehrere Screens durchklicken, obwohl er einfach von einer Version in die andere kopieren will.
In diesem Beitrag zeige ich Ihnen eine elegantere Lösung. Der Benutzer kann die Quell- und Zielversion über Dropdowns auswählen und die Funktion über ein Button ausführen.

Versionen können über Dropdown ausgewählt werden

Unser Ziel

Der Weg dahin führt über mehrere Stationen. Neben unserer Tabelle mit der Auswahl haben wir eine Tabelle mit den Bereichen PARAMETERS und PACKAGE.
Der Bereich PARAMETERS enthält alle Parameter für die jeweilge Funktion mit den zugehörigen Werten.

PARAMETERS Bereich

PARAMETERS Bereich

Der Bereich PACKAGE enthält die Angaben zu der DataPackage die ausgeführt werden soll. Die SAP legt beim Aufruf eines DataPackages eine XML-Datei namens DMUserSelection.xml mit den Parametern an. Wir legen unsere eigene Datei für diese Zwecke an. Daher wird im PACKAGE Bereich auch der Name für die Datei angegeben, die die Werte für die Eingabeaufforderung (Prompt) enthält.

PACKAGE Bereich

PACKAGE Bereich

Über ein Button wird das VBA Makro aufgerufen, welches das in PACKAGE definierte DataPackage mit den in PARAMETERS definierten Parametern versorgt.

Zunächst legen den Bereich PARAMETERS für die Parameter an.
Das Standardpackage Copy erwartet folgende Parameter:

  • CLEARDATA – enthält 0 oder 1. Standardeinstellung ist 0.
  • RUNLOGIC – enthält 0 oder 1. Standardeinstellung ist 0.
  • CHECKLCK – enthält 0 oder 1. Standardeinstellung ist 1.
  • SELECTION – Dimensionen und Member die den Datenbereich der Quelle festlegen.
  • TOSELECTION – Dimensionen und Member die den Datenbereich des Ziels festlegen. Dimensionen werden über die Konstante DIMS festgelegt. Den Inhalt können Sie in Berichtspaketeinstellungen unter Konstanten sehen.
DataPackage Script

Einstellungen des Berichtspakets

Diese Informationen können Sie der jeweiligen Skriptdatei entnehmen. Gehen Sie dabei wie folgt vor.
Wählen Sie im EPM AddIn den Reiter Daten-Manager aus. Gehen Sie anschließend auf OrganisierenBerichtspaketliste organisieren.

Daten-Manager Pakete organisieren

Berichtspaketliste organisieren

Wählen Sie nun das Berichtspaket (DataPackage), in unserem Beispiel ist es Copy, mit Rechtsklick aus und wählen Sie Berichtspaket ändern aus.

DataPackage anpassen

Berichtspaket ändern

Wählen Sie anschließend Skript ändern aus und klicken Sie im folgenden Fenster oben rechts auf Erweitert.

DataPackage Skript anpassen

Skript des Berichtspakets ändern

Sie sehen nun das Skript für die Berichtspaket Prozesskette mit allen Parametern. Diese Parameter übernehmen wir in unseren Excel Bereich PARAMETERS.
Erstellen Sie im neuen Reiter eine Tabelle mit dem folgenden Aufbau.

Aufbau PARAMETERS

Aufbau von PARAMETERS

Die Promptnamen sollten mit denen im Skript übereinstimmen, inklusive %-Zeichen. Zum Beispiel %CLEARDATA%. Prompt Typ kann entweder ein Parameter (z.B. Ladeeinstellungen) oder StringListPairs (Variablen) sein. Dimensionen sind nur für StringListPairs relevant. Als Wert tragen Sie den Wert ein, den das jeweilige Merkmal annehmen soll. Diese können hardgecodet sein oder über Formeln auf Usereingaben beziehen.
Dabei können Sie EPM-Formeln oder auch ganz normale Excel-Bezüge nutzen. In unserem Beispiel beziehe ich mich auf die Dropdown-Felder.
Als nächstes legen wir einen Bereich an. Markieren Sie dazu alle Zellen (A1 bis D20). Tragen Sie in das Namenfeld oben links PARAMETERS ein und drücken Sie ENTER.

Bereich benennen

Bereich benennen

Wir haben nun erfolgreich einen Bereich für die Parameter erstellt.
Im nächsten Schritt legen wir den PACKAGE Bereich an. Die notwendigen Infos sind in der Tabelle UJD_PACKAGES2 abgelegt. Um an die notwendigen Informationen zu kommen müssen wir uns zunächst in SAP GUI einlogen. Rufen Sie anschließend die Transaktion SE16 (Data Browser) auf. Geben Sie UJD_PACKAGES2 als Tabellennamen an.

TA SE16 Data Browser

Data Browser

Geben Sie im nächsten Screen APPSET_ID (Ihre Umgebung) sowie die APP_ID (Ihr Model / Cube) ein und drücken Sie Ausführen (F8).
Sie sehen nun alle Berichtpakete für Ihren Cube. Suchen Sie nach der PACKAGE_ID Copy. Selektieren Sie die Zeile und drücken Sie auf Anzeigen (F7).

Inhalt der Tabelle UJD_PACKAGES2

Einträge der Tabelle UJD_PACKAGES2

Sie sehen nun alle Informationen die wir für den PACKAGE Bereich benötigen.

Informationen über das DataPackage

Details für den PACKAGE Bereich

Tragen Sie diese Infos in die Excel Tabelle nach dem folgenden Muster ein:

UJD_PACKAGES2 Feld Excel Feld Beispiel
CHAIN ID Filename /CPMB/COPY
GROUP ID GroupId Data Management
PACKAGE ID PackageDesc Copy
PACKAGE ID PackageId Copy
PACKAGE TYPE PackageType Process Chain
TEAM ID TeamID <leer>
USER GROUP UserGroup 0010

Beachten Sie dabei, dass das Feld UserGroup als vierstelliges Feld mit führenden Nullen eingetragen werden muss. Darüber hinaus beinhaltet das Feld PromptFile den Pfad für die Datei, die auf dem PC von allen Benutzern existieren muss. Zum Beispiel C:\DataManagerPromptFile.txt.
Legen Sie nun den PACKAGE Bereich an.

Wählen Sie nun die Felder aus (F1 bis G9), tragen Sie PACKAGE im Namensbereich ein und drücken Sie ENTER.

Im nächsten Schritt legen wir den Visual Basic Code an. Wie man ein VBA Makro anlegt beschreibe ich in dem Beitrag Excel VBA Grundlagen. In der Entwicklungsumgebung (ALT+F11), gehen Sie auf ExtrasVerweise (engl. ToolsReferences) und wählen Sie die folgenden Einträge aus.

VBA Referenzen

VBA Verweise

Legen Sie nun ein neues Modul an und fügen Sie das folgende Coding ein:

Public Sub executeDmPackageWithParameters()
' Create the Answer Prompt file in the location
' specified in the Name Range "PACKAGE"
createAnswerPromptFile "PACKAGE", "PARAMETERS"
' Get the DM Automation class instance
Dim objDMautomation As EPMAddInDMAutomation
Set objDMautomation = New EPMAddInDMAutomation
' Run the package specified in Excel Name Range "PACKAGE",
' using the promtp file specified in Name Range "PACKAGE"
objDMautomation.RunPackage objPackageFromSheet("PACKAGE"), _
strFilename("PACKAGE")
End Sub
Private Function strFilename(strRange As String) As String
' Get the range in which the DM package paramteres is set
Dim rngPackageRange As Range
Set rngPackageRange = Application.Names(strRange).RefersToRange
' Loop through the rows
For i = 1 To rngPackageRange.Rows.Count
If rngPackageRange(i, 1).Value = "PromptFile" Then
strFilename = rngPackageRange(i, 2).Value
Exit Function
End If
Next
End Function
Private Function strPackageDescription(strRange As String) As String
' Get the range in which the DM package paramteres is set
Dim rngPackageRange As Range
Set rngPackageRange = Application.Names(strRange).RefersToRange
' Loop through the rows
For i = 1 To rngPackageRange.Rows.Count
If rngPackageRange(i, 1).Value = "PackageId" Then
strPackageDescription = rngPackageRange(i, 2).Value
Exit Function
End If
Next
End Function
Private Function objPackageFromSheet(strRange As String) As ADMPackage
' Get the range in which the DM package paramteres is set
Dim rngPackageRange As Range
Set rngPackageRange = Application.Names(strRange).RefersToRange
' Create the ADM Package object
Set objPackageFromSheet = New ADMPackage
' Loop through the rows
For i = 1 To rngPackageRange.Rows.Count
Select Case rngPackageRange(i, 1).Value
Case "Filename"
objPackageFromSheet.Filename = rngPackageRange(i, 2).Value
Case "GroupId"
objPackageFromSheet.GroupId = rngPackageRange(i, 2).Value
Case "PackageDesc"
objPackageFromSheet.PackageDesc = rngPackageRange(i, 2).Value
Case "PackageId"
objPackageFromSheet.PackageId = rngPackageRange(i, 2).Value
Case "PackageType"
objPackageFromSheet.PackageType = rngPackageRange(i, 2).Value
Case "TeamId"
objPackageFromSheet.TeamId = rngPackageRange(i, 2).Value
Case "UserGroup"
objPackageFromSheet.UserGroup = rngPackageRange(i, 2).Value
End Select
Next
End Function
Private Sub createAnswerPromptFile(strPackageName As String, _
strParametersName As String)
' Create a new XML document
Dim objDOM As DOMDocument
Set objDOM = New DOMDocument
' Set the processing instruction of the XML document
Dim objProcessingInstruction As IXMLDOMProcessingInstruction
Set objProcessingInstruction = _
objDOM.createProcessingInstruction("xml", _
" version='1.0' encoding='utf-16'")
objDOM.appendChild objProcessingInstruction
' Create root element
Dim objRootElem As IXMLDOMElement
Set objRootElem = objDOM.createElement("ArrayOfAnswerPromptPersistingFormat")
objDOM.appendChild objRootElem
' XSI Attribute
Dim objMemberRel As IXMLDOMAttribute
Set objMemberRel = objDOM.createAttribute("xmlns:xsi")
objMemberRel.NodeValue = "http://www.w3.org/2001/XMLSchema-instance"
objRootElem.setAttributeNode objMemberRel
' XSD Attribute
Set objMemberRel = objDOM.createAttribute("xmlns:xsd")
objMemberRel.NodeValue = "http://www.w3.org/2001/XMLSchema"
objRootElem.setAttributeNode objMemberRel
' Get the range of cells containing the parameters
Dim rngParameters As Range
Set rngParameters = ThisWorkbook.Names(strParametersName).RefersToRange
'Excel.Names(strParametersName).RefersToRange
'
Dim objCurrentStringPairParent As IXMLDOMElement
' Loop through each row
For i = 1 To rngParameters.Rows.Count
' See which type of parameter is being passed
Select Case rngParameters(i, 2).Value
' If it is a single Parameter, then add a parameter node to the root node
Case "Parameter"
addSingleSelectionParameterToXML rngParameters(i, 1).Value, _
rngParameters(i, 4).Value, _
objRootElem, _
objDOM
' If it is a list of values
Case "StringListPairs"
' If it's a new set of String List Pairs, then create a new parent
If rngParameters(i, 1).Value <> strCurrentStringPair Then
strCurrentStringPair = rngParameters(i, 1).Value
Set objCurrentStringPairParent = _
getStringListPairParent(rngParameters(i, 1).Value, _
objRootElem, _
objDOM)
End If
' Add the Dimension Name and Value to the parent
addStringListPair rngParameters(i, 3).Value, _
rngParameters(i, 4).Value, _
objCurrentStringPairParent, _
objDOM
End Select
Next
' Create the File object
Dim objFile As FileSystemObject
Set objFile = New FileSystemObject
' Create a stream to create and write to the file
Dim objStream As TextStream
Set objStream = objFile.OpenTextFile(strFilename(strPackageName), _
ForWriting, True)
' Write the name of the DM package first and then the XML output
objStream.WriteLine strPackageDescription(strPackageName) & _
"{param_separator}" & _
objDOM.XML
' Close the file
objStream.Close
End Sub

Private Function addStringListPair(strVariableName As String, _
strValue As String, _
objParent As IXMLDOMElement, _
objDOM As DOMDocument)
' Create the "StringListPair" node
Dim objStringListPairElement As IXMLDOMElement
Set objStringListPairElement = _
objDOM.createElement("StringListPair")
objParent.appendChild objStringListPairElement
' Create the "Str" element containing the variable name
Dim objStrElement As IXMLDOMElement
Set objStrElement = objDOM.createElement("str")
objStringListPairElement.appendChild objStrElement
objStrElement.Text = strVariableName
' Create the "lst" element
Dim objLstElement As IXMLDOMElement
Set objLstElement = objDOM.createElement("lst")
objStringListPairElement.appendChild objLstElement
' Create the "string" element containing the variable value
Dim objStringElement As IXMLDOMElement
Set objStringElement = objDOM.createElement("string")
objLstElement.appendChild objStringElement
objStringElement.Text = strValue
End Function
Private Function getStringListPairParent(strVariableName As String, _
objParent As IXMLDOMElement, _
objDOM As DOMDocument) As IXMLDOMElement
' Create the "AnswerPromptPersistingFormat" node
Dim objAnswerPromptPersistingFormatElement As IXMLDOMElement
Set objAnswerPromptPersistingFormatElement = _
objDOM.createElement("AnswerPromptPersistingFormat")
objParent.appendChild objAnswerPromptPersistingFormatElement
' Create the "_ap" node
Dim objApElement As IXMLDOMElement
Set objApElement = objDOM.createElement("_ap")
objAnswerPromptPersistingFormatElement.appendChild objApElement
' Create the parameter name element
Dim objParameterElement As IXMLDOMElement
Set objParameterElement = objDOM.createElement("Name")
objApElement.appendChild objParameterElement
objParameterElement.Text = strVariableName
' Create the values element
Dim objValuesElement As IXMLDOMElement
Set objValuesElement = objDOM.createElement("Values")
objApElement.appendChild objValuesElement
' Create the "_apc" node
Set getStringListPairParent = objDOM.createElement("_apc")
objAnswerPromptPersistingFormatElement.appendChild getStringListPairParent
End Function

Private Function addSingleSelectionParameterToXML(strVariableName As String, _
strValue As String, _
objParent As IXMLDOMElement, _
objDOM As DOMDocument)
' Create the "AnswerPromptPersistingFormat" node
Dim objAnswerPromptPersistingFormatElement As IXMLDOMElement
Set objAnswerPromptPersistingFormatElement = _
objDOM.createElement("AnswerPromptPersistingFormat")
objParent.appendChild objAnswerPromptPersistingFormatElement
' Create the "_ap" node
Dim objApElement As IXMLDOMElement
Set objApElement = objDOM.createElement("_ap")
objAnswerPromptPersistingFormatElement.appendChild objApElement
' Create the parameter name element
Dim objParameterElement As IXMLDOMElement
Set objParameterElement = objDOM.createElement("Name")
objApElement.appendChild objParameterElement
objParameterElement.Text = strVariableName
' Create the values element
Dim objValuesElement As IXMLDOMElement
Set objValuesElement = objDOM.createElement("Values")
objApElement.appendChild objValuesElement
' Create the string element with the value passed to the parameter
Dim objStringElement As IXMLDOMElement
Set objStringElement = objDOM.createElement("string")
objValuesElement.appendChild objStringElement
objStringElement.Text = strValue
End Function

Legen Sie nun die Dropdowns und den Button für VBA an. Über diesen Button rufen Sie das Makro executeDmPackageWithParameters aus.
Das Datenpaket wird nun ausgeführt. Betrachten Sie den Status indem Sie auf Daten-ManagerStatus anzeigen gehen. Die Daten wurden erfolgreich kopiert.

Sie wissen nun wie Sie Standardfunktionen mit Variablen füttern können.
Betrachten wir im nächsten Schritt eigene Skript Logiken die über ein DataPackage ausgeführt werden. Da werden die Variablen zum Beispiel über PROMPT %CATEGORY_DIM% oder COMPCODE (Für Kundeneigene Dimensionen) angefordert, anschließend verwenden wir in der Logik %CATEGORY_SET%.
So sieht mein DataPackage aus

PROMPT(SELECTINPUT,,,,"%CATEGORY_DIM%,COMPCODE,SAORG")
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SUSER,%USER%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SAPPSET,%APPSET%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SAPP,PSX_PLAN)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SELECTION,%SELECTION%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,LOGICFILENAME,DIR_STRAT.LGF)

In meiner RUNALLOCATION ScriptLogic verteile ich die Planwerte anhand der Ist-Werte des Vorjahres.

*XDIM_MEMBERSET ACCOUNT = SAAMO
*XDIM_MEMBERSET CATEGORY = %CATEGORY_SET%
*XDIM_ADDMEMBERSET CATEGORY = ACTUAL
*XDIM_MEMBERSET COMPCODE = %COMPCODE_SET%
*XDIM_MEMBERSET SAORG = %SAORG_SET%
*XDIM_MEMBERSET SAOFF = 
*XDIM_MEMBERSET DICHA = 
*XDIM_MEMBERSET PRODH1 = 
*XDIM_MEMBERSET PRODUCT = 
*XDIM_MEMBERSET INPUTCURRENCY = EUR
*XDIM_MEMBERSET TIME = BAS(%YEAR%.TOTAL)
*XDIM_ADDMEMBERSET TIME = BAS(%YEAR%(-1).TOTAL)

*RUNALLOCATION
*FACTOR = USING/TOTAL

*DIM ACCOUNT         WHAT = SAAMO;    WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM CATEGORY        WHAT = %CATEGORY_SET%;      WHERE = <<<;       USING = ACTUAL;          TOTAL = <<<;
*DIM COMPCODE        WHAT = %COMPCODE_SET%;     WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM SAORG           WHAT = %SAORG_SET%;     WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM SAOFF           WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM DICHA           WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM PRODH1          WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM PRODUCT         WHAT = NONE;     WHERE = NONE;  USING = BAS(ALL);        TOTAL = <<<;
*DIM INPUTCURRENCY   WHAT = EUR;      WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM TIME            WHAT = BAS(%YEAR%.TOTAL); WHERE = <<<;       USING = BAS(%YEAR%(-1).TOTAL); TOTAL = <<<;

*ENDALLOCATION

Wenn ich nun diese ScriptLogic über ein DataPackage aufrufen will, muss ich die Variablen noch einmal eingeben. Das ist natürlich kein Zustand.

Variablenwerte müssen vom User ausgewählt werden

Auswahl der Variablen

Sie kennen jetzt einen Weg um dieses Problem zu lösen. Als erstes legen wir unseren PARAMETERS Bereich an.
Die Werte für die zu füllenden Variablen lesen wir mithilfe der EPM-Formel EPMContextMember aus.

Im nächsten Schritt legen wir den PACKAGE Bereich mit den Infos aus der Tabelle UJD_PACKAGES2 an.

PACKAGE Bereich für ScriptLogic

ScriptLogic PACKAGE Bereich

Als nächsten aktivieren wir die Verweise und legen ein Modul mit dem Coding an. Danach triggern wir das executeDmPackageWithParameters Makro über ein Button. Et voilà ! Das DataPackage mit unserer ScriptLogic wird ausgeführt.

Was ist aber, wenn wir auch die Version für Referenzdaten (in unserem Beispiel ACTUAL) variabel setzen wollen? Dazu können wir die Formelvariablen benutzen. Zunächst müssen wir unsere ScriptLogic Verteilungsfunktion anpassen und die Variable $VAR_CAT$ hinzufügen.

 *XDIM_MEMBERSET ACCOUNT = SAAMO
*XDIM_MEMBERSET CATEGORY = %CATEGORY_SET%
*XDIM_ADDMEMBERSET CATEGORY = $VAR_CAT$
*XDIM_MEMBERSET COMPCODE = %COMPCODE_SET%
*XDIM_MEMBERSET SAORG = %SAORG_SET%
*XDIM_MEMBERSET SAOFF = <ALL>
*XDIM_MEMBERSET DICHA = <ALL>
*XDIM_MEMBERSET PRODH1 = <ALL>
*XDIM_MEMBERSET PRODUCT = <ALL>
*XDIM_MEMBERSET INPUTCURRENCY = EUR
*XDIM_MEMBERSET TIME = BAS(%YEAR%.TOTAL)
*XDIM_ADDMEMBERSET TIME = BAS(%YEAR%(-1).TOTAL)

*RUNALLOCATION
*FACTOR = USING/TOTAL

*DIM ACCOUNT         WHAT = SAAMO;    WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM CATEGORY        WHAT = %CATEGORY_SET%;      WHERE = <<<;       USING = $VAR_CAT$;          TOTAL = <<<;
*DIM COMPCODE        WHAT = %COMPCODE_SET%;     WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM SAORG           WHAT = %SAORG_SET%;     WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM SAOFF           WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM DICHA           WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM PRODH1          WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM PRODUCT         WHAT = NONE;     WHERE = NONE;  USING = BAS(ALL);        TOTAL = <<<;
*DIM INPUTCURRENCY   WHAT = EUR;      WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM TIME            WHAT = BAS(%YEAR%.TOTAL); WHERE = <<<;       USING = BAS(%YEAR%(-1).TOTAL); TOTAL = <<<;

*ENDALLOCATION

Die Variable $VAR_CAT$ muss durch das DataPackage (Berichtspaket) übergeben werden.
Daher passen wir im nächsten Schritt das Skript des Berichtspakets an.

PROMPT(SELECTINPUT,,,,"%CATEGORY_DIM%,COMPCODE,SAORG")
PROMPT(TEXT, %VAR_CAT%, "Version der Referenzwerte",). 

INFO(%EQU%,=)

TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SUSER,%USER%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SAPPSET,%APPSET%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SAPP,PSX_PLAN)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SELECTION,%SELECTION%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,LOGICFILENAME,TEST.LGF)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,REPLACEPARAM,VAR_CAT%EQU%%VAR_CAT%)

Neben unseren alten Variablen soll nun auch die Variable %VAR_CAT% gefüllt werden. Diese muss dann in das Format der ScriptLogic (allerdings ohne $) übersetzt werden.
Dies geschieht in der letzten Zeile des Codes.
Im nächsten Schritt erweitern wir unseren PARAMETERS Bereich. Den Namensbereich können Sie im Reiter FormelnNamens-Manager ändern.

PARAMETRS Bereich wird um Variablen erweitert

Zusätzlicher Prompt Typ – Variable

Um den zusätzlichen Prompt Typ verarbeiten zu können, müssen wir unsere VBA Logik ändern. Glücklicherweise stimmt die XML-Syntax für Variablen mit der der Parameter überein. Wir können also dieselbe Methode addSingleSelectionParameterToXML nutzen. Erweitern Sie einfach das Makro createAnswerPromptFile um eine zusätzliche CASE Abfrage.

' If it is a single variable, then add a variable node to the root node
Case "Variable"
addSingleSelectionParameterToXML rngParameters(i, 1).Value, _
rngParameters(i, 4).Value, _
objRootElem, _
objDOM

Zur Sicherheit nochmal das gesamte Coding:

 Public Sub executeDmPackageWithParameters()
' Create the Answer Prompt file in the location
' specified in the Name Range "PACKAGE"
createAnswerPromptFile "PACKAGE", "PARAMETERS"
' Get the DM Automation class instance
Dim objDMautomation As EPMAddInDMAutomation
Set objDMautomation = New EPMAddInDMAutomation
' Run the package specified in Excel Name Range "PACKAGE",
' using the promtp file specified in Name Range "PACKAGE"
objDMautomation.RunPackage objPackageFromSheet("PACKAGE"), _
strFilename("PACKAGE")
End Sub
Private Function strFilename(strRange As String) As String
' Get the range in which the DM package paramteres is set
Dim rngPackageRange As Range
Set rngPackageRange = Application.Names(strRange).RefersToRange
' Loop through the rows
For i = 1 To rngPackageRange.Rows.Count
If rngPackageRange(i, 1).Value = "PromptFile" Then
strFilename = rngPackageRange(i, 2).Value
Exit Function
End If
Next
End Function
Private Function strPackageDescription(strRange As String) As String
' Get the range in which the DM package paramteres is set
Dim rngPackageRange As Range
Set rngPackageRange = Application.Names(strRange).RefersToRange
' Loop through the rows
For i = 1 To rngPackageRange.Rows.Count
If rngPackageRange(i, 1).Value = "PackageId" Then
strPackageDescription = rngPackageRange(i, 2).Value
Exit Function
End If
Next
End Function
Private Function objPackageFromSheet(strRange As String) As ADMPackage
' Get the range in which the DM package paramteres is set
Dim rngPackageRange As Range
Set rngPackageRange = Application.Names(strRange).RefersToRange
' Create the ADM Package object
Set objPackageFromSheet = New ADMPackage
' Loop through the rows
For i = 1 To rngPackageRange.Rows.Count
Select Case rngPackageRange(i, 1).Value
Case "Filename"
objPackageFromSheet.Filename = rngPackageRange(i, 2).Value
Case "GroupId"
objPackageFromSheet.GroupId = rngPackageRange(i, 2).Value
Case "PackageDesc"
objPackageFromSheet.PackageDesc = rngPackageRange(i, 2).Value
Case "PackageId"
objPackageFromSheet.PackageId = rngPackageRange(i, 2).Value
Case "PackageType"
objPackageFromSheet.PackageType = rngPackageRange(i, 2).Value
Case "TeamId"
objPackageFromSheet.TeamId = rngPackageRange(i, 2).Value
Case "UserGroup"
objPackageFromSheet.UserGroup = rngPackageRange(i, 2).Value
End Select
Next
End Function
Private Sub createAnswerPromptFile(strPackageName As String, _
strParametersName As String)
' Create a new XML document
Dim objDOM As DOMDocument
Set objDOM = New DOMDocument
' Set the processing instruction of the XML document
Dim objProcessingInstruction As IXMLDOMProcessingInstruction
Set objProcessingInstruction = _
objDOM.createProcessingInstruction("xml", _
" version='1.0' encoding='utf-16'")
objDOM.appendChild objProcessingInstruction
' Create root element
Dim objRootElem As IXMLDOMElement
Set objRootElem = objDOM.createElement("ArrayOfAnswerPromptPersistingFormat")
objDOM.appendChild objRootElem
' XSI Attribute
Dim objMemberRel As IXMLDOMAttribute
Set objMemberRel = objDOM.createAttribute("xmlns:xsi")
objMemberRel.NodeValue = "http://www.w3.org/2001/XMLSchema-instance"
objRootElem.setAttributeNode objMemberRel
' XSD Attribute
Set objMemberRel = objDOM.createAttribute("xmlns:xsd")
objMemberRel.NodeValue = "http://www.w3.org/2001/XMLSchema"
objRootElem.setAttributeNode objMemberRel
' Get the range of cells containing the parameters
Dim rngParameters As Range
Set rngParameters = ThisWorkbook.Names(strParametersName).RefersToRange
'Excel.Names(strParametersName).RefersToRange
'
Dim objCurrentStringPairParent As IXMLDOMElement
' Loop through each row
For i = 1 To rngParameters.Rows.Count
' See which type of parameter is being passed
Select Case rngParameters(i, 2).Value
' If it is a single Parameter, then add a parameter node to the root node
Case "Parameter"
addSingleSelectionParameterToXML rngParameters(i, 1).Value, _
rngParameters(i, 4).Value, _
objRootElem, _
objDOM
' If it is a list of values
Case "StringListPairs"
' If it's a new set of String List Pairs, then create a new parent
If rngParameters(i, 1).Value <> strCurrentStringPair Then
strCurrentStringPair = rngParameters(i, 1).Value
Set objCurrentStringPairParent = _
getStringListPairParent(rngParameters(i, 1).Value, _
objRootElem, _
objDOM)
End If
' Add the Dimension Name and Value to the parent
addStringListPair rngParameters(i, 3).Value, _
rngParameters(i, 4).Value, _
objCurrentStringPairParent, _
objDOM
' If it is a single variable, then add a variable node to the root node
Case "Variable"
addSingleSelectionParameterToXML rngParameters(i, 1).Value, _
rngParameters(i, 4).Value, _
objRootElem, _
objDOM
End Select
Next
' Create the File object
Dim objFile As FileSystemObject
Set objFile = New FileSystemObject
' Create a stream to create and write to the file
Dim objStream As TextStream
Set objStream = objFile.OpenTextFile(strFilename(strPackageName), _
ForWriting, True)
' Write the name of the DM package first and then the XML output
objStream.WriteLine strPackageDescription(strPackageName) & _
"{param_separator}" & _
objDOM.XML
' Close the file
objStream.Close
End Sub

Private Function addStringListPair(strVariableName As String, _
strValue As String, _
objParent As IXMLDOMElement, _
objDOM As DOMDocument)
' Create the "StringListPair" node
Dim objStringListPairElement As IXMLDOMElement
Set objStringListPairElement = _
objDOM.createElement("StringListPair")
objParent.appendChild objStringListPairElement
' Create the "Str" element containing the variable name
Dim objStrElement As IXMLDOMElement
Set objStrElement = objDOM.createElement("str")
objStringListPairElement.appendChild objStrElement
objStrElement.Text = strVariableName
' Create the "lst" element
Dim objLstElement As IXMLDOMElement
Set objLstElement = objDOM.createElement("lst")
objStringListPairElement.appendChild objLstElement
' Create the "string" element containing the variable value
Dim objStringElement As IXMLDOMElement
Set objStringElement = objDOM.createElement("string")
objLstElement.appendChild objStringElement
objStringElement.Text = strValue
End Function
Private Function getStringListPairParent(strVariableName As String, _
objParent As IXMLDOMElement, _
objDOM As DOMDocument) As IXMLDOMElement
' Create the "AnswerPromptPersistingFormat" node
Dim objAnswerPromptPersistingFormatElement As IXMLDOMElement
Set objAnswerPromptPersistingFormatElement = _
objDOM.createElement("AnswerPromptPersistingFormat")
objParent.appendChild objAnswerPromptPersistingFormatElement
' Create the "_ap" node
Dim objApElement As IXMLDOMElement
Set objApElement = objDOM.createElement("_ap")
objAnswerPromptPersistingFormatElement.appendChild objApElement
' Create the parameter name element
Dim objParameterElement As IXMLDOMElement
Set objParameterElement = objDOM.createElement("Name")
objApElement.appendChild objParameterElement
objParameterElement.Text = strVariableName
' Create the values element
Dim objValuesElement As IXMLDOMElement
Set objValuesElement = objDOM.createElement("Values")
objApElement.appendChild objValuesElement
' Create the "_apc" node
Set getStringListPairParent = objDOM.createElement("_apc")
objAnswerPromptPersistingFormatElement.appendChild getStringListPairParent
End Function

Private Function addSingleSelectionParameterToXML(strVariableName As String, _
strValue As String, _
objParent As IXMLDOMElement, _
objDOM As DOMDocument)
' Create the "AnswerPromptPersistingFormat" node
Dim objAnswerPromptPersistingFormatElement As IXMLDOMElement
Set objAnswerPromptPersistingFormatElement = _
objDOM.createElement("AnswerPromptPersistingFormat")
objParent.appendChild objAnswerPromptPersistingFormatElement
' Create the "_ap" node
Dim objApElement As IXMLDOMElement
Set objApElement = objDOM.createElement("_ap")
objAnswerPromptPersistingFormatElement.appendChild objApElement
' Create the parameter name element
Dim objParameterElement As IXMLDOMElement
Set objParameterElement = objDOM.createElement("Name")
objApElement.appendChild objParameterElement
objParameterElement.Text = strVariableName
' Create the values element
Dim objValuesElement As IXMLDOMElement
Set objValuesElement = objDOM.createElement("Values")
objApElement.appendChild objValuesElement
' Create the string element with the value passed to the parameter
Dim objStringElement As IXMLDOMElement
Set objStringElement = objDOM.createElement("string")
objValuesElement.appendChild objStringElement
objStringElement.Text = strValue
End Function

Genauso können Sie mit der Zeit verfahren.
ScriptLogic:

 *XDIM_MEMBERSET ACCOUNT = SAAMO
*XDIM_MEMBERSET CATEGORY = %CATEGORY_SET%
*XDIM_ADDMEMBERSET CATEGORY = $VAR_CAT$
*XDIM_MEMBERSET COMPCODE = %COMPCODE_SET%
*XDIM_MEMBERSET SAORG = %SAORG_SET%
*XDIM_MEMBERSET SAOFF = <ALL>
*XDIM_MEMBERSET DICHA = <ALL>
*XDIM_MEMBERSET PRODH1 = <ALL>
*XDIM_MEMBERSET PRODUCT = <ALL>
*XDIM_MEMBERSET INPUTCURRENCY = EUR
*XDIM_MEMBERSET TIME = BAS($VAR_AY$.TOTAL)
*XDIM_ADDMEMBERSET TIME = BAS($VAR_PY$.TOTAL)

*RUNALLOCATION
*FACTOR = USING/TOTAL

*DIM ACCOUNT         WHAT = SAAMO;    WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM CATEGORY        WHAT = %CATEGORY_SET%;      WHERE = <<<;       USING = $VAR_CAT$;          TOTAL = <<<;
*DIM COMPCODE        WHAT = %COMPCODE_SET%;     WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM SAORG           WHAT = %SAORG_SET%;     WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM SAOFF           WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM DICHA           WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM PRODH1          WHAT = NONE;     WHERE = BAS(ALL);  USING = BAS(ALL);        TOTAL = <<<;
*DIM PRODUCT         WHAT = NONE;     WHERE = NONE;  USING = BAS(ALL);        TOTAL = <<<;
*DIM INPUTCURRENCY   WHAT = EUR;      WHERE = <<<;       USING = <<<;             TOTAL = <<<;
*DIM TIME            WHAT = BAS($VAR_AY$.TOTAL); WHERE = <<<;       USING = BAS($VAR_PY$.TOTAL); TOTAL = <<<;

*ENDALLOCATION

DataPackage Skript:

PROMPT(SELECTINPUT,,,,"%CATEGORY_DIM%,COMPCODE,SAORG")
PROMPT(TEXT, %VAR_CAT%, "Version der Referenzwerte",). 
PROMPT(TEXT, %VAR_AY%, "Aktuelles Jahr",). 
PROMPT(TEXT, %VAR_PY%, "Vorheriges Jahr",). 

INFO(%EQU%,=)
INFO(%TAB%,;)

TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SUSER,%USER%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SAPPSET,%APPSET%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SAPP,PSX_PLAN)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,SELECTION,%SELECTION%)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,LOGICFILENAME,TEST.LGF)
TASK(/CPMB/DEFAULT_FORMULAS_LOGIC,REPLACEPARAM,VAR_CAT%EQU%%VAR_CAT%%TAB%VAR_AY%EQU%%VAR_AY%%TAB%VAR_PY%EQU%%VAR_PY%)

PARAMETERS Bereich:

PARAMETERS Bereich mit Zeitvariablen

PARAMETERS Bereich mit Zeitvariablen

Viel Spass dabei!

Quellen:
Tristan Colgate et al – How to Call a BPC Data Manager Package from VBA
Sergey Nelyapenko – How to deal with BPC Data Manager packages programmatically
SAP Hilfe

Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.

Denis Reis ist Business Intelligence Consultant bei Dahlbeer und gibt als Buchautor sein Wissen rund um den SAP Projektalltag weiter. Des Weiteren unterrichtet er Projektmanagement und Controlling an der Wiesbaden Business School. Der aus Düsseldorf stammende Familienmensch zählt zu denjenigen, die auf komplizierte Darstellungen verzichten und das Ganze auf den Punkt bringen.

How To BPC – Sprachabhängige Workbooks über VBA mit API Aufruf

Planungsmappen in BPC werden hauptsächlich auf Basis von Excel umgesetzt. Das heißt, dass wir unsere Überschriften, Reiternamen, Buttons usw. in Excel anlegen. Oft stehen wir vor der Herausforderung die Layouts zu lokalisieren, das heißt in verschiedenen Sprachen verfügbar zu machen. Wie stellen wir es am Besten an?
Eine Alternative wäre es Überschriften über eine Wenn/Dann Formel zu füllen indem man sich auf die Merkmalsbeschreibung bezieht die in verschiedenen Sprachen unterschiedliche Werte annimmt. Zum Beispiel Umsatz/Revenue. Allerdings können wir auf diese Weise keine Buttons oder Reiter umbenennen.
Die zweite Alternative wäre es, über VBA die Spracheinstellungen von Excel auszulesen und über SELECT CASE die Beschreibung der Elemente dementsprechend zu ändern. Das grundsätzliche Prinzip habe ich bereits im Beitrag „Sprachabhängige Meldungen ausgeben“ dargestellt.
Betrachten wir das folgende Planungslayout.

Planungslayout in BPC Excel

Planungslayout

In dem folgenden Coding lese ich nun beim Aufruf des Workbooks die Spracheinstellungen von Excel aus und ändere so die Beschriftung.

Function AFTER_WORKBOOK_OPEN()
AFTER_WORKBOOK_OPEN = True
'Lokalisierung
Select Case Application.LanguageSettings.LanguageID(msoLanguageIDUI)
'Deutsch
Case 1031, 3079, 5127, 4103

With Aggregated 'Worksheet Aggregated Planning
.Name = "Aggregierte Planung"
.Cells(4, 1).Value = "Absatz- und Umsatzplanung: Strategische Vorgaben"
.CommandButton1.Caption = "Umsatz berechnen"
.Cells(12, 2).Value = "Buchungskreis"
.Cells(12, 3).Value = "Verkaufsorganisation"
End With

'Englisch
Case Else
With Aggregated 'Worksheet Aggregated Planning
.Name = "Aggregated Planning"
.Cells(4, 1).Value = "Sales Planning: Strategical Guidlines"
.CommandButton1.Caption = "Calculate Revenues"
.Cells(12, 2).Value = "Company Code"
.Cells(12, 3).Value = "Sales Org."
End With

End Select
End Function

Was ist aber wenn Sie die Beschriftung nicht von der Excel-, sondern von der BPC-Einstellung abhängig machen wollen?

Benutzeroptionen BPC

BPC Spracheinstellungen

In diesem Fall können Sie auf die von SAP bereitgestellten APIs zurückgreifen. Zunächst müssen Sie diese aktivieren. Gehen Sie dazu in der Entwicklungsumgebung (ALT+F11) auf Extras → Verweise (engl. Tools → References) und wählen Sie FPMXLClient aus.

VBA Referenzen aktivieren

VBA Verweise

Nun können Sie alle Objekte im Objektkatalog (F2) sehen. Wählen Sie in der Dropdown-Liste FPMXLClient aus.
Die Klasse EPMAddInAutomation enthält alle Makros, die für das EPM-AddIn ausgeführt werden können. Beachten Sie, dass Sie diese nicht mit der Funktion EPMExecuteAPI verwenden können.
Die Klasse IEPMExecuteAPI enthält Makros, die direkt aus einer Arbeitsblattzelle über die Funktion EPMExecuteAPI ausgeführt werden können. Beispiele für diese Funktion finden Sie in den Beiträgen Script Logic über Excel Button ausführen und Automatische Aktualisierung der Inhalte nach dem Reiterwechsel.
Uns interessiert die Methode GetUserOption. Mit dem Parameter LanguageIsoCode können wir die Anwendungssprache und mit dem Parameter LanguageEdition die Sprache der Daten auslesen. Diese Methode liefert uns eine Zeichenfolge (String) im ISO 639-1 Format. So steht zum Beispiel de für Deutsch. Weitere Parameter für dieses API können Sie dem Benutzerhandbuch für das EPM-Add-In entnehmen.
Sie können dieses API wie folgt aufrufen. Beachten Sie, dassLanguageIsoCode in Gänsefüßchen steht, da es ein Parameter und keine Variable ist.

Sub Sprache()
Dim language As String
Dim EPMObj As FPMXLClient.EPMAddInAutomation
Set EPMObj = New FPMXLClient.EPMAddInAutomation

language = EPMObj.GetUserOption("LanguageIsoCode")
Debug.Print language

End Sub

Unser Makro für die Lokalisierung würde nun wie folgt aussehen.

Function AFTER_WORKBOOK_OPEN()
AFTER_WORKBOOK_OPEN = True
'Lokalisierung
Dim language As String
Dim EPMObj As FPMXLClient.EPMAddInAutomation
Set EPMObj = New FPMXLClient.EPMAddInAutomation

language = EPMObj.GetUserOption("LanguageIsoCode")
Select Case language
'Deutsch
Case "de"

With Aggregated 'Worksheet Aggregated Planning
.Name = "Aggregierte Planung"
.Cells(4, 1).Value = "Absatz- und Umsatzplanung: Strategische Vorgaben"
.CommandButton1.Caption = "Umsatz berechnen"
.Cells(12, 2).Value = "Buchungskreis"
.Cells(12, 3).Value = "Verkaufsorganisation"
End With

'Englisch
Case Else
With Aggregated 'Worksheet Aggregated Planning
.Name = "Aggregated Planning"
.Cells(4, 1).Value = "Sales Planning: Strategical Guidlines"
.CommandButton1.Caption = "Calculate Revenues"
.Cells(12, 2).Value = "Company Code"
.Cells(12, 3).Value = "Sales Org."
End With

End Select
End Function

Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.

Denis Reis ist Business Intelligence Consultant bei Dahlbeer und gibt als Buchautor sein Wissen rund um den SAP Projektalltag weiter. Des Weiteren unterrichtet er Projektmanagement und Controlling an der Wiesbaden Business School. Der aus Düsseldorf stammende Familienmensch zählt zu denjenigen, die auf komplizierte Darstellungen verzichten und das Ganze auf den Punkt bringen.

How To BPC – Automatische Aktualisierung der Inhalte nach dem Reiterwechsel

Oft bestehen die BPC Planungsmappen aus mehreren Tabellen.
In diesem How To zeige ich Ihnen, wie Sie mithilfe von VBA nach der Reiterauswahl einen automatischen Refresh durchführen können.
Wechseln Sie dazu mit ALT+F11 in die Entwicklungsumgebung und wählen Sie den Reiter aus, den Sie aktualisieren wollen.
Legen Sie ein Makro mit dem folgenden Code an.

Private Sub Worksheet_Activate()
Application.Run "EPMExecuteAPI", "RefreshActiveSheet"
End Sub

Nun erfolgt die Aktualisierung automatisch. Dies ist vor allem bei mehrstufigen Planungsprozessen nützlich.

Automatische Aktualisierung in BPC

Autorefresh in BPC

Wollen Sie nur die Daten der Berichte, jedoch nicht die Daten lokaler Elemente regenerieren, verwenden Sie den API RefreshReportDataOnly.

Private Sub Worksheet_Activate()
Application.Run "EPMExecuteAPI", "RefreshReportDataOnly"
End Sub

Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.

Denis Reis ist Business Intelligence Consultant bei Dahlbeer und gibt als Buchautor sein Wissen rund um den SAP Projektalltag weiter. Des Weiteren unterrichtet er Projektmanagement und Controlling an der Wiesbaden Business School. Der aus Düsseldorf stammende Familienmensch zählt zu denjenigen, die auf komplizierte Darstellungen verzichten und das Ganze auf den Punkt bringen.

BPC Business Process Flow anlegen und administrieren

In diesem How To möchte ich Ihnen zeigen wie Sie Arbeitsabläufe mittels Business Process Flow gestalten können. Die wesentlichen Objekte sind Prozessvorlagen (engl. Process Templates) und Prozessinstanzen (Process Instance). In der Vorlage definieren Sie den eigentlichen Fluss. Von diesem können Sie mehrere Instanzen anlegen, zum Beispiel getrennt nach Regionen und Zeit.

BPC Business Prozess FLow Modellierung

Busniess Process Flow Aufbau

Als erstes erstellen wir die Prozessvorlage zur Umsatzplanung. Wir vergeben den Namen und die Beschreibung für die Prozessvorlage. Danach wählen wir das Modell aus, auf dem die Vorlage basiert, sowie die Dimensionen der Planung. Für unsere Planung sind die Dimensionen Zeit und Version wichtig.

Prozessvorlage Dimensionen

Dimensionen der Planung

Anschließend bestimmen wir einen Benutzer, der die Instanzen überwachen kann.

Prozesseinstellungen Business Process Flow

Prozesseinstellungen

Im nächsten Schritt legen wir die eigentlichen Prozess-Schritte, die Aktivitäten (engl. Activity), fest. Wir vergeben einen Namen und eine Beschreibung (Anweisung). Als nächstes bestimmen wir die treibende Dimension. Diese bestimmt die Granularität der Planung sowie die Bearbeiter. Wir wollen die Aktivität ein Mal pro Buchungskreis ausführen, daher wählen wir Buchungskreis als treibende Dimension. Als Members selektieren wir die Hierarchie sodass die Kinder der Hierarchie, also die einzelnen Buchungskreise, die Granulariät der Aktivität festlegen (Basiselemente von der Hierarchie ALL). Der Bearbeiter wird durch die Eigenschaft Owner in Stammdaten des jeweiligen Elements bestimmt. In unserem Beispiel benötigen wir keinen Prüfer.
Über Öffnungskriterien können Sie festlegen ob die Aktivität nur gestartet werden kann, wenn alle vorherigen Aktivitäten für alle Prozesskontexte abgeschlossen wurden (Alle). Oder ob die Aktivität für einen bestimmten Kontext gestartet werden, wenn die vorherige Aktivität für denselben Kontext abgeschlossen ist (Abgestimmt).
Angenommen, wir planen auf der Ebene des Buchungskreise und haben folgende Aktivitäten festgelegt.

Unterscheid zwischen Öffnungskriterien Alle und Abgestimmt

Öffnungskriterien

Wenn Öffnungskriterium Alle (engl. All) gesetzt ist muss Buchungskreis 1000 vor der Währungsumrechnung warten bis Buchungskreis 2000 die Daten kontrolliert hat. Wenn das Öffnungskriterium jedoch auf Abgestimmt (engl. Matched) steht, kann Buchungskreis 1000 bereits mit der Währungsumrechnung anfangen, denn er hat ja seine Daten schon kontrolliert.
In unserem Beispiel entscheiden wir uns für Abgestimmt. Ferner können wir bestimmen, ob das erneute Öffnen dieser Aktivität erlaubt ist, nachdem der Planer diese schon abgeschlossen hat.

BPC Business Process Flow Aktivitäten

Aktivitäten

Im nächsten Schritt legen wir einen Arbeitsbereich (engl. Workspace) für den Bearbeiter an. Dieser enthält die einzelnen Aufgaben (Hyperlinks).
Nachdem wir den Arbeitsbereich erstellt haben fügen wir über den Button in der oberen rechten Ecke eine Aufgabe / einen Hyperlink hinzu.

BPC Hyperlinks hinzufügen

Hyperlinks hinzufügen

Wir nennen unsere Aufgabe „Umsätze planen“. Als Zielaktion soll das Eingabeformular für die strategische Planung in Excel geöffnet werden. Wir könnten noch bestimmte Ausprägungen übergeben, diese können aber auch durch den Kontext des Arbeitsbereiches vorgegeben werden.

Hyperlink bearbeiten

Ziealaktionen definieren

Die strategische Planung erfolgt auf einer aggregierten Ebene. Daher sollen die Werte anschließend heruntergebrochen werden. Dazu erstellen wir eine zugehörige Aktion „Werte herunterbrechen“.

Folgepaket

Zugehörige Aktion

Damit wäre die strategische Planung abgeschlossen, also soll als nächstes der Arbeitsstatus festgelegt werden.

Arbeitsstatus festlegen

Planung abschließen

Als letztes benennen wir die Registerkarte „Hyperlinks“ in „Strat. Planung“ um und speichern den Arbeitsbereich sowie die Prozessvorlage.

Hyperlinks umbenennen

Hyperlinks umbenennen

Geben Sie die fertige Prozessvorlage nun frei.

Prozessvorlage freigeben

Prozessvorlage freigeben

Nun können wir eine Prozessinstanz anlegen. Prozessinstanzen sind individualisierte Kopien der Vorlage.

BPC Business Process Flow Instance

Beispiel für Prozessinstanzen

Wählen Sie in der Administration unter Business Process Flows das Menü Prozessinstanzen aus. Klicken Sie auf den Button „Neu“. Wählen Sie zunächst einen Prozess aus. In unserem Fall ist es relativ einfach.

Neue Prozessinstanz anlegen

Prozess Auswählen

Wählen Sie nun den Eigentümer der Instanz aus.

Eigentümer auswählen

Eigentümer auswählen

Anschließend bestimmen Sie den Kontext für die Instanz. Alle Planer sollen in der Version S01 für das Jahr 2014 planen.

Kontext auswählen

Kontext bestimmen

Als nächstes werden die Zuordnungen erzeugt. In der Vorlage haben wir für die Aktivität „Strategische Planung“ den Buchungskreis als Treibende Dimension und als Bearbeiter den jeweiligen Owner ausgewählt. Die Dimension COMPCODE hat die folgenden Stammdaten (Elemente).

Buchungskreis Stammdaten

Owner Buchungskreis

Der User SPLANER (Strategic Planner) plant also die Buchungskreise Deutschland und Vereinigtes Königreich. Portugal und Frankreich muss ich selbst beplanen. Dementsprechend werden auch die Zuordnungen generiert. Sie können den Bearbeiter aber auch manuell ändern.

Bearbeiter zuordnen

Bearbeiter zuordnen

Im nächsten Fenster überprüfen Sie die Einstellungen und können die Prozessinstanz sofort starten. Die Aktivitäten der jeweiligen Bearbeiter werden generiert.
Achtung! Wenn eine Instanz gestartet wurde, können Sie keine Änderungen an der Vorlage vornehmen. Sie müssen die Instanz „Aussetzen“ und „Archivieren“.
Auf meiner Startseite, unter dem Menü Aktivitäten, sehe ich nun den Prozess „Umsatzplanung“ mit dem Kontext Version und Jahr. In den Details sehe ich die meine Buchungskreise. Ich bin für die Buchungskreise Portugal und Frankreich verantwortlich. User SPLANER (Strategic Planner) ist für die Buchungskreise Deutschland (IDES AG) und Vereinigtes Königreich (IDES UK) zuständig. Dementsprechend anders sieht seine Liste aus.

Startseite Aktivitäten

Aktivitäten von User SPLANER

Wenn der User nun auf die Aktivität klickt wird eine Eingabeform mit dem vorbelegten Kriterien, hier: Version, Buchungskreis und Zeit, geöffnet. Rechts erscheint ein Fenster mit dem Business Process Flow. Der Planer sieht die Aktionen die er ausführen muss. Die Information zeigt die Beschreibung die wir vergeben haben.

EPM Business Process Flow

Aktionen für die Aktivität

Nachdem er die notwendigen Planungsschritte ausgeführt hat, kann er die Planung abschließen und den Arbeitsstatus ändern. Damit können keine Änderungen mehr vorgenommen werden.
Der strategische Planer kann alle Verkaufsorganisationen in Deutschland sperren, da diese zum Buchungskreis Deutschland (1000) gehören. Diese werden für die Version S01 (Strategische Planung 01) und alle Monate des Jahres 2014 gesperrt.

Arbeitsstatus ändern

Arbeitsstatus setzen

Damit wäre die Planung abgeschlossen.
Nun wollen wir die Umsatzplanung um die operative Planung erweitern. Die operative Planung soll im Rahmen eines Top-Down Ansatzes erfolgen, das heißt die Planung erfolgt unter der Berücksichtigung der strategischen Vorgaben.

Die Planung soll auf der Ebene der Verkaufsorganisation durchgeführt werden. Der Bearbeiter wird durch die Eigenschaft Owner und der Prüfer durch die Eigenschaft Reviewer bestimmt.

Activity

Aktivität operative Planung

In den Stammdaten der Dimension Verkaufsorganisation ist OPLANER (Operativer Plannr) als Owner und SPLANER (Strategischer Planer) als Reviewer festgelegt.

Dimension Verkaufsorganisation

Stammdaten der Verkaufsorganisation

Als nächstes erstellen wir einen Arbeitsbereich für den Bearbeiter. Dieser enthält mehrere Aufgaben bzw. Hyperlinks. So sollen strategische Ziele kopiert und umgewertet werden. Danach müssen Preise und Mengen für Produkte gefunden werden. Anschließend wird der Umsatz berechnet.

Hyperlink Top Down Planung

Hyperlink

Sobald die eigentliche Planung beendet wurde, soll der Arbeitsstatus aktualisiert werden. Insgesamt umfasst die operative Planung fünf Aufgaben.

Workspace

Arbeitsbereich operative Planung

Der Prüfer soll einen eigenen Arbeitsbereich bekommen. Er soll sich die geplanten Werte anschauen und bestätigen.

Workspace Prüfer

Arbeitsbereich des Prüfers

Der strategische Planer hat seine Planung bereits durchgeführt. Bei der operativen Planung ist zunächst keine Aktion erforderlich.

Aktivitäteten Strategischer Planer

Aktivitäten strategischer Planer

Nun führt der operative Planer seine Planung durch.

Arbeitspakete

Zielaktionen operativer Planer

Anschließend ändert er den Arbeitsstatus für die jeweilige Verkaufsorganisation auf Submitted und legt seine Planung dem strategischen Planer zur Überprüfung vor (Button Vorlegen). Durch die Änderung des Arbeitsstatus kann er die eingegeben Werte nicht mehr nachträglich ändern.

Workstatus

Arbeitsstatus

Die Aktivität wurde zur Überprüfung vorgelegt.

Status der Planung

Status vorgelegt

Nun ändert sich das Aktivitäten Menü des Prüfers. Der strategische Planer sieht, dass bei der operativen Planung seine Aktion erforderlich ist.

Prüfung erforderlich

Aktion erforderlich

Der strategische Planer kann nun als Prüfer die geplanten Werte evaluieren. Je nach seiner Entscheidung kann er den Plan genehmigen oder ablehnen. (Er kann in diesem Schritt auch die Daten manuell ändern, je nach Einstellungen des Arbeitsstatus in der Administration). Aber davor sollte er den Arbeitsschritt „Arbeitsstatus festlegen“ ausführen, den wir für ihn bestimmt haben.
Falls er den Plan ablehnt kann er die Daten wieder entsperren und so dem operativen Planer eine erneute Eingabe der Werte erlauben. Oder er könnte auch die Daten endgültig sperren und den Plan genehmigen. Dadurch wird der Status auf „Abgeschlossen“ gesetzt.

Als Prozessmanager kann ich den Fortschritt unter dem Menü Prozessmonitor im Reiter Startseite den Fortschritt überprüfen.

Prozessmonitor

Prozessmonitor

Im Rahmen des Business Process Flows bekommen alle Beteiligten (Prozesseigentümer, Bearbeiter und Prüfer) E-Mails, die über den Fortschritt der Planung informieren. Zur Generierung von E-Mails wird das Programm UJB_MAINTAIN_EMAIL_TMPL genutzt. Sie können neue E-Mail Vorlagen über die Transaktion SMARTFORMS anlegen. Die Vorlagen werden in der Tabelle UJB_EMAIL10 gespeichert.

Ich hoffe ich konnte Ihnen einen Überblick über Business Process Flows in BPC geben. Diese bieten viele Gestaltungsmöglichkeiten. Viel Spaß beim werkeln!

Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.

Denis Reis ist Business Intelligence Consultant bei Dahlbeer und gibt als Buchautor sein Wissen rund um den SAP Projektalltag weiter. Des Weiteren unterrichtet er Projektmanagement und Controlling an der Wiesbaden Business School. Der aus Düsseldorf stammende Familienmensch zählt zu denjenigen, die auf komplizierte Darstellungen verzichten und das Ganze auf den Punkt bringen.