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.
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.
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.
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.
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.
Ü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 KonstanteDIMS
festgelegt. Den Inhalt können Sie in Berichtspaketeinstellungen unter Konstanten sehen.
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 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.
Wählen Sie anschließend Skript ändern aus und klicken Sie im folgenden Fenster oben rechts auf Erweitert.
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.
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
.
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.
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
).
Sie sehen nun alle Informationen die wir für den PACKAGE
Bereich benötigen.
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
.
Planung und Reporting mit SAP Analysis leicht gemacht!
Lernen Sie, wie Sie mit SAP Analysis for Microsoft Office professionelle Berichte erstellen. Dieses Praxishandbuch erklärt Ihnen, wie Sie Ihre Daten auf vielfältige Weise auswerten und darstellen. Schritt-für-Schritt-Anleitungen mit zahlreichen Screenshots unterstützen Sie – von der Implementierung bis zur Anwendung.
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 Extras → Verweise (engl. Tools → References) und wählen Sie die folgenden Einträge aus.
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 = "https://www.w3.org/2001/XMLSchema-instance" objRootElem.setAttributeNode objMemberRel ' XSD Attribute Set objMemberRel = objDOM.createAttribute("xmlns:xsd") objMemberRel.NodeValue = "https://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-Manager → Status 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.
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.
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 Formeln → Namens-Manager ändern.
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 = "https://www.w3.org/2001/XMLSchema-instance" objRootElem.setAttributeNode objMemberRel ' XSD Attribute Set objMemberRel = objDOM.createAttribute("xmlns:xsd") objMemberRel.NodeValue = "https://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:
Viel Spass dabei!
Ihre User beklagen sich über langsame Berichte?
- In meinem Newsletter lernen Sie, wie Sie Abhilfe schaffen.
- Entdecken Sie die Möglichkeiten der Performanceoptimierung.
- Praktische Anleitungen ermöglichen Ihnen schnelle Erfolge bei der Optimierung von SAP Systemen.
- Viele Tipps und Tricks zu SAP BI Themen.
- Holen Sie die maximale Performance aus Ihrem SAP BI!
- Bei der Anmeldung zu meinem Newsletter erhalten Sie das Buch „High Performance SAP BI“ als Willkommensgeschenk.


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.
Gutes Howto – probier ich bei Gelegenheit mal aus.
Vielen Dank.