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

How To BPC – Variablenübergabe an ScriptLogic DataPackages aus Excel
5 Sterne
1 Bewertungen

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 und gibt als Buchautor sein Wissen rund um den SAP Projektalltag weiter. Wenn Sie tatkräftige Unterstützung bei Ihren SAP BI Projekten benötigen, können Sie ihn über Xing, LinkedIn oder Facebook kontaktieren.
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.

2 Kommentare

Dein Kommentar

Want to join the discussion?
Feel free to contribute!

Kommentar verfassen