Title: Ten Things Every OFA Developer Should Know
1Ten Things Every OFA Developer Should Know
- David Geist
- Braun Consulting
- NCOAUG 2001
- August 27, 2001
2Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
3Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
4(1) Rules for Efficient Cube Design
- Put TIME first or last, depending on how you will
process data - ACTUAL lt LINE ORG PROD TIME gt
- BUDGET lt TIME LINE ORG PROD gt
- Never put TIME in the composite
- ACTUAL lt LINE CMP lt ORG PROD TIME gtgt
- ACTUAL lt LINE CMP lt ORG PROD gt TIME gt
- Never put all your dimensions in the composite
- Never put the composite first in the dimension
order - ACTUAL lt CMP lt ORG PROD gt LINE TIME gt
- ACTUAL lt LINE CMP lt ORG PROD gt TIME gt
5(1) Rules for Efficient Cube Design
- Skinny composites generally perform better
- In a five-dimensional variable, a
three-dimensional composite will outperform a
four-dimensional composite - Find the appropriate composite where does your
sparsity truly lie? - Disk is cheap dont just put dimensions in the
composite to save disk space you may compromise
performance
6Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
7(2) Starting OFA Without the Front-End
- Several things happen when the OFA Super
workstation is started - Temporary valuesets are populated
- Variables are checked and set
- Since these items are temporary, it is generally
not possible to attach the Super personal and
query them - For batch program construction, it is helpful to
simulate the startup of OFA programmatically
8(2) Starting OFA Without the Front-End
- dtb attach /yoursuperdbapath/yoursuperdbaname.db
rw - dtb attach /yourxpdbpath/xpdb.db ro last
- call init.main(/yoursuperdbapath/)
- call da.set.lang(ENU)
- call fms.startup
- call dir.startup
- Adding this series of commands to your program
will simulate the startup of the Super
workstation, including all database attachments - You are then free to query objects and/or call
APIs (distribution, solve, etc.)
9Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
10(3) OS Scripts to Start/Stop Express TP
GUI tools may be used to start/stop Express and
the task processor, but this is not always
appropriate
- System backups that run in the wee hours, e.g.
ADSM, require Express to be down so they can
lock the DB files - Scripted exports of OFA environments should take
place with the TP down so DBs all remain
synchronized
Option 1
Train your third-shift operations staff on the
GUI tools and hope they remember Build scripts
to start and stop Express and the TP
Option 2
11(3) OS Scripts to Start/Stop Express TP
Start Script
- ! /bin/sh
- Header express_start.sh,v 1.0 00/08/21 integ
Exp -
-
- . /path/express.prm
- /path/bin/oesmgr -v -b ora_ro_tcpservername -u
oesdbaid -p oesdbapwd start ExpSrv630 -
- exit 0
12(3) OS Scripts to Start/Stop Express TP
Stop Script
- ! /bin/sh
- Header express_stop.sh,v 1.0 00/08/21 integ
Exp -
-
- mv /taskfilepath/tkrun.flg /taskfilepath/tkstop.fl
g -
- sleep 30
-
- . /path/express.prm
- /path/bin/oesmgr -v -b ora_ro_tcpservername -u
oesdbaid -p oesdbapwd -t 600 stop immediate
ExpSrv630 -
- mv /taskfilepath/tkstop.flg /taskfilepath/tkrun.fl
g -
- exit 0
13Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
14(4) Creating a File of Historical Solve Info
- Many organizations use regular hourly or daily
solves and/or solves that get triggered by
submissions of data - Since only the DBA can see when solves have
completed in the Task Queue, it is often helpful
to publish this information where the users can
see it - Using the following program, a text file of the
last n solve completions can be created - This program should be wrapped with a UNIX script
to run the program and move the resulting text
file to a web server or network location - The script can then be scheduled to run every 5
or 10 minutes
15(4) Creating a File of Historical Solve Info
- DEFINE SOLVE_HISTORY PROGRAM
- PROGRAM
-
- variable _outf integer "File
handle for output file - variable _textrow text "Row of
text -
- trap on HADERROR
- pushlevel 'SOLVE_HISTORY'
- push DATEFORMAT
-
- dtb attach /path1/ofastask ro
- _outf fileopen('/path2/filename.txt' write)
- DATEFORMAT 'ltMTEXTLgt ltDDgt, ltYYYYgt'
-
- push TK.ENTRY
- limit TK.ENTRY to TK.CATALOG(TK.PROP 'USER') eq
'AA' - limit TK.ENTRY keep TK.CATALOG(TK.PROP 'TASK')
eq 'SOLVE GROUP' or - - TK.CATALOG(TK.PROP 'TASK')
eq 'SOLVE MODEL' - limit TK.ENTRY keep TK.CATALOG(TK.PROP 'STATUS')
eq 'COMPLETED'
16(4) Creating a File of Historical Solve Info
- fileput _outf joinchars('Last 50 solve
completions as of ' TOD ' on ' TODAY) - fileput _outf ' '
-
- for TK.ENTRY
- do
- _textrow row(w 100 joinchars(extchars(blank
strip(extlines(- - TK.CATALOG(TK.PROP 'MESSAGE')
- - numlines(TK.CATALOG(TK.PROP
'MESSAGE'))-2 1) both) 1 14) - - ' ' extlines(TK.CATALOG(TK.PRO
P 'SUM') 1 1) ' completed.')) - fileput _outf _textrow
- doend
-
- fileclose _outf
- _outf NA
- dtb detach ofastask
-
17(4) Creating a File of Historical Solve Info
- ALLDONE
- poplevel 'SOLVE_HISTORY'
- if _outf ne NA
- then do
- fileclose _outf
- _outf NA
- doend
- return
-
- HADERROR
- poplevel 'SOLVE_HISTORY'
- if _outf ne NA
- then do
- fileclose _outf
- _outf NA
- doend
- if dtb(attached 'ofastask')
- then dtb detach noq ofastask
- signal errorname errortext
18(4) Creating a File of Historical Solve Info
- Heres a portion of the output file
- Last 50 solve completions as of 103012 on
February 14, 2001 -
- 02-14 102454 Forecast Hourly Process completed.
- 02-14 082423 Forecast Hourly Process completed.
- 02-14 072433 Forecast Hourly Process completed.
- 02-14 062454 Forecast Hourly Process completed.
- 02-14 043611 Actual Large Solve completed.
- 02-14 041316 Actual Monthly process completed.
- 02-14 032951 Forecast Nightly Process
completed. - 02-13 185353 Forecast Hourly Process completed.
19Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
20(5) Using Functions for Complex Modeling
OFAs modeling function is one of the powers of
the tool, extending beyond simple rollups to
perform calculations
- Heres a simple example
-
- Services Revenue Input
- Software Revenue Input
- Total Revenue Services Revenue Software
Revenue - Salary Expense Input
- Travel Expense Input
- Rent Expense Input
- Total Expense Salary Expense Travel
Expense Rent Expense - Gross Profit Total Revenue Total Expense
- Tax Rate Input
- Taxes Gross Profit Tax Rate
- Net Profit Gross Profit Taxes
21(5) Using Functions for Complex Modeling
- Frequently, the complexity of the calculation is
such that a simple model will not suffice - An Express function can be developed to perform
the complex calculation, and the function can
then be utilized in the model - As an example, lets look at a salary forecasting
model operating on the following FDIs - BUDGET lt LINE ORG TIME gt (DECIMAL)
- EMP_SALARY lt EMPLOYEE TIME gt (DECIMAL)
- EMP_TEXT_INFO lt EMPLOYEE INFO TIME gt (TEXT)
22(5) Using Functions for Complex Modeling
- Users are budgeting employee salaries in the
EMP_SALARY cube - Users are projecting future changes in each
employees department or status (retired,
severed, inactive) in the EMP_TEXT_INFO cube - Since budget is not dimensioned by employee, need
to figure out salary cost for each department in
each future period, taking into account the
future changes - Because two other FDIs must be combined and
manipulated using LIMIT commands to produce the
result, a simple model would not do the trick
23(5) Using Functions for Complex Modeling
- Define a program with a datatype of DECIMAL to do
the calculation - DEFINE SALARY_MODEL PROGRAM DECIMAL
- PROGRAM
-
- argument _org ORG "Org
value coming in - variable _budget decimal "Budget
value to return -
- trap on HADERROR
- pushlevel 'SALARY_MODEL'
- push EMPLOYEE
-
- NASKIP2 YES
- OKNULLSTATUS YES
-
- Limit EMPLOYEE to all those who are
members of the org in question in the time - period for which the model is operating.
If none are found, skip to the end. -
- limit EMPLOYEE to upcase(EMP_TEXT_INFO(INFO
'ORG')) eq charlist(_org)
24(5) Using Functions for Complex Modeling
- " Keep the EMPLOYEEs who are not retired,
severed, or inactive in this time period. - If none are found, skip to the end.
-
- limit EMPLOYEE keep not inlist(RETIRED\nSEVERED\
nINACTIVE -
upcase(EMP_TEXT_INFO(INFO STATUS))) - ifnone ALLDONE
-
- Calculate the total salary for the
EMPLOYEEs that met the criteria -
- _budget total(EMP_SALARY)
-
- ALLDONE
- poplevel 'SALARY_MODEL'
- return _budget
-
- HADERROR
- if ERRORNAME eq 'QUIT' or ERRORNAME eq 'ATTN'
- then goto ALLDONE
- poplevel 'SALARY_MODEL'
25(5) Using Functions for Complex Modeling
- Test the function by reporting it at the command
line - When the results are correct, refer to the
function in the model - Services Revenue Input
- Software Revenue Input
- Total Revenue Services Revenue Software
Revenue - Salary Expense SALARY_MODEL(ORG)
- Travel Expense Input
- Rent Expense Input
- Total Expense Salary Expense Travel
Expense Rent Expense - Etc
Disadvantage of this Technique
The nature of the salary calculation is hidden
from the users in the model view
26Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
27(6) Capturing OFAs Instructions to Express
- OFA is a Visual Basic application issuing Express
SPL instructions to the underlying databases - To reproduce an OFA front-end function with a
program, these instructions must simply be
captured - Open the Express Monitor within an OFA
workstation - Type dbgoutfile /path/filename.extension
(e.g. dbgoutfile /olap_home/list.txt) - Type ifcopy yes
- Leave Express Monitor open
- Perform the OFA function you wish to capture
- Return to the Express Monitor window
- Type dbgoutfile eof
28(6) Capturing OFAs Instructions to Express
- The resulting text file can be viewed with
Notepad - Heres the last portion of a file resulting from
my capture of the creation of a Group Solve
called Test Group Solve - -gtcall CheckDesc('SS.ENTRY', 'Test Group
Solve','') - -gtcall ct.add.Entry('SS.CATALOG',
'Dummy','DESCRIPTION', 'Test Group Solve') - -gtcall XapiUpdate
- -gtlimit SS.ENTRY to 10
- -gtfetch SS.ENTRY TAG '1'
- -gtfetch ct.get.val('SS.CATALOG',
values(SS.ENTRY), 'CLASS') TAG '2' - -gtfetch ct.get.val('SS.CATALOG',
values(SS.ENTRY), 'DESCRIPTION') TAG '3' - -gtcall ss.clean.Entry(values(ss.Entry))
- -gtfetch convert(numlines(ss.catalog(ss.prop
'LIST')), text) TAG '4' - -gtfetch ss.catalog(ss.prop 'LIST') TAG '5'
- -gtfetch ss.catalog(ss.prop 'TYPES') TAG '6'
- -gt
- -gtcall ct.put.val('SS.CATALOG', 'SS.AA39194',
'LIST', 'SO.FX89196\nSO.FX43859\nSO.FX68598') - -gtcall ct.put.val('SS.CATALOG', 'SS.AA39194',
'TYPES', 'SOLVE\nSOLVE\nSOLVE') - -gtcall XapiUpdate
- -gtdbgoutfile eof
29(6) Capturing OFAs Instructions to Express
- After I typed in Test Group Solve and clicked
Save, the CheckDesc program was called to
determine if the description conflicted with an
existing solve - CT.ADD.ENTRY physically added the solve, and the
six FETCH commands are populating the blank solve
form - I picked three Solves to be part of the Group
Solve that drove the two calls to CT.PUT.VAL to
populate two properties in the SS.CATALOG - To create a group solve with a program, I would
simply discard the FETCH statements and use the
rest of the commands in my program - This will work for almost any OFA front-end
function
30Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
31(7) Locating Empty Nesters in Hierarchies
- In most OFA systems, data are aggregated and
stored at parent levels in hierarchies - When a hierarchy changes, the data must be
re-aggregated to correct the parent totals - However, a certain situation sometimes arises in
which re-aggregation will not fix the problem
32(7) Locating Empty Nesters in Hierarchies
- Assume the following simple organizational
hierarchy and rolled up data
33(7) Locating Empty Nesters in Hierarchies
- Now, suppose hierarchy maintenance occurs which
moves cost center 5 from business unit 3 to
business unit 2 the data must be re-aggregated
to correct the parents
34(7) Locating Empty Nesters in Hierarchies
- If cost center 6 is subsequently moved from
business unit 3 to business unit 2, leaving no
children (an empty nest) at business unit 3, a
re-aggregation will NOT correct the parent-level
data
35(7) Locating Empty Nesters in Hierarchies
- In organizations with thousands of dimension
values this can be difficult to spot especially
if hierarchies are maintained programmatically
(i.e. with data loaders) - The following code can be used to identify these
problem values the DBA can then choose to wipe
out their data, remove them from the hierarchy,
or delete them from the system - Since there is no transactional record of
hierarchy changes in OFA, a text variable can be
used to store a previous list of parents for
comparison Ive used ORG_PARENTS in this example
36(7) Locating Empty Nesters in Hierarchies
- DEFINE STRANDED_PRNT PROGRAM
- PROGRAM
- "Find all ORGs which have no children now but
did have children prior to last - Hierarchy maintenance
-
- push ORG OKNULLSTATUS
- OKNULLSTATUS YES
-
- Limit ORG to current list of hierarchy
participants that have no children -
- limit ORG to all
- limit ORG keep ancestors
- limit ORG add descendants
- limit ORG remove ancestors
37(7) Locating Empty Nesters in Hierarchies
- Keep any ORGs that were previously parents
-
- limit ORG keep inlist(charlist(ORG_PARENTS) ORG)
- if statlen(ORG) gt 0
- then do
- for ORG
- do
- show joinchars('This leaf ORG previously
had children ' ORG) - doend
- doend
- else show There are no problem ORGs at this
time. -
- ALLDONE
- pop ORG OKNULLSTATUS
- return
- END
38(7) Locating Empty Nesters in Hierarchies
- After running the program and taking corrective
action, the ORG_PARENTS variable should then be
set to the current list of parents - DEFINE POP_ORG_PARENTS PROGRAM
- PROGRAM
-
- push ORG OKNULLSTATUS
- OKNULLSTATUS YES
-
- Limit ORG to current list of hierarchy
participants that are parents -
- limit ORG to all
- limit ORG keep ancestors
-
- Set list of parents into ORG_PARENTS
-
- ORG_PARENTS charlist(ORG)
-
- ALLDONE
- pop ORG OKNULLSTATUS
39Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
40(8) Dimension Values Submitted/Not Submitted
- During the budgeting cycle, it may be useful to
identify which dimension values have had data
submitted for them and which have not - This information can be derived manually from the
task queue, but that process can be tedious - The information can instead be derived
programmatically from the TK.CATALOG in the
OFASTASK database with the following code - This example will identify dimension values
submitted for an example that will identify
dimension values not submitted, see the white
paper
41(8) Dimension Values Submitted/Not Submitted
- DEFINE DV_SUBMITTED PROGRAM
- PROGRAM
- variable _dvlist text "Dim
values submitted -
- pushlevel 'DV_SUBMITTED'
-
- Replace DIM in the push command below with
the object name of your dim - such as COST_CTR or PROD
-
- push TK.ENTRY -
- TK.PROP -
- DIM
-
- Get all tasks, then filter out submissions
from the Super (AA). The - DET property holds the Details field in
the Task database. -
- dtb attach /path/ofastask.db
- limit TK.ENTRY to all
- limit TK.ENTRY keep TK.CATALOG(TK.PROP 'USER')
ne 'AA'
42(8) Dimension Values Submitted/Not Submitted
- Loop over tasks, looking for indication
that Dim was involved (replace - Dim with the mixed-case user-friendly
description of your dimension, such - as Cost Center or Product)
-
- for TK.ENTRY
- do
- if findchars(joinchars(TK.CATALOG)
'Dimension Dim') gt 0 - then do
- _dvlist joinlines(_dvlist -
- blankstrip(extlines(e
xtchars(TK.CATALOG - - findchars(joinchars
(TK.CATALOG) - -
'Dimension Dim')) 2 1) both)) - doend
- doend
-
- A dimension value may be submitted more
than once, so use uniquelines to - remove duplicates from the list
-
- show joinchars('Prior to unique '
numlines(_dvlist))
43(8) Dimension Values Submitted/Not Submitted
- Sort the dimension values alphabetically
by their - descriptions, and produce report
-
- sort DIM a DIMPREFIX.DESC
- row w 80 Dims that have submitted data'
- for DIM
- do
- row w 4 skip w 75 extchars(DIMPREFIX.DESC 1
75) - doend
-
- ALLDONE
- return
-
- HADERROR
- signal errorname errortext
- return
- END
44Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
45(9) Reporting a List of Users and Their Access
- The distribution report in OFA provides this
information, but when the numbers of users and
dimension values are high, the report is
cumbersome - The code below will produce a file of users
sorted alphabetically by name and list their
access to individual dimension values - That resulting flat file can be pulled into Excel
for easy sorting, slicing, and dicing
46(9) Reporting a List of Users and Their Access
- DEFINE USER_ACCESS PROGRAM
- PROGRAM
- variable _counter1 integer "Counter
-
- trap on HADERROR
-
- Set up the list of users for whom youd
like to see access -
- push USER OKNULLSTATUS DIM
- limit USER to all
- Generally you want to remove AA and
SHARED, as they would have - access to all
- limit USER remove 'AA' 'SHARED'
- Include this line if you want to see only
the web users, for example - limit USER keep USER.CATALOG(user.prop 'TYPE')
eq 'EXTERNAL' - OKNULLSTATUS YES
-
- outfile /path/filename.txt
-
47(9) Reporting a List of Users and Their Access
- for USER
- do
- _counter1 0
- limit DIM to UAD.DIMPREFIX ne na and
UAD.DIMPREFIX gt 0 - while _counter1 lt statlen(DIM)
- do
- row w 20 USER.CATALOG(USER.PROP
'DESCRIPTION') - - w 40 USER.CATALOG(USER.PROP
'COMMENT') - - w 20 extlines(joinlines(charlist(DIM)
) _counter11 1) - _counter1 _counter1 1
- doend
- if statlen(DIM) eq 0
- then row w 20 user.catalog(user.prop
'DESCRIPTION') - - w 40 user.catalog(user.prop
'COMMENT') - - w 20 'None'
-
- doend
-
- ALLDONE
48(9) Reporting a List of Users and Their Access
- Heres a portion of the output of the program
-
- eabadaba Abadaba, Edward
EN8100.811588 - rackerman Ackerman, Ralph
EN4500.400920 - madana Adana, Maureen
EN662.O - madana Adana, Maureen
EN662.TG - kadelhpa Adelpha, Kurt
EN4000.410601 - jbaker Baker, James
EN671.438 - jbaker Baker, James
EN671.446 - jbaker Baker, James
EN671.952 - jbaker Baker, James
EN672.951 - jbarbarella Barbarella, Jane
EN635.548030 - abeeker Beeker, Alan
EN6000.501 - cchan Chan, Charlie
EN601.70N7808 - cchan Chan, Charlie
EN661.DC5001
49Agenda
- Introduction
- 1 Rules for Efficient Cube Design
- 2 Starting OFA Without the Front-End
- 3 OS Scripts to Start/Stop Express and TP
- 4 Creating a File of Historical Solve
Information - 5 Using Functions for Complex Modeling
- 6 Capturing OFAs Instructions to Express
- 7 Locating Empty-Nesters in Hierarchies
- 8 Identifying Dimension Values
Submitted/Not Submitted - 9 Reporting a List of Users and Their
Access - 10 Other Resources
- QA
50(10) Other Resources
- Any Oracle customer can register for MetaLink
(http//metalink.oracle.com) - Discussion forums
- Technical notes on OFA meta data, hooks to
customize OFA, database design guide - Product documentation
- Bug database
- Business Intelligence Group Special Interest
Group (BIG SIG) of the IOUG-A - Discussion forum
- Listserve http//ls2.ioug.org/cgi-bin/lyris.pl?e
nterioug-bigsigtext_mode0 - Regular newsletter and conference calls
51Questions?
Ten Things Every OFA Developer Should Know
52Ten Things Every OFA Developer Should Know
- David Geist
- Braun Consulting
- dgeist_at_braunconsult.com
- (312) 984.7149
- NCOAUG 2001
- August 27, 2001