簡介
本教學課程示範如何實作 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 。