I was asked to present at a "Last Minute ODTUG Kscope18 Planning Souvenirs You Will ACTUALLY Use!" presentation on Thursday. This will take you into deeper functional use cases of the Groovy GridBuilder.
1. Groovy Grid Builder – Deep Dive • Kyle Goodfriend
LAST MINUTE ODTUG KSCOPE18
PLANNING SOUVENIRS
June 14th
, 9:30 - 11:00 a.m.
Southern Hemisphere II, Fifth Level
Kyle Goodfriend
ODTUG • Kscope 18
2. 2
GROOVY GRIDBUILDER DEEP DIVE AGENDA
INTRODUCTION
PBCS AND GROOVY
THE GRIDBUILDER
GRIDBUILDER
METHODS
REAL WORLD
EXAMPLES
PRODUCTIVITY GUIDANCE
AND SUGGESTIONS
WHERE TO GO NEXT
WRAP-UP
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
4. Slide 4
HOUSEKEEPING
• Questions and Answers
» We will answer questions throughout
the presentation
» Bring questions with your
name/email/phone number up to the
front at the end of the presentation and I
will make sure they get answered
ODTUG • KScope18
Top-Down & Bottom-Up Planning at Breakthru Beverage Group
Wed, Jun 13, 2018 (11:45 PM - 12:45 PM)
5. 5
WHO AM I?
• BBA, concentration in Finance
• Moved into technology because I was always trying
to find a way to eliminate redundant tasks (AKA –
hated my job)
• Started using Essbase to consolidate multiple GLs
with consolidated companies
• Started consulting in 1999
• Really enjoy what I do because it is artistic and
creative - finding solutions for complex problems
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
kyle@in2hyperion.com
614.668.7324
6. 6
WHY DID I START USING GROOVY CALCULATIONS?
• Forms were taking minutes to update
» Hundreds of products
» Data was entered at parent level
» Hundreds of allocations were executed
• Client wanted real time reporting
» Users wanted full P&L consolidated reporting when product/material
group/delivery channel were made
» Users wanted full P&L consolidated reporting when employee level changes were
made
• Complex data validation was required in data that was changed
» Monthly spreading has to have a net impact of zero
» Employee level validation was required
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
7. PERFORMANCE AND USABILITY
7
99%IMPROVEMENT 98% 99%
Reporting includes all updates from
detailed modules (product, Capex,
workforce, and similar modules) and
is included in
real time as changes are made
Consolidated Reporting
Reporting includes all updates from
detailed modules (product, Capex,
workforce, and similar modules) at
scheduled intervals
users have to wait to see
consolidated information
Groovy eliminates the need to
consolidate the BSO cube and
copies data directly from the
ASO cube at a consolidated
level
.2 Seconds
Dimensions are consolidated
and copied to the P&L model
82.9 Seconds
Consolidated P&L
Product detailed dimensions
are consolidated and moved
to the P&L model
Groovy selects only the cells
that where edited and copies
only what changed to the
reporting model
1.0 Seconds
All data on the form is
synchronized
14.5 Seconds
Smart Push
Data synchronizes to the
reporting cube for analysis
01
0110
0001
01101
Groovy selects only edited
cells and executes the logic
on only products and periods
that changed
0.3 Seconds
All products on the form are
calculated
26.1 Seconds
Business Logic
Growth rates are entered at
total product breakouts and
allocated to the detailed level
With the inclusion of Groovy
and access to the Java API,
more customization can be
integrated to maximum
performance and achieve real
time consolidated reporting
Submit
Planner Input
User submits updates to the
Gross Profit model at a
detailed product level that
exists at a more granular level
than in the P&L model
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
8. ADMINISTRATIVE FLEXIBILITY
8
Reporting includes all updates from
detailed modules (product, Capex,
workforce, and similar modules) and
is included in
real time as changes are made
Consolidated Reporting
Reporting includes all updates from
detailed modules (product, Capex,
workforce, and similar modules) at
scheduled intervals
users have to wait to see
consolidated information
Automated Process
Administrative processes are
executed to run all business
logic and model
synchronizations
The entire data set is
consolidated and moved to
the P&L model
12.0 Seconds
Dimensions are consolidated
and copied to the P&L model
663.6 Seconds
Global Consolidation
Global product consolidations are
often required to catch all changes
and completed during
maintenance windows
99% 99%
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
9. NEVER THOUGHT I WOULD SAY
THIS
It is possible to build a planning application without writing a single BSO calculation
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend 9
10. PBCS AND GROOVY
Groovy is now available in ePBCS as calculation
10Groovy Grid Builder – Deep Dive • Kyle Goodfriend
ODTUG • Kscope 18
2
11. 11
CONVERTING TO GROOVY CALCULATION
• Open Rules in PBCS and create a new rule
• Change the dropdown box with from Designer to Edit Script
• Change the Script type dropdown box to Groovy Script
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
12. 12
WHAT IS AVAILABLE WITH GROOVY CALCULATIONS
• Iterating through data grid cells
» Color coding
» Data validation
» Identification of edited and non-edited cells
• Data synchronization between ASO/BSO and BSO/ASO
• Execute business logic
• Mapping data between cubes
• Can be executed in stages
» Pre-save
» On-load
» Post-save
Groovy Grid Builder – Deep Dive • Kyle GoodfriendODTUG • Kscope 18
13. THE GRID BUILDER
The GridBuilder methods provide a completely
customized way to do so many things. Your
creativity is the only thing that limits the
possibilities. It is the gateway to completing the
circle of doing everything in Groovy
ODTUG • Kscope 18
Groovy Grid Builder – Deep Dive • Kyle Goodfriend 13
3
14. Groovy Grid Builder – Deep Dive • Kyle Goodfriend 14
GRIDBUILDER CONCEPTS
• Each grid has
» A POV
» Column headers
» Row headers
• Grids can
» Build = refresh
» Save = submit
• Grids have limits
» 500,000 cell limit when reading
» 200,000 cell limit when saving
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
15. Groovy Grid Builder – Deep Dive • Kyle GoodfriendODTUG • Kscope 18 15
GRIDBUILDER USE CASES
• Benefits
» Move Data from ASO to BSO to eliminate the need for consolidations
» Calculate outside of Essbase
» If the DataMap is used it bypases user security
• Creative use cases
» Mapping data when moving from cube to cube
» Clearing ASO without limits – Data Maps only clear what is in the BSO cube, not
everything in the POV
» Get POV with data (aka, suppression)
Groovy Grid Builder – Deep Dive • Kyle Goodfriend
16. GRIDBUILDER
METHODS
Before you can become productive, get to know
the methods.
16Groovy Grid Builder – Deep Dive • Kyle Goodfriend
ODTUG • Kscope 18
4
17. Groovy Grid Builder – Deep Dive • Kyle Goodfriend 17
GRID BUILDER CLASS OVERVIEW
• Classes
» DataGridBuilder (submit data)
» DataGridDefinitionBuilder (read data)
• DataGridBuilder
» Create a grid
» Specify data
» Save the data
• DataGridDefinitionBuilder
» Create a grid
» Retrieve the data
» Can use functions
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
19. 19
DATAGRIDBUILDER EXAMPLE
// Setup the connection to the plan type
Cube cube = operation.application.getCube("Plan1")
DataGridBuilder builder = cube.getDataGridBuilder("MM/DD/YYYY")
// Setup the grid POV, Rows, and Columns
builder.addPov('Salary', 'Current', 'Local', 'BU Version_1’)
builder.addColumn('FY16', 'FY16', 'FY16’)
builder.addColumn('Jan', 'Feb', 'Mar’)
// Add rows to the grid
builder.addRow(['Department 1', 'Employee 1'], [30000, 30000, 30000])
builder.addRow(['Department 5', 'Employee 2'], [40000, 40000, 40000])
builder.addRow(['Department 1', 'Employee 3'], [30000, 30000, 30000])
// Create a status class to hold the results
DataGridBuilder.Status status = new DataGridBuilder.Status()
// Build the grid – basically a refresh/retrieve
DataGrid grid = builder.build(status)
println("Total number of cells accepted: status.numAcceptedCells")
println("Total number of cells rejected: status.numRejectedCells")
println("First 100 rejected cells: status.cellsRejected")
// Save the data to the cube
cube.saveGrid(grid)
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
20. 20
DATAGRIDDEFINITIONBUILDER EXAMPLE
// Setup the connection to the plan type
Cube cube = operation.application.getCube("Plan1")
//Create the grid definition builder
DataGridDefinitionBuilder builder = cube.dataGridDefinitionBuilder
// Add the POV – Dimensions and a collection of the members in those dimensions
builder.addPov(['Years', 'Scenario', 'Currency', 'Period', 'Version', 'Entity’],
[['FY16'], ['Current'], ['Local'], ['BegBalance'], ['BU Version_1'], ['No Entity’]])
// Add the columns – 2 parameters, collection of dimensions and
// collection of collections of members in those dimensions
builder.addColumn(['Years', 'Account’],
[['Children(Years)'],['Min Salary','Max Salary','Min Bonus','Max Bonus']])
// Add rows no data - in this class as it is retrieving data
builder.addRow(['Grades'], [ ['ILvl0Descendants("Grades")']])
// Build the grid
DataGridDefinition gridDefinition = builder.build()
// Load a data grid from the specified grid definition and cube
DataGrid dataGrid = cube.loadGrid(gridDefinition, false)
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
21. REAL WORLD
EXAMPLES
A walk through gridbuilder use cases
ODTUG • Kscope 18
Groovy Grid Builder – Deep Dive • Kyle Goodfriend 21
5
22. 22
DEMONSTRATION
CLEAR ASO DATA
• DataMaps won’t work when removing
data in the BSO application first
» Removing TBHs
» Removing new products
• Clearing data when the Smart Push
clear limits are reached
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
23. 23
SCRIPT SETUP
/*RTPS: {RTP_YesNoClearBlk} {RTP_Vendor}*/
def mbUs = messageBundle(["validation.AbortClear":"You have chosen to NOT clear the selected Brand Family. No Action
has been taken. To proceed with clearing, please acknowledge by selecting (YES) from the drop down menu. Otherwise
please click (Cancel). "])
def mbl = messageBundleLoader(["en" : mbUs])
//If yes, proceed to second rule in rule set
if(rtps.RTP_YesNoClearBlk.getEssbaseValue() != "1")
{
println rtps.RTP_YesNoClearBlk.getEssbaseValue()
println "The user cancelled the operation"
throwVetoException(mbl, "validation.AbortClear", rtps.RTP_YesNoClearBlk)
}
//set account map
def acctMap = ['Regular_Cases':'Regular_Cases',
'Net_Sales':'42001',
'Cost_of_Sales_without_Samples':'50001',
'Gallonage_Tax':'50015',
'Depletion_Allowance_Manual_Chargeback':'56010',
'Gain_Loss_Inv_Reval':'50010',
'Supplier_Commitments':'56055',
'Supplier_Spend_Non_Committed':'56300',
'Samples':'56092'
]
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
27. 27
PERFORMANCE AND PROCESS
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
99%IMPROVEMENT 98% 99%
Reporting includes all updates from
detailed modules (product, Capex,
workforce, and similar modules) and
is included in
real time as changes are made
Consolidated Reporting
Reporting includes all updates from
detailed modules (product, Capex,
workforce, and similar modules) at
scheduled intervals
users have to wait to see
consolidated information
Groovy eliminates the need to
consolidate the BSO cube and
copies data directly from the
ASO cube at a consolidated
level
.2 Seconds
Dimensions are consolidated
and copied to the P&L model
82.9 Seconds
Consolidated P&L
Product detailed dimensions
are consolidated and moved
to the P&L model
Groovy selects only the cells
that where edited and copies
only what changed to the
reporting model
1.0 Seconds
All data on the form is
synchronized
14.5 Seconds
Smart Push
Data synchronizes to the
reporting cube for analysis
01
0110
0001
01101
Groovy selects only edited
cells and executes the logic
on only products and periods
that changed
0.3 Seconds
All products on the form are
calculated
26.1 Seconds
Business Logic
Growth rates are entered at
total product breakouts and
allocated to the detailed level
With the inclusion of Groovy
and access to the Java API,
more customization can be
integrated to maximum
performance and achieve real
time consolidated reporting
Submit
Planner Input
User submits updates to the
Gross Profit model at a
detailed product level that
exists at a more granular level
than in the P&L model
28. 28
TYPICAL CONSOLIDATION VS GRIDBUILDER
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
Detailed
App
Consolidated
P&L
Detailed
App
Consolidated
P&L
NON GROOVY
• All dimensions need to be
consolidated
• Movement from ASO is not possible
• Movement is batched and scheduled
WITH GROOVY
• NO BSO consolidation is required
• Data can be transferred from ASO
• Movement is executed on form
save
29. 29
SETTING UP THE VARIABLES AND PUSHING DATA
def startTime = currentTimeMillis()
def procTime = currentTimeMillis()
def elapsed=(currentTimeMillis()-startTime)/1000
Calendar calendar = Calendar.getInstance()
calendar.setTimeInMillis(currentTimeMillis())
def now = calendar.getTime()
def dtstmp = now.format("MM/dd/yyyy")
elapsed=(currentTimeMillis()-procTime)/1000
procTime = currentTimeMillis()
println "****************************************************"
println "Time taken for allocation and consolidation = $elapsed secs"
println "Total Time = " + (currentTimeMillis()-startTime)/1000 + " secs"
println "****************************************************"
//****************************************************************************
// Data Movement between Apps
//****************************************************************************
// Get POV
String sCompany = operation.grid.getCellWithMembers().getMemberName("Company")
def sMaterialGroup = operation.grid.getCellWithMembers().getMemberName("Material_Group")
String sChannel = operation.grid.getCellWithMembers().getMemberName("Channel")
// Get a list of edited rows
def lstVendors = []
operation.grid.dataCellIterator({DataCell cell -> cell.edited}).each{
lstVendors.add(it.getMemberName("Vendor"))
}
String strVendors = """"${lstVendors.unique().join('","')}""""
println "data push running for " + strVendors
if(operation.grid.hasSmartPush("GP_SmartPush") && lstVendors)
operation.grid.getSmartPush("GP_SmartPush").execute(["Vendor":strVendors,"Currency":'"Local","USD”’])
elapsed=(currentTimeMillis()-procTime)/1000
procTime = currentTimeMillis()
println "****************************************************"
println "Time taken for data push = $elapsed secs"
println "Total Time = " + (currentTimeMillis()-startTime)/1000 + " secs"
println "****************************************************"
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
32. 32
EXECUTING THE SUBMISSION FORMS
DataGridBuilder.Status status = new DataGridBuilder.Status()
DataGridBuilder.Status rstatus = new DataGridBuilder.Status()
DataGrid grid = finGrid.build(status)
DataGrid rgrid = rfinGrid.build(rstatus)
println("Total number of cells accepted: $status.numAcceptedCells")
println("Total number of cells rejected: $status.numRejectedCells")
println("First 100 rejected cells: $status.cellsRejected")
finCube.saveGrid(grid)
println("Total number of cells accepted: $rstatus.numAcceptedCells")
println("Total number of cells rejected: $rstatus.numRejectedCells")
println("First 100 rejected cells: $rstatus.cellsRejected")
rfinCube.saveGrid(rgrid)
elapsed=(currentTimeMillis()-procTime)/1000
procTime = currentTimeMillis()
println "****************************************************"
println "Time taken copy to fin = $elapsed secs"
println "Total Time = " + (currentTimeMillis()-startTime)/1000 + " secs"
println "****************************************************"
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
33. 33
DEMONSTRATION
CALCULATING
OUTSIDE OF THE
ESSBASE ENGINE
• Calculating Currency in ASO
• Connecting forms with business logic
directly to an ASO play type
» Rewrite form rate*volume or currency
conversion
» NBF calculate accounts
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
35. 35
CREATE THE CURRENCY RATES MAP
// Build currency for the company
Cube lookupCube = operation.application.getCube("GP")
DataGridDefinitionBuilder builder = lookupCube.dataGridDefinitionBuilder()
builder.addPov(['Years', 'Scenario',
'Version','Channel','Material_Group','Source','Vendor’,
'Currency','Account’],
[[sYear],[sScenario],[sVersion],['No_Channel'],['No_Material_Group’],
['Input'],['No_Vendor_Assigned'],['Local'],['End_C_Rate']])
builder.addColumn(['Period'], [ ['ILvl0Descendants("YearTotal")']])
builder.addRow(['Company'], [ [sCompany] ])
DataGridDefinition gridDefinition = builder.build()
// Load the data grid from the lookup cube
lookupCube.loadGrid(gridDefinition, false).withCloseable { dataGrid ->
dataGrid.dataCellIterator().each{ rate ->
currencyRates.put(rate.getMemberName('Period'),checkZero(rate.data))
}
}
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
36. 36
SETUP THE WRITEBACK GRID BUILDERS
// Setup Grid to submit results
// Get list of vendors
def listVendors = operation.grid.rows.headers*.essbaseMbrName.collect
{vendor, account -> return vendor}.unique()
// List of calculated members
def listAccounts = ["Regular_Cases","Net_Sales","GP_Level_1","Cost_of_Sales_without_Samples",
"GP_Level_2","Depletion_Allowance_Manual_Chargeback"]
//Fin Grid Setup
Cube finCube = operation.application.getCube("GP")
Cube rfinCube = operation.application.getCube("rGP")
DataGridBuilder bsoGrid = finCube.dataGridBuilder("MM/DD/YYYY")
DataGridBuilder aspGrid = rfinCube.dataGridBuilder("MM/DD/YYYY")
bsoGrid.addPov(sYear,sScenario,sVersion,sChannel,sMaterialGroup,sSource,sCompany)
aspGrid.addPov(sYear,sScenario,sVersion,sChannel,sMaterialGroup,sSource,sCompany,'MTD')
bsoGrid.addColumn('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')
aspGrid.addColumn('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')
def lstCurrency = ["Local","USD"]
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
37. 37
ADD THE ROWS AND VALUES TO SUBMIT (PART 1)
// loop through the grid on the form
listVendors.each{ vendor ->
listAccounts.each{ account ->
def sValues = []
def sValuesUSD = []
List addcells = new ArrayList()
List addcellsUSD = new ArrayList()
['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'].each{cMonth ->
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
40. 40
SUBMIT AND GET THE STATUS OF THE GRID BUILDER
DataGridBuilder.Status status = new DataGridBuilder.Status()
DataGridBuilder.Status rstatus = new DataGridBuilder.Status()
DataGrid grid = bsoGrid.build(status)
DataGrid rgrid = aspGrid.build(rstatus)
println("Total number of cells accepted: $status.numAcceptedCells")
println("Total number of cells rejected: $status.numRejectedCells")
println("First 100 rejected cells: $status.cellsRejected")
finCube.saveGrid(grid)
println("Total number of cells accepted: $rstatus.numAcceptedCells")
println("Total number of cells rejected: $rstatus.numRejectedCells")
println("First 100 rejected cells: $rstatus.cellsRejected")
rfinCube.saveGrid(rgrid)
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
42. 42
DEMONSTRATION
QUERYING
METADATA
• Process Segmentation
» Execute processes only on a POV with
data
» Loop through metadata and execute
processes
• Currency Conversion
» Identify whether the account should be
converted to USD
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
43. 43
PROCESS SEGMENTATION
Cube cube = operation.application.getCube("GP")
Dimension companyDim = operation.application.getDimension("Company", cube)
def Companies = companyDim.getEvaluatedMembers("ILvl0Descendants(tot_Company)", cube) as String[]
def Currencies = ["Local","USD"]
// Companies.each{company->
for (def i = 0; i < Companies.size(); i++) {
def sCompanyItem = '"' + Companies[i] + ‘”’
// Currencies.each(currency ->
for (def iCurrency = 0; iCurrency < Currencies.size(); iCurrency++){
def sCurrency = '"' + Currencies[iCurrency] + '"'
operation.application.getDataMap("GP Form Push").execute
(["Company":Companies[i],"Channel":"ILvl0Descendants(Channel)",
"Material_Group":"ILvl0Descendants(Material_Group)",
"Vendor":"ILvl0Descendants(Vendor)","Scenario":rtps.RTP_Scenario.getEssbaseValue(),
"Version":"OEP_Working","Years":rtps.RTP_Year.getEssbaseValue(),
"Source":"ILvl0Descendants(Source)","Currency":Currencies[iCurrency]],
rtps.RTP_Push.getEssbaseValue().toBoolean())
elapsed=(currentTimeMillis()-procTime)/1000
procTime = currentTimeMillis()
println "Push for Company $sCompanyItem, in ${Currencies[iCurrency]}: $elapsed seconds"
}
}
elapsed=(currentTimeMillis()-procTime)/1000
procTime = currentTimeMillis()
println "****************************************************"
println "Time taken for allocation and consolidation = $elapsed secs"
println "Total Time = " + (currentTimeMillis()-startTime)/1000 + " secs"
println "****************************************************"
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
44. 44
CURRENCY CONVERSION
boolean convertCurrency(def account='')
{
Dimension AccountDim = operation.application.getDimension("Account")
Member AccountMbr = AccountDim.getMember(account)
def memberProps = AccountMbr.toMap()
if(memberProps['UDA'].toString().contains('IgnoreCurrencyConversion'))
return false
else
return true
}
if(convertCurrency(account)){
[… do some action and convert the account (revenue * currency conversion rate)]
}
else{
[… do some action but don’t convert the account (headcount)]
}
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
45. PRODUCTIVITY,
GUIDANCE AND
SUGGESTIONS
Many people have challenges learning Groovy and
the PBCS API at the same time. Here are some
things that might help you get started
ODTUG • Kscope 18
Groovy Grid Builder – Deep Dive • Kyle Goodfriend 45
6
46. 46
SUGGESTIONS / TIPS
• Get to know maps/collections/lists and how to manipulate them
• Learn the inheritance of objects and how Groovy works with them
• Understand how to read the API
• Use closures anywhere you can
• Grow your knowledge around string manipulation
• Come up with a strategy to log the grid POV/headers/columns/data
• .crossDimCell is your best friend
I plan on posting detailed explainations of these at www.in2Hyperion.com
in the near future, along with other use cases around Groovy knowledge
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
47. WHERE TO GO NEXT
Need help? Here is a great place to start.
47
ODTUG • Kscope 18
Groovy Grid Builder – Deep Dive • Kyle Goodfriend
7
48. 48
IN2HYPERION GROOVY SERIES
• My Adventures in Groovy Calculations - Part 1
• Part 2: Data Validation
• Part 3: Acting On Edited Cells
• Part 4: Run Time Prompts
• Part 5: Accessing Run Time Prompts
• Part 6: Converting a POV into a Fix
• Part 7: Validating Run Time Prompts
• Part 8: Customizing Data Maps and Smart Pushes
• Part 9: Groovy and PBCS is Game Changing in Louisville
• Part 10: Validating Form Data
• Part 11: Accessing Metadata Properties
• Part 12: Learning and Testing Groovy Outside of PBCS
• Part 13: Returning Errors (Data Forms)
• Part 14: Returning Errors (Data Form Cells)
• Part 15: Returning Errors (RTP Edition) add enhancement and
other bug report
• Part 16: Ignore Form Save When No Data Has Been Edited
• Part 17: Force Cell Comments
• Part 18: Real Time Data Movement (Setting The Stage)
• Part 19: Real Time Reporting Webinar with Breakthru Beverage
Group
• Part 20: Groovy On-Premise vs. Groovy Cloud
• Part 21: Real Time Data Movement (Getting Groovy)
• Part 22: Looping Through Member Descendants
• Part 23: Is the POV a level 0 member?
• Part 24: Getting Member Properties?
• Part 25: The DataGridBuilders
• Part 26: Interacting with Smart Lists
• Part 27: Using Maps in Groovy as lookup Tables
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
49. INSTRUCTIONAL VIDEOS
• Real -Time Reporting in PBCS/ ePBCS
• PBCS Require Comment - Groovy Calculation
• Real Time Reporting Webinar
• Groovy Examples: Webinar Follow-up
I plan to supplement with more BLOG posts that include videos
49ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
50. 50
ORACLE AND GROOVY HOT SPOTS
• PBCS Admin guide overview
Using Groovy Rules.
• Groovy rules
Setting Business Rule Properties.
• The Groovy API Reference on the
E/PBCS library:
• Java API Reference for Oracle Enterprise
Performance Management Cloud Groovy
Rules
• The EPBCS Academy also links to the Groovy
Rules Java API Reference hosted on the library.
• Groovy Business Rule examples
• There are a lot of great books, articles, videos on
Groovy listed here:
http://groovy-lang.org/learn.html
• In particular, I would like to highlight the following
two books:
https://www.manning.com/books/groovy-in-
action-second-edition
https://pragprog.com/book/vslg2/programming-
groovy-2
• The following course on Udemy is very affordable,
and can be a useful asset:
https://www.udemy.com/apache-
groovy/learn/v4/overview
• They can also start by going over the “Language
Specification” section in the following document is
also useful:
http://groovy-lang.org/documentation.html
51. OTHER SESSIONS
Ask the Experts - Planning Panel
Jun 12th, 2018 02:15 PM - 03:15 PM
Southern Hemisphere II
Top-Down and Bottom-Up Planning at Breakthru Beverage Group
June 13th, 2018 11:45 AM - 12:45 PM
Northern Hemisphere E3
Why Groovy is Game Changing
June 13th, 2018, 3:30 PM - 4:30 PM
Northern Hemisphere E3
Last Minute ODTUG Kscope18 Planning Souvenirs You Will ACTUALLY Use!
June 14th, 9:30 - 11:00 a.m.
Southern Hemisphere II
51ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend
53. 53
A FEW PARTING GIFTS
• Question & Answer Session
• What would you like to see next at In2Hyperion.com?
» Adventures in Groovy
» Challenge Accepted
Kyle Goodfriend
kyle@in2hyperion.com
614.668.7324
ODTUG • Kscope 18 Groovy Grid Builder – Deep Dive • Kyle Goodfriend