簡介
本教學課程示範如何實作 Groovy 指令碼,以針對儲存在驅動程式立方體中的允許範圍來驗證資料輸入。
背景
在此範例中,您將建立一個指令檔,當使用者從資料輸入表單儲存員工薪資與紅利更新時執行。指令碼會將員工職等資料 (允許的薪資下限 / 上限,以及允許的加成下限 / 上限) 從動因立方體載入記憶體中的暫存方格,然後根據允許的範圍驗證輸入的薪資與加成值。
必要條件
Cloud EPM 實作教學課程可能需要您將快照匯入您的 Cloud EPM Enterprise Service 例項。您必須先要求另一個 Cloud EPM Enterprise Service 例項或移除目前的應用程式與業務程序,才能匯入教學課程快照。教學課程快照不會透過您現有的應用程式或業務程序進行匯入,也不會自動取代或還原您目前使用的應用程式或業務程序。
開始此教學課程之前,您必須:
- 讓服務管理員可以存取 Cloud EPM Enterprise Service 例項。
- 上傳此快照並匯入至您的 Planning 例項。如果您先前已上傳另一個 Groovy 教學課程的快照,您可以繼續使用相同的快照。
附註:
如果匯入快照時發生移轉錯誤,請重新執行移轉 (不包括 HSS-Shared Services 元件),以及「核心」元件中的「安全性與使用者偏好設定」人工因素。如需上傳與匯入快照的詳細資訊,請參考管理 Oracle Enterprise Performance Management Cloud 的移轉文件。秘訣:
此教學課程所需的命令檔會連結為每個區段內的文字檔。建立程序檔
- 開啟 Calculation Manager,並在 Plan1 立方體中建立名為 Groovy 驗證員工資料的規則。
- 在「規則編輯器」中,將「設計工具」選項變更為編輯命令檔,然後將「命令檔類型」設為 Groovy 命令檔。
- 複製此命令檔並貼到編輯器中。
- 在工具列上,按一下
(儲存) 以儲存命令檔,然後按一下
(驗證並部署) 以驗證並部署命令檔。提示時,按一下確定。關閉 Calculation Manager。


class GradeData { Integer Grade DataGrid.DataCell minSalary DataGrid.DataCell maxSalary DataGrid.DataCell minBonus DataGrid.DataCell maxBonus public String toString() { return "minSalary: ${minSalary?.formattedValue}, maxSalary: ${maxSalary?.formattedValue}, minBonus: ${minBonus?.formattedValue}, maxBonus: ${maxBonus?.formattedValue}" } } // Create a resource bundle loader containing localized messages needed by this rule. def mbUs = messageBundle( ["validation.missingmember.grade":"No Grades found on the Grid."] ) def mbl = messageBundleLoader(["en" : mbUs]) Cube lookupCube = operation.application.getCube("Plan1") DataGridDefinitionBuilder builder = lookupCube.dataGridDefinitionBuilder() builder.addPov(['Years', 'Scenario', 'Currency', 'Period', 'Version', 'Entity'], [['FY16'], ['Current'], ['USD'], ['BegBalance'], ['BU Version_1'], ['No Entity']]) builder.addColumn(['Account'], [ ['Min Salary', 'Max Salary', 'Min Bonus', 'Max Bonus'] ]) builder.addRow(['Grades'], [ ['ILvl0Descendants("Grades")'] ]) DataGridDefinition gridDefinition = builder.build() // Load the data grid from the lookup cube DataGrid dataGrid = lookupCube.loadGrid(gridDefinition, false) // Create a map of grade data (Min/Max Salary and Bonus) by grade name from the data grid. def gradeDataMap = new HashMap() if(dataGrid) { println("dataGrid is not null") dataGrid.dataCellIterator('Min Salary').each { def gradeData = new GradeData() gradeData.minSalary = it gradeData.maxSalary = it.crossDimCell('Max Salary') gradeData.minBonus = it.crossDimCell('Min Bonus') gradeData.maxBonus = it.crossDimCell('Max Bonus') gradeDataMap[(it.getMemberName('Grades'))] = gradeData println(it.getMemberName('Grades') + ": " + gradeData) } } DataGrid grid = operation.grid // Construct an iterator that iterates over all data cells containing the Grade member. GridIterator itr = grid.dataCellIterator('Grade') // Throw a veto exception if the grid has at least one cell but does not contain any cells containing the Grade member. if(!grid.empty && !itr.hasNext()) { // Found 0 cells with Grade throwVetoException(mbl, "validation.missingmember.grade") } // Validate the values in the grid being saved against the values in gradeDataMap. itr.each { GradeData gradeData = gradeDataMap[it.DataAsSmartListMemberName] if(gradeData == null) { println("Unable to locate grade data for grade: ${it.DataAsSmartListMemberName}, with data value: ${it.formattedValue}" ) } else { println(it.getMemberName('Employee') + ": " + gradeData.toString()) DataCell salary = it.crossDimCell('Salary') if(salary == null) println("Unable to locate Salary") else if(salary.data < gradeData.minSalary.data || salary.data > gradeData.maxSalary.data) { salary.addValidationError(0xFF0000, "Salary is outside of the allowed range.") } DataCell bonus = it.crossDimCell('Bonus') if(bonus == null) { println("Unable to locate Bonus") } else if(bonus.data < gradeData.minBonus.data || bonus.data > gradeData.maxBonus.data) { bonus.addValidationError(0xFF0000, "Bonus is outside of the allowed range.") } } }
說明命令檔邏輯
在本節中,我們將一次描述一個區段的指令檔邏輯。
-
建立課程。
class GradeData {
Integer Grade DataGrid.DataCell minSalary DataGrid.DataCell maxSalary DataGrid.DataCell minBonus DataGrid.DataCell maxBonus public String toString() { return "minSalary: ${minSalary?.formattedValue}, maxSalary: ${maxSalary?.formattedValue}, minBonus: ${minBonus?.formattedValue}, maxBonus: ${maxBonus?.formattedValue}"
} }
建立類別
GradeData
,以從動因立方體儲存員工職等資料 (允許的薪資下限 / 上限,以及允許的獎金下限 / 上限)。toString()
方法會傳回GradeData
物件的字串表示法。此方法使用 Groovy 提供的空值安全運算子 (?.
)。如果問號之前的變數為空值,則不會繼續並傳回NULL
。例如,如果minSalary
為空值,{minSalary?.formattedValue}
會評估為NULL
值,而不是發出NullPointerException
異常狀況。 - 建立搭售品載入器。
- 從 DataGridDefinition 物件所定義區域的查尋立方體載入資料方格。
- 從資料方格中,依薪等名稱建立薪等資料 (最低 / 最高薪資與獎金) 對應。
def gradeDataMap = new HashMap<String, GradeData>()
if(dataGrid) { println("dataGrid is not null") dataGrid.dataCellIterator('Min Salary').each {
def gradeData = new GradeData() gradeData.minSalary = it gradeData.maxSalary = it.crossDimCell('Max Salary') gradeData.minBonus = it.crossDimCell('Min Bonus') gradeData.maxBonus = it.crossDimCell('Max Bonus') gradeDataMap[(it.getMemberName('Grades'))] = gradeData println(it.getMemberName('Grades') + ": " + gradeData) } }
依職等名稱建立名為
gradeDataMap
的職等資料對應 (最低 / 最高薪資與獎金)。將每個「成績」的成績資料植入
gradeDataMap
對應。等級是索引鍵,且填入「最低 / 最高薪資」和「獎金」的 GradeData 物件為值。 - 建構重複程式,以重複目前輸入方格中包含「等級」成員的所有資料儲存格。
- 發出否決例外。
- 驗證方格值。
// Create a resource bundle loader containing localized messages needed by this rule. def mbUs = messageBundle( ["validation.missingmember.grade":"No Grades found on the Grid."] )def mbl = messageBundleLoader(["en" : mbUs]) Cube lookupCube = operation.application.getCube("Plan1")
DataGridDefinitionBuilder builder = lookupCube.dataGridDefinitionBuilder()
builder.addPov(['Years', 'Scenario', 'Currency', 'Period', 'Version', 'Entity'], [['FY16'], ['Current'], ['USD'], ['BegBalance'], ['BU Version_1'], ['No Entity']]) builder.addColumn(['Account'], [ ['Min Salary', 'Max Salary', 'Min Bonus', 'Max Bonus'] ]) builder.addRow(['Grades'], [ ['ILvl0Descendants("Grades")'] ]) DataGridDefinition gridDefinition = builder.build()
![]()
建立包含此規則所需之本地化訊息的資源組合載入器。
取得動因 / 查詢立方體。
取得立方體的 DataGridDefinitionBuilder。使用建構器透過新增 POV 成員、欄成員和列來建構載入資料的區域。
建立 DataGridDefinition 物件。
DataGrid dataGrid = lookupCube.loadGrid(gridDefinition, false)
DataGrid grid = operation.grid GridIterator itr = grid.dataCellIterator('Grade')
// Throw a veto exception if the grid has at least one cell but does not contain any cells containing the Grade member. if(!grid.empty && !itr.hasNext()) {// Found 0 cells with Grade throwVetoException(mbl, "validation.missingmember.grade") }
驗證輸入方格至少有一個包含「等級」成員的儲存格。如果不是,則在本土化訊息中發出否決例外。
// Validate the values in the grid being saved against the values in gradeDataMap. itr.each {GradeData gradeData = gradeDataMap[it.DataAsSmartListMemberName] if(gradeData == null) { println("Unable to locate grade data for grade: ${it.DataAsSmartListMemberName}, with data value: ${it.formattedValue}" ) } else { println(it.getMemberName('Employee') + ": " + gradeData.toString()) DataCell salary = it.crossDimCell('Salary')
if(salary == null) println("Unable to locate Salary") else if(salary.data < gradeData.minSalary.data || salary.data > gradeData.maxSalary.data) { salary.addValidationError(0xFF0000, "Salary is outside of the allowed range.") } DataCell bonus = it.crossDimCell('Bonus')
if(bonus == null) { println("Unable to locate Bonus") } else if(bonus.data < gradeData.minBonus.data || bonus.data > gradeData.maxBonus.data) { bonus.addValidationError(0xFF0000, "Bonus is outside of the allowed range.") } } }
根據 gradeDataMap 中的值驗證要儲存之輸入方格中的值。輸入方格中的職等是智慧型列示類型的科目,其衍生自查尋立方體中定義的職等階層。呼叫
it.DataAsSmartListMemberName
會取得從中導出目前儲存格之智慧列示值的成員名稱,然後在對應中作為索引鍵來取得等級資料。
交叉調暗至「薪資」儲存格,然後根據成績資料中允許的「薪資」來驗證「薪資」。
橫向展開「紅利」儲存格,並針對成績資料中允許的「紅利」驗證「紅利」。如果「薪資」或「紅利」不在允許的限制內,請將儲存格的背景顏色設為紅色,並呼叫
addValidationError()
API 在儲存格上新增驗證錯誤。錯誤訊息將設為儲存格的工具提示,也會顯示在「方格驗證訊息」中。此外,如果此規則在「儲存後」執行,則系統會否決儲存作業。
測試程序檔
- 在「表單管理程式」中,編輯 ManageEmployees 表單,並將「Groovy 驗證員工資料」規則與載入後和儲存前建立關聯 (您可能需要先從「立方體」清單中選取 Plan1)。
- 儲存表單並開啟「表單管理程式」視窗。
- 開啟員工儀表板。為員工 1 新增 1000 紅利,將員工 2 的薪資增加至 65000 。在表單工具列中,按一下
(儲存)。
- 在「錯誤訊息」對話方塊中,按一下確定。
- 將滑鼠游標停留在紅色儲存格上方,即可看到詳細的錯誤訊息作為工具提示。
- 關閉儀表板並開啟「工作」主控台。
- 按一下 Groovy 驗證員工資料以顯示職務詳細資料。按一下已完成狀態,以查看從查尋立方體載入的職等資料,以及每個員工職等的職等資料。





相關連結
其他學習資源
在 docs.oracle.com/learn 上探索其他實驗室,或在 Oracle Learning YouTube 頻道上存取更多免費學習內容。此外,請造訪 Oracle University 以檢視可用的訓練資源。
如需產品文件,請造訪 Oracle Help Center 。