Présentation
Ce tutoriel explique comment mettre en oeuvre un script Groovy qui valide l'entrée de données par rapport aux intervalles autorisés stockés dans un cube de pilote.
Contexte
Dans cet exemple, vous allez créer un script qui s'exécute lorsque les utilisateurs enregistrent les mises à jour des salaires et des primes des employés à partir d'un formulaire de saisie de données. Le script charge les données d'échelon d'employé (salaire minimum/maximum permis et prime minimum/maximum permis) d'un cube d'inducteur dans une grille temporaire en mémoire, puis valide les valeurs de salaire et de prime entrées par rapport aux intervalles autorisés.
Préalables
Les tutoriels pratiques Cloud EPM peuvent nécessiter l'importation d'un instantané dans votre instance Cloud EPM Enterprise Service. Avant d'importer un instantané de tutoriel, vous devez demander une autre instance du service Cloud EPM Enterprise ou supprimer l'application et le processus d'affaires courants. L'instantané du tutoriel ne sera pas importé sur votre application ou processus d'affaires existant, et il ne remplacera pas ou ne restaurera pas automatiquement l'application ou le processus d'affaires avec lequel vous travaillez actuellement.
Avant de commencer ce tutoriel, vous devez :
- Permet à l'administrateur de service d'accéder à une instance Cloud EPM Enterprise Service.
- Chargez et importez cet instantané dans votre instance Planning. Si vous avez précédemment chargé l'instantané pour un autre tutoriel Groovy, vous pouvez continuer à utiliser le même instantané.
Note :
Si vous rencontrez des erreurs de migration lors de l'importation de l'instantané, réexécutez la migration à l'exclusion du composant HSS-Shared Services, ainsi que des artefacts Security et User Preferences du composant Core. Pour plus d'informations sur le chargement et l'importation d'instantanés, consultez la documentation sur l'administration de la migration pour Oracle Enterprise Performance Management Cloud.Conseil :
Les scripts dont vous avez besoin pour ce tutoriel sont liés sous forme de fichiers texte dans chaque section.Création du script
- Ouvrez Calculation Manager et créez une règle nommée Groovy Validate Employee Data dans le cube Plan1.
- Dans l'éditeur de règle, remplacez l'option Concepteur par Modifier le script et réglez le type de script à Script Groovy.
- Copiez ce script et collez-le dans l'éditeur.
- Dans la barre d'outils, cliquez sur
(Enregistrer) pour enregistrer le script, puis cliquez sur
(Valider et déployer) pour valider et déployer le script. Cliquez sur OK lorsque vous y êtes invité. Fermez 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.") } } }
expliquer la logique du script
Dans cette section, nous allons décrire la logique du script une section à la fois.
-
Créez une classe.
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}"
} }
Créez une classe,
GradeData
, pour stocker les données d'échelon d'employé (salaire minimum/maximum permis et prime minimum/maximum permis) à partir d'un cube d'inducteur.La méthode
toString()
retourne une représentation de chaîne de l'objetGradeData
. La méthode utilise l'opérateur de sécurité nul (?.
) fourni par Groovy. Si la variable précédant le point d'interrogation est nulle, elle ne va pas continuer et retourneNULL
. Par exemple,{minSalary?.formattedValue}
donne la valeurNULL
au lieu de générer une exceptionNullPointerException
siminSalary
est nul. - Créez un chargeur d'ensembles.
- Chargez la grille de données à partir du cube de consultation pour la région définie par l'objet DataGridDefinition.
- Créez une mappe de données d'échelon (salaire minimal/maximal et prime) par nom d'échelon à partir de la grille de données.
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) } }
Créez une carte nommée
gradeDataMap
des données d'échelon (salaire minimal/maximal et prime) par nom d'échelon.Alimentez la carte
gradeDataMap
avec les données d'échelon pour chaque échelon. L'échelon est la clé et l'objet GradeData alimenté avec le salaire minimum/maximum et la prime est la valeur. - Créez un itérateur qui effectue une itération sur toutes les cellules de données contenant le membre Grade dans la grille d'entrée courante.
- Lancez une exception de veto.
- Validez les valeurs du tableau.
// 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()
![]()
Créez un chargeur d'ensembles de ressources contenant les messages localisés requis par cette règle.
Obtenir le cube inducteur/consultation.
Obtenez une valeur DataGridDefinitionBuilder pour le cube. Utilisez le générateur pour construire une région à partir de laquelle charger les données en ajoutant les membres PDV, les membres de colonne et les lignes.
Créez l'objet 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") }
Vérifiez que la grille d'entrée contient au moins une cellule contenant le membre Grade. Sinon, lancez une exception de veto avec le message localisé.
// 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.") } } }
Validez les valeurs de la grille d'entrée en cours d'enregistrement par rapport aux valeurs de gradeDataMap. L'échelon dans la grille d'entrée est un compte de type liste dynamique qui est dérivé de la hiérarchie d'échelon définie dans le cube de consultation. L'appel de
it.DataAsSmartListMemberName
obtient le nom du membre à partir duquel la valeur de liste dynamique de la cellule courante est dérivée, qui peut ensuite être utilisée comme clé dans la carte pour obtenir les données d'échelon.
Transférer la dimension dans la cellule Salary et valider le salaire par rapport au salaire autorisé dans les données d'échelon.
Transférer dim dans la cellule Bonus et valider le Bonus par rapport au Bonus autorisé dans les données d'échelon. Si le salaire ou la prime n'est pas compris dans les limites autorisées, réglez la couleur d'arrière-plan de la cellule à rouge et ajoutez une erreur de validation à la cellule en appelant l'API
addValidationError()
. Le message d'erreur sera défini en tant qu'infobulle de la cellule et apparaîtra également dans les messages de validation de grille. De plus, si cette règle est exécutée après l'enregistrement, le système opposera son veto à l'opération d'enregistrement.
Tester le script
- Dans le gestionnaire de formulaires, modifiez le formulaire ManageEmployees et associez la règle Groovy Valider les données d'employé à exécuter Après le chargement et Avant l'enregistrement (vous devrez peut-être sélectionner Plan1 dans la liste Cube en premier).
- Enregistrez le formulaire et fermez la fenêtre Form Manager.
- Ouvrez le tableau de bord Employés. Ajoutez une prime de 1000 pour l'employé 1, augmentez le salaire de l'employé 2 à 65000. Dans la barre d'outils du formulaire, cliquez sur
(Enregistrer).
- Dans la boîte de dialogue Message d'erreur, cliquez sur OK.
- Pointez la souris sur les cellules rouges pour voir les messages d'erreur détaillés sous forme d'infobulles.
- Fermez le tableau de bord et ouvrez la console Jobs.
- Cliquez sur Valider les données d'employé de Groovy pour afficher les détails de l'emploi. Cliquez sur le statut Terminé pour voir les données d'échelon chargées à partir du cube de consultation et les données d'échelon par échelon de chaque employé.





Liens connexes
- Vidéos sur Groovy sur le canal YouTube des tutoriels sur Oracle EPM
- EPM Cloud Planning - Tutoriels Groovy
- Informations de référence sur l'API Java pour Oracle Enterprise Performance Management Cloud et Groovy Rules
- API REST pour Oracle Enterprise Performance Management Cloud
- Référence de script Groovy
Autres ressources d'apprentissage
Explorez d'autres laboratoires sur le site docs.oracle.com/learn ou accédez à plus de contenu d'apprentissage gratuit sur le canal Oracle Learning YouTube. De plus, visitez Oracle University pour voir les ressources de formation disponibles.
Pour obtenir la documentation sur le produit, visitez Oracle Help Center.
Validation des valeurs d'entrée de données avec Groovy
G44678-01
Octobre 2025