10 дек. 2010 г.

Запуск calc скриптов

Предлагаю 2 варианта запуска calc скриптов Essbase c параметрами через MaxL:

1. Используем подстановочные переменные (substitution variables ):

Создаем переменные:
   alter application Sample add variable 'vScenario';
   alter application Sample add variable 'vVersion';

   или через EAS консоль:


Создаем в кубе Sample.Basic calc скрипт Agg_test.csc:
FIX (&vScenario, &vEntity) 
 CALC DIM (Account, Period, Entity...)
ENDFIX
Создаем MaxL Agg_test.mxl:
login admin identified by 'password' on localhost;

spool on to "Maxl.log";
set timestamp on;

set inputScenario  = $1;
set inputVersion    = $2;

alter application Sample set variable "vScenario"  "$inputScenario";
alter application Sample set variable "vVersion"   "$inputVersion";

execute calculation Sample.Basic.Agg_test;

exit;
Запускаем MaxL:
essmsh Agg_test.mxl BUD VR_Work
 
2. Используем возможности MaxL

Создаем MaxL Agg_test2.mxl:
login admin identified by 'password' on localhost;

spool on to "Maxl.log";
set timestamp on;

set inputScenario  = $1;
set inputVersion    = $2;

execute calculation "
FIX ($inputScenario, $inputVersion)
 CALC DIM (Account, Period, Entity...)
ENDFIX
" on Sample.Basic;

exit;
Запускаем MaxL:
essmsh Agg_test2.mxl BUD VR_Work
В итоге результат будет достигнут аналогично п.1, но в данном случае не надо создавать отдельный calc скрипт и подстановочные переменные.

3. Дополнительная информация.

Чем отличается скрипт в ' ' от скрипта в " "?
vYear=FY10
Execute Calculation "FIX ($vYear)" on Sample.Basic /* правильно */
Execute Calculation 'FIX ($vYear)' on Sample.Basic /* не правильно */
В результате код первого скрипта будет - FIX (FY10), а код второго скрипта останется без изменения - FIX ($vYear), что приведет к ошибке. Т.е. если данные заключены в одинарные кавычки, то подстановка переменных не происходит.

Не используйте в кодах измерений Outline символы ".", пробел и прочие спец. символы т.к. это приводит к усложнению написания скриптов т.к. необходимо применять символ '/'.
Если не поставить "/" перед "." и не взять код элемента, в котором есть пробел в кавычки, MaxL будет сообщать об ошибке.

Не правильно:
Execute Calculation "
FIX ($vYear, Moscow.01, "Moscow 02")
  CALC DIM (Account, Period) 
ENDFIX" on Sample.Basic
Правильно:
Execute Calculation "FIX ($vYear, Moscow/.01, /"Moscow 02/")
  CALC DIM (Account, Period) 
ENDFIX" on Sample.Basic
Правильно, но подстановка невозможна:
Execute Calculation '
FIX (FY10, "Moscow.01", "Moscow 02")
  CALC DIM (Account, Period) 
ENDFIX' on Sample.Basic

23 нояб. 2010 г.

XREF vs Partitions

Наверное на каждом проекте мы сталкиваемся с необходимостью обмениваться данными между кубами. Для этого в Essbase есть специальные инструменты: XREF, Replicated Partition, Transparent Partition.

Рассмотрим их по порядку.

XREF - cамый простой и безболезненый способ получить данные из другого куба, минусы - это низкая производительность и проблемы с созданием блоков (в 11.1.2 добавили @XWRITE). Не рекомендую использовать XREF в формулах динамических элементов (Dynamic Calc) т.к. на больших срезах это приводит к потере производительности.
Пример использования: получить значение по ограниченному срезу.

Replicated partition -  если вам надо копировать блоки нижнего уровня 1:1 без всяких расчетов и транформаций, то что надо. Есть функциональность по переносу только обновленных данных.
Пример использования: передать данные по статье A по нижнему уровню из Source в Target.

Дополнительная информация - http://essbase.ru/2010/10/replicated-partitions/

Transparent partition - мощный инструмент для маштабирования. Если сравнивать с Oracle RDB - это аналог view или updateable view. Имеет ряд особенностей связанных с тем, что данные не хранятся в Target кубе, а подтягиваются налету. Пример: в Target по данным из партиции невозможно создать блоки, выгрузить данные с помощью Dataexport и т.д. Но что очень интерестно - из Target можно обновлять данные в Source!
Пример использования: разделение приложения на Факт и План с партицией по сценарию, разделение по странам, версиям и т.д.

Дополнительная информация - http://essbase.ru/2010/10/transparent-partition/

Сравнительная таблица:

* в 11.1.2 добавлена функция @XWRITE, которая позволяет записывать данные в Target
** данные изменяются только после запуска обновления партиции или вызова XREF
*** write-back функциональность

Пример MaxL создание Replicated partition и ее обновление:
create or replace replicated partition 'RP_ACT'.'RP'
area '"ACT"' sourcearea1
to 'RP_BUD'.'RP'
area '"ACT"' targetarea1;

refresh replicated partition RP_ACT.RP to RP_BUD.RP at 'localhost' all data;

refresh replicated partition RP_ACT.RP to RP_BUD.RP at 'localhost' updated data; 

P.S. Выгрузка и загрузка данных с помощью Dataexport, Report script, MDX в данном случае не рассматривались
P.S.S. Source - это куб источник. Target - куб получатель данных.
P.S.S.S. Если производительности XREF не хватает, смотрите в сторону партиций. Если партиции не устраивают, то используйте Dataexport

10 нояб. 2010 г.

Берегись пустых блоков

Агрегирует ли Essbase пустые блоки? Сейчас узнаем.

1. Очищаем куб Sample.Basic и смотрим количество существующих блоков:
2. Вводим число 1.
3. Меняем 1 на #Missing
4. Смотрим количество существующих блоков:
  • Existing level 0 blocks - 1
  • Existing upper-level blocks - 0
5. Запускаем скрипт агрегации:

     SET AGGMISSG ON;
     CALC ALL;

6. Смотрим количество существующих блоков:
  • Existing level 0 blocks - 1
  • Existing upper-level blocks - 8!!!

Вывод - независимо от того есть ли данные в какой-либо ячейке или нет Essbase агрегирует данные (создает блоки верхнего уровня), что приводит к увеличению времени расчета и увеличению размера БД.

Что делать - удалить пусты блоки можно командой "CLEARBLOCK Empty;"

Как еще бороться с ненужными данными:
  • Удаляйте нули (часто пользователи вместо #Missing вносят "0")
  • Правильно удаляйте ненужные срезы командами CLEARBLOCK или CLEARDATA (не фиксируйте плотные элементы).
  • Выгружайте нулевой срез в реляционную таблицу и анализируйте данные (часто много ненужных цифр залипают на Begbalance, архивных статьях и т.д.)

P.S. Еще один пример скрипта и его краткого лога, где агрегация работает неэффективно
/* параметр логировая */
SET MSG SUMMARY;

/* удаляем все блоки*/
CLEARBLOCK ALL;

/* создаем один блок c Jan = 100*/
SET CREATENONMISSINGBLK ON;
FIX ("New York",    "100-10",    "Sales", "Actual")
    "Jan" = 100;
ENDFIX
SET CREATENONMISSINGBLK OFF;

/* агрегируем Feb */
SET AGGMISSG ON;
FIX ("Feb")
   CALC DIM ("Measures", "Product", "Market", "Scenario");
ENDFIX
/* удалили */
Clearing all data blocks from [(ALL)] partition
Removed [9] data blocks

/* создали один блок */
Calculating [ Year(Jan)] with fixed members [Sales; 100-10; New York; Actual]
Create Blocks on Equations: [Enabled]
Create Non #Missing Blocks: [Enabled]
Total Block Created: [1.0000e+000] Blocks

/* создали 7 блоков */ 
Calculating [ Measures, Scenario, Product, Market, with fixed members [Year(Feb)]
Aggregate #Missing values:  [Enabled]
Total Block Created: [7.0000e+000] Blocks
Я сделал запись в Jan, а агрегировал по Feb - все равно блоки создаются. Это конечно же не ошибка, а особенность работы Essbase, которую надо учитывать.

8 нояб. 2010 г.

Hyperion Roadmap 2011

Hyperion Essbase 11.1.3
  • Full integration with BI Foundation installation
  • Oracle Business Intelligence Essbase Integrator
  • Fusion Middleware Integration
  • Active-Active high availability clustering
  • User-defined objects
  • ASO calc extensions
  • Storage optimization
  • Metadata integration
  • Fast-restructure of ASO outline changes
  • BSO restructure performance improvements
  • Parallel-calc performance improvements
  • Enterprise Manager replace EAS admin functionality
  • Unify capabilities in Studio and EAS
  • Essbase as a Studio Source

Hyperion EPM 11.1.3
  • New Project Planning module
  • New Chart of Accounts Manager module
  • Portfolio wide Enterprise 2.0 adoption
  • Hyperion Financial Management
    • Configurable Dimensionality
  • Financial Close
    • Variance Monitoring
  • Disclosure Management
    • Collaborative document authoring
    • Smart Rounding & Footing
  • Hyperion Planning
    • PSB Commitment control
    • Valid combinations
    • ASO Integration
http://www.oracle.com/ocom/groups/public/@opnpublic/documents/webcontent/177623.pdf

2 нояб. 2010 г.

Парсер логов calcmgrlaunch.log

Предлагаю вашему вниманию парсер логов расчетов Calc Manager 11.1.1.x. Данный парсер ищет окончание расчета и выводит результат в удобном виде.

1. Скачиваем файл Excel с макросом BR_log.xls

2. Копируем файл /logs/calcmgr/calcmgrlaunch.log на локальный компьютер

3. Открываем BR_log.xls и жмем кнопку "Open calcmgrlaunch.log"


3. Наслаждаемся видом :)



P.S. Файл лога обязательно должен называться calcmgrlaunch.log

24 окт. 2010 г.

Dynamic Calc Members (BSO)

Когда же лучше всего использовать динамические элементы в BSO-кубах?


1. Плотные (dense) измерения

Использовать нужно всегда т.к. это ведет к уменьшению размера блока => размер куба будет меньше => производительность расчетов улучшится, производительность извлечения данных (retrieve) меняется незначительно +/- 1%! Необходимо только избегать динамических элементов с комплексными формулами т.е. когда при расчете формулы необходимо смотреть в другие блоки. Кандидаты на изменения типа храния на динамический - родители или любой элемент с простой формулой.

Примеры (Период и Статья - плотные, Страна - разряженные):
  • Кварталы (Q1, Q2, Q3, Q4)  - можно сделать динамическими
  • (+) Acc_Total: Выручка итого
        (+) Acc_01: Выручка A
        (+) Acc_02: Выручка Б
    Статью Acc_Total можно сделать динамической
  • Статья: Prof_01 = Acc_01 / Acc_Total - можно сделать динамической (расчет в пределах одного блока)
     
  • Статья: Prof_Russia =  Acc_Total->Entity_Russia - нужно делать хранимой т.к. при распаковке любого блока (расчете или просмотре) Essbase будет смотреть на блок по стране Entity_Russia


2. Разряженные (sparse) измерения

Использовать  можно только для уменьшения времени агрегации, при этом ухудшается время извлечения данных (retrieve).

Пример:
  • (+) Entity_Russia - dynamic
        (+) Entity_Msc - store
        (+) Entity_Spb - store
    Если пользователь строит запрос по Entity_Russia, то серверу необходимо прочитать 2 дополнительных блока по Msc и Spb
Когда не нужно делать динамическими плотные элементы:
  • Когда элемент участвует в выгрузках (report script, dataexport)
  • Когда элемент участвует в партициях
  • Когда элемент участвует в создании блоков (datacopy с динамических элементов не работает)
  • Когда на элементе хранят расчетные данные (аллокации, элиминации)

3. Выводы

Динамические элементы - это хорошая возможность улучшить производительность, но конечно же со своей спецификой.

15 окт. 2010 г.

История одной оптимизации

Часть 1. Как было настроено до оптимизации

Настройки Essbase.cfg
...
CALCCACHEHIGH    200000000 
CALCCACHEDEFAULT 50000000 
CALCCACHELOW     10000000
...

Порядок измерений (песочные часы):

Dimension                    Type    Declared Size  Actual Size
=============================================
Account                          DENSE   809            785
Period                             DENSE   20               18
Currency Rates               SPARSE  6                  5
Scenario                         SPARSE  7                  6
SparseDimA                   SPARSE  8                  6
Years                             SPARSE  8                  7
Currency                        SPARSE  10                8
Version                          SPARSE  15               15
SparseDimB                  SPARSE  17                13
SparseDimC                  SPARSE  125            122
SparseDimD                  SPARSE  125            124
Entity                             SPARSE  198            196
SparseDimE                  SPARSE  199            197
SparseDimF                  SPARSE  288            144

Скрипт агрегации:
SET CACHE ALL;
SET CACHE HIGH;
SET AGGMISSG ON;
SET UPDATECALC OFF;
SET FRMLBOTTOMUP ON;
SET MSG SUMMARY;
SET LOCKBLOCK HIGH;
SET EMPTYMEMBERSETS ON;

FIX(InputValue, FY10, RUR, Work, Budget)

       CALC DIM (Account, Period, SparseDimA, SparseDimB...)

ENDFIX

Часть 2. Что получилось улучшить

1. Сделал динамическими родителей в измерениях Period и Account  +25%

      Размер блока:
  • было  Account(785) х Period(18) х 8байт =  113040
  • стало  Account(705) х Period(13) х 8байт = 73320 (~уменьшился на 30%)

    P.S. Не делайте динамическими dense элементы с комплексными формулами (есть ссылка на другой блок)

2. Изменил порядок измерений +15%:
  • Dense - от большего к меньшему
  • Sparse - от меньшего агрегируемого к большему, неагрегируемые измерения, большие плоские измерения для паралельных вычислений

Dimension                    Type    Declared Size  Actual Size
=============================================
/* Dense от большего к меньшему */
Account                          DENSE   809            705
Period                             DENSE   20               13
/* Агрегируемые */
SparseDimC                  SPARSE  125            122
SparseDimD                  SPARSE  125            124
SparseDimE                  SPARSE  199            197
SparseDimA                  SPARSE  8                  6
SparseDimB                  SPARSE  17                13
/* Прочие (неагрегируемые) измерения */
Currency Rates               SPARSE  6                  5
Scenario                         SPARSE  7                  6
Years                             SPARSE  8                  7
Currency                        SPARSE  10                8
Version                          SPARSE  15               15
/* Измерения для параллельных расчетов */
Entity                             SPARSE  198            196
SparseDimF                  SPARSE  288            144

    P.S. Измерения  SparseDimA и SparseDimB логичнее поставить выше, но на них не хватит CalcCache, поэтому эти измерения перемещены ниже
    P.S.S. Какие sparse измерения необходимо переместить вниз, а какие вверх определяется только опытным путем т.е. тестируем-тестируем-тестируем

3. Включил параллельные вычисления +40%

    SET CALCPARALLEL 4;
    SET CALCTASKDIMS 2;

4. Расчитал Calculator Cache +5%
   SparseDimC (122) х SparseDimD(124) х SparseDimE (197) х 8байт / 1024 = 23 282 кб

Изменения в essbase.cfg
...
CALCCACHEHIGH    200000000 
CALCCACHEDEFAULT 50000000 
CALCCACHELOW     25000000
...


5. Изменил скрипт агрегации +50%

SET CACHE ALL;
SET CACHE LOW; /* 25Мб */;

SET AGGMISSG ON;
SET UPDATECALC OFF;
SET FRMLBOTTOMUP ON;
SET MSG SUMMARY;
SET LOCKBLOCK HIGH;
SET EMPTYMEMBERSETS ON; 

SET CALCPARALLEL 4;
SET CALCTASKDIMS 2;
/* WaterFall agreggetion */ FIX(InputValue, FY10, RUR, Work, Budget, @RELATIVE(YearTotal,0)) /*main*/ FIX(@RELATIVE(&vEntity,0)) FIX(@RELATIVE(SparseDimA,0)) FIX(@RELATIVE(SparseDimB,0)) FIX(@RELATIVE(SparseDimC,0)) FIX(@RELATIVE(SparseDimD,0)) FIX(@RELATIVE(SparseDimE,0)) FIX(@RELATIVE(SparseDimF,0)) CALC DIM (Account); ENDFIX FIX(@DESCENDANTS(Account)) AGG(SparseDimF); ENDFIX ENDFIX /*SparseDimF*/ FIX(@DESCENDANTS(Account) @DESCENDANTS(SparseDimF)) AGG(SparseDimE); ENDFIX ENDFIX /*SparseDimD*/ FIX(@DESCENDANTS(Account) @DESCENDANTS(SparseDimF) @DESCENDANTS(SparseDimE)) AGG(SparseDimD); ENDFIX ENDFIX /*SparseDimC*/ FIX(@DESCENDANTS(Account) @DESCENDANTS(SparseDimF) @DESCENDANTS(SparseDimE) @DESCENDANTS(SparseDimD)) AGG(SparseDimC); ENDFIX ENDFIX /*SparseDimB*/ FIX(@DESCENDANTS(Account) @DESCENDANTS(SparseDimF) @DESCENDANTS(SparseDimE) @DESCENDANTS(SparseDimD) @DESCENDANTS(SparseDimC)) AGG(SparseDimB); ENDFIX ENDFIX /*SparseDimA*/ FIX(@DESCENDANTS(Account) @DESCENDANTS(SparseDimF) @DESCENDANTS(SparseDimE) @DESCENDANTS(SparseDimD) @DESCENDANTS(SparseDimC) @DESCENDANTS(SparseDimB)) AGG(SparseDimA); ENDFIX ENDFIX /*Entity*/ FIX(@DESCENDANTS(Account) @DESCENDANTS(SparseDimF) @DESCENDANTS(SparseDimE) @DESCENDANTS(SparseDimD) @DESCENDANTS(SparseDimC) @DESCENDANTS(SparseDimB) @DESCENDANTS(SparseDimA)) @IDESCENDANTS(&vEntity, -1); @ANCESTORS(&vEntity); ENDFIX ENDFIX /*main*/

Часть 3. Не забываем про стандартные рекомендации

    - ACR (Average clustering Rate) должен стремится к  1, для этого запускайте dense реструктуризацию
    - Размер блока должен быть между 10 и 100KB (может быть больше для 64 bit essbase)
    - Data cache должен быть около 12.5% от общего размера pag файлов
    - Index cache должен быть таким же как ind файлы
    - В одном приложение только 1 куб

11 окт. 2010 г.

Типовые запросы к реляционным таблицам Planning

Данные запросы создавались для версии 11.1.1.3 на БД Oracle 10g

/* Список групп */ 
SELECT g.object_name as group_nane
FROM hsp_group ug, hsp_object g
WHERE ug.group_id = g.OBJECT_ID
ORDER by ug.group_id; 

/* Список пользователей и групп */ 
SELECT g.object_name as group_nane, u.object_name as user_name
FROM hsp_usersingroup ug
   , hsp_object g
   , hsp_object u
WHERE ug.group_id = g.OBJECT_ID
AND ug.user_id = u.OBJECT_ID
ORDER by ug.group_id;

/* Статусы сценариев */
SELECT scenario.object_name Scenario
     , start_y.object_name Start_Year
     , end_y.object_name End_Year
     , start_p.object_name Start_Period
     , end_p.object_name End_Period
FROM HSP_SCENARIO s
   , hsp_object scenario
   , hsp_object start_y
   , hsp_object end_y
   , hsp_object start_p
   , hsp_object end_p
WHERE 1=1
AND s.scenario_id = scenario.object_id
AND s.start_yr_id = start_y.object_id
AND s.end_yr_id = end_y.object_id
AND s.start_tp_id = start_p.object_id
AND s.end_tp_id = end_p.object_id;

/* Настройка безопасности */
SELECT user_name, o_name memeber,
case when ACCESS_MODE=-1 then 'None'
when ACCESS_MODE=3 then 'Write'
when ACCESS_MODE=1 then 'Read'
else 'UnKnown'
end access_type,
case when FLAGS=0 Then 'MEMBER'
when FLAGS=9 Then '@IDESCENDANTS'
when FLAGS=8 Then '@DESCENDANTS'
when FLAGS=6 Then '@ICHILDREN'
when FLAGS=5 Then '@CHILDREN'
else 'UnKnown'
end member_type
FROM HSP_ACCESS_CONTROL
inner join (SELECT object_name as user_name, object_id as u_id 
            FROM hsp_object) u 
      on hsp_access_control.user_id=u_id
inner join (SELECT object_name as o_name, object_id as o_id 
            FROM hsp_object WHERE hsp_object.object_type !=7 ) o 
      on OBJECT_ID=o_id;

/* Пример построение parent-child запроса */
SELECT object_name
FROM hsp_object
WHERE 1=1
--and has_children = 0 -- только уровень 0
START WITH UPPER(object_name) = UPPER('Account') -- все потомки Account
CONNECT BY PRIOR object_id = parent_id;

/* Пример запроса для выгрузки настроек измерения Account */
SELECT o2.object_name PARENT ,
    o.object_name CHILD ,
    o.generation ,
    o.position ,
    DECODE(m.data_storage, 2, 'O', 5, 'X', 'N') data_storage, -- N Never, O - Label, X - Dynamic ,
    DECODE(m.twopass_calc, 1, 'T', '') twopass_calc ,
    m.data_type ,
    DECODE(m.consol_op1, 6, '^', 5, '~', '+') consol_op ,
    DECODE(a.time_balance, 2, 'L', '') time_balance ,
    a.account_type ,
    DECODE(a.variance_rep, 1, 'E', '') variance_rep ,
    path
  FROM hsp_member m ,
    (SELECT parent_ID,
      OBJECT_ID,
      object_name,
      generation,
      position,
      sys_connect_by_path( acc.object_name, '/') path
    FROM hsp_object acc
    WHERE 1 =1
      START WITH acc.object_name     = 'Account'
      CONNECT BY PRIOR acc.object_id = acc.parent_id
    ) o ,
    HSP_OBJECT o2 ,
    hsp_account a
  WHERE 1         =1
  AND O.OBJECT_ID = m.member_id
  AND O.parent_ID = O2.OBJECT_ID
  AND m.member_id = a.account_id
  AND a.used_in   = '1' -- For 1-st plan;

/* Список измененных объектов в Planning, которые должны обновиться в Essabse */ 
 SELECT   'PL' AS application,
          ot.type_name object_type,
          t.object_id,
          t.plan_type,
          t.xact_type,
          t.object_name,
          t.old_name,
          t.xact_date,
          t.src_mbr,
          o.modified_by
   FROM   hp_PL.hsp_pending_xacts t,
          hp_PL.hsp_object o,
          hp_PL.hsp_object_type ot
  WHERE   t.object_id = o.object_id(+)
          AND o.object_type = ot.object_type(+) 

Ссылки по настройке производительности

http://download.oracle.com/docs/cd/E17236_01/epm.1112/epm_install_start_here/ch03s01.html - Official Sizing Info

www.innowavetech.com/downloads/090623_odtug_s629.pdf - Windows + Unix tuning

http://ilearning.oracle.com/ilearn/en/learner/jsp/rco_details_find.jsp?srchfor=null&rcoid=873918036  - EPM Performance Tuning Webcast (только для партнеров)

www.norcaloaug.com/seminar_archive/2008_training_day_pres/6_16_helmer.pdf  - System 9 Overview + Sizing

http://dlc.sun.com/pdf/817-0404/817-0404.pdf  - Sun Solaris Tuning

http://www.scribd.com/doc/18384637/Essbase-Optimization  - Essbase Optimization

ODTUG Hyperion Tech Content - много всего :)

http://essbase.ru/archives/663 - оптимизация Essbase

http://blogs.oracle.com/pa/ - оптимизация EPM

11 сент. 2010 г.

Выгрузка/загрузка в многопользовательской среде (shell)

С какими проблемами можно столкнуться при запуске Essbase calc-скриптов при большом количестве пользователей:
  • невозможно использовать переменные подстановки (Substitution varaibles) т.к. изменение переменной одним пользователем, может отразиться в расчете другого пользователя
  • необходимо дополнительно создавать имена файлов выгрузок с уникальными именами

Предлагаю вам вариант выгрузки данных из одного куба в другой без использования переменных постановки.

Для это нам надо создать шаблон MaxL скрипта, который будет выполнять выгрузку/загрузку и shell-скрипт, который будет создавать копию MaxL c уникальным именем, выставлять необходимые переменные и запускать его.

Шаблон MaxL-скрипта Export.mxl
login user identified by 'password' on localhost;

/* Export data from cube1 */
execute calculation '
FIX (
     "VR_Work",
     "ACT",
     @RELATIVE("&vEntity",0)
    )
    DATAEXPORT "File" " " "./export_data_&file_id.txt" "#MI";  
ENDFIX' on Test.Cube1;

/* Clear data to Cube2 */
execute calculation '
FIX (
    "ACT",
     @RELATIVE("&vEntity",0)
    )
    CLEARDATA "VR_Work";
ENDFIX' on TEST.Cube2;

/* Import data to Cube2 */
import database TEST.Cube2 data
from  data_file   "./export_data_&file_id.txt"
/*using rules_file  "some_rule_if_necessary"*/
on error write to "./export_data_&file_id.err";

exit;

Shell-скрипт Export.sh
#!/bin/bash

#Создаем переменные
R=$RANDOM
#уникальный идентификатор файлов (можно в конец добавить $R)
file_id=`date '+%Y%m%d_%H%M%S'`

#создаем Maxl-скрипт из шаблона и проставляем переменые
sed -e 's/&file_id/'${file_id}'/' ./export.mxl | sed -e 's/&vEntity/'$1'/'  > ./export_${file_id}.mxl

#запускаем MaxL
./startMax.sh ./export_${file_id}.mxl

Запускаем скрипт c параметром филиал:
./Export.sh EN_RUSSIA

У нас появятся файлы
  • Export_20110909_180650.mxl (MaxL, все переменные уже проставлены)
  • Export_20110909_180650.log
  • Export_data_20110909_180650.txt - файл с данными
Все подстановки помогает выполнить команда sed. Делает она следующее
  • открывает ./export.mxl
  • заменяет &file_id на ${file_id} (в нашем случае 20110909_180650)
  • заменяет &vEntity на $1 (в нашем случае EN_RUSSIA)
  • записывает изменения в ./export_${file_id}.mxl 

Листинг Export_20110909_180650.mxl
login user identified by 'password' on localhost;

/* Export data from cube1 */
execute calculation '
FIX (
     "VR_Work",
     "ACT",
     @RELATIVE("EN_RUSSIA",0)
    )
    DATAEXPORT "File" " " "./export_data_20110909_180650.txt" "#MI";  
ENDFIX' on Test.Cube1;

/* Clear data to Cube2 */
execute calculation '
FIX (
    "ACT",
     @RELATIVE("EN_RUSSIA",0)
    )
    CLEARDATA "VR_Work";
ENDFIX' on TEST.Cube2;

/* Import data to Cube2 */
import database TEST.Cube2 data
from  data_file   "./export_data_20110909_180650.txt"
/*using rules_file  "some_rule_if_necessary"*/
on error write to "./export_data_20110909_180650.err";

exit;

P.S. Как запустить shell-скрипт из бизнес-правила читай CDF

    30 авг. 2010 г.

    Настройка HSP_PM_STATES

    В Planning есть возможность изменить название статусов процесса согласования бюджетных блоков и их цветовое представление.


    Пример:

    UPDATE "HSP_PM_STATES" SET NAME = 'Не начато' WHERE STATE_ID = 0;
    UPDATE "HSP_PM_STATES" SET NAME = 'Подписано', COLOR = 'ORANGE' WHERE STATE_ID = 4;
    UPDATE "HSP_PM_STATES" SET NAME = 'Начато' WHERE STATE_ID = 1;
    UPDATE "HSP_PM_STATES" SET NAME = 'Отклонено', COLOR = 'RED' WHERE STATE_ID = 5;
    UPDATE "HSP_PM_STATES" SET NAME = 'На рассмотрении', COLOR = 'BLUE' WHERE STATE_ID = 2;
    UPDATE "HSP_PM_STATES" SET NAME = 'Утверждено', COLOR = 'GREEN' WHERE STATE_ID = 3;
    

    Выглядит этот светофор так:


    P.S. дополнительная информация http://www.orahyplabs.com/

    19 авг. 2010 г.

    Essbase Custom-Defined Macros

    Задача:
    Существует куб со следующими измерениями:
    Account
       Acc1
       Acc2
       Acc3
    Period
       YearTotal
         Q1
           Jan
           Feb
           ...
    Year
       FY09 
       FY10
       FY11

    Необходимо создать функцию XXPRIOR которая умеет "перескакивать" через год т.е.

    XXPRIOR(Jan->FY10) = Dec->FY09

    Решение:
    Создаем макрос в MaxL:
    create or replace macro '@XXPRIOR' 
    (SINGLE) as 
    '( 
      (@ISMBR(Jan) * @@1->Dec->@CURRMBRRANGE("Years", LEV, 0, -1,-1))  
        + (@ISMBR(Feb:Dec) * @PRIOR (@@1)) 
    )'
    

    Перестартовываем приложение в Essbase.

    Используем макрос в calc-сриптах:
    FIX(FY10, Jan:May)
     
        Acc2 = @XXPRIOR(Acc1); /* Macro */
        Acc3 = @PRIOR(Acc1);   /* Standart Function */
    
    ENDFIX
    

    Этот пример показывает результат работы скрипта:
    Dec     Jan     Feb     Mar    Apr    May
                    FY09    FY10    FY10    FY10   FY10   FY10
                    ===     ===     ===     ===    ===    ===                       
    Acc1            1100    1200    1000    1300   1300   1400
    Acc2            #MI     1100    1200    1000   1300   1300
    Acc3            #MI     #MI     1200    1000   1300   1300
    

    Для детального изучения смотрите Technical Reference: Custom-Defined Macros

    19 июл. 2010 г.

    Оптимизация скриптов Essbase

    Алгоритм оптимизации прост:
    • Запускаем расчет
    • Анализируем лог
    • Находим узкое место
    • Оптимизируем :)

    1. Запускаем расчет.

    Самый удобный лог для анализа - это лог esscmd. С его помощью и будем запускать скрипты. Не забудьте в скипте установить параметр "SET MSG SUMMARY" т.к. без него ничего интересного в логе вы не найдете.

    Создаем calc-скрипт PL_Calc.csc, который необходимо анализировать:
    SET MSG SUMMARY;
    ...
    A = A + B;
    ...

    Создаем esscmd-скрипт PL_Calc.scr:
    output 1 "PL_Calc.log";
    login "ess_server" "admin" "password";
    
    updatevariable "vEntity" "ess_server" "PL" "" "EN_Russia";
    updatevariable "vYear" "ess_server" "PL" "" "FY10";
    
    select "PL" "PL";
    
    runcalc 2 "PL_Calc";
    
    OUTPUT 3;
    exit;

    Запускаем esscmd-скрипт и получаем PL_Calc.log:
    esscmd PL_Calc.scr

    2. Анализируем лог.

    Для анализа мне понравился RightLog. Качаем и запускаем вот с такими параметрами:
    RightLog.exe -i PL_Calc.log -s ; -t -d EUR -f "1012668|1012555|1012553|1012579|1003052" > PL_Calc.csv
    Получили PL_Calc.csv

    3. Находим узкое место.

    Открываем PL_Calc.csv в Excel делаем расчетную колонку "Время исполнения" - вот и весь поиск.

    4. Типовые проблемы производительности и возможные варианты решения.
    Долго работает XREF - меняйте на партиции.
    Долго считается формула на sparse элементе - используйте FRMLBOTTOMUP ON;
    Долго работает агрегация - необходимо настраивать порядок измерений, кэши, использовать параллельные вычисления.

    По настройке оптимизации предлагаю почитать "Optimizing Calc Scripts" by Edward Roske

    P.S. Если необходимо просматривать информацию о кол-ве обработаных блоков
    RightLog.exe -i PL_Calc.log -s ; -t -d EUR -f "1012668|1012555|1012553|1012579|1003052|Calculations:|Block Created|1012574|1017018" > PL_Calc.csv
    

    18 июл. 2010 г.

    PREVSIBLING vs CURRMBRRANGE

    Хочу поделиться наблюдением.

    Передо мной стояла задача создать динамическую статью Acc01_PrevYear, которая равняется статье Acc01 за прошлый год.

    Вот такая формула работает 1 сек:
    Acc01_PrevYear = Acc01->@PREVSIBLING(@CURRMBR("Years"))

    Вот такая формула работает 0.01 сек:
    Acc01_PrevYear = Acc01->@CURRMBRRANGE("Years", Lev, 0, -1, -1)

    4 июл. 2010 г.

    Essbase Integration Services VS Studio

    В версии 11.1.1.0 появился новый продукт Essbase Studio, который пришел на замену Essbase Integration Services (EIS)

    Чего пока что не может Studio 11.1.1.3:
    - нельзя добавить колонку в таблицу источник, если эта таблица уже добавлена в Studio
    - проблемы с загрузкой данных, если измерение создано вручную
    - проблемы с cозданием drill-through отчетов для ненулевого уровня

    Что понравилось:
    + удобный интерфейс
    + удобное управление подключениями
    + добавлены новые источники данных (EPM, Oracle BI)

    В версии Studio 11.1.2 кое-что поправили, но с drill-through сложность так и осталась.

    Выводы: до промышленной экплуатации Studio еще далеко, но знакомится с продуктом надо обязательно т.к. возможно скоро Studio заменит и EAS Console

    P.S. Вот неплохой tutorial по Studio

    28 июн. 2010 г.

    Использование CDF (часть II)

    Как передать в CDF значение переменной бизнес-правила?

    К сожелению Java-класс, описаный в первой части, имеет ряд ограничений:
    • Невозможно передать значение переменной бизнес-правила
    • Нельзя использовать внутри FIX, получать код возврата

    Что нужно сделать, чтобы CDF работала:
    • Настроить Essbase (см. часть I)
    • Создать и скомпилировать Java-класс
    • Настроить безопасность
    • Зарегистрировать Java-функцию в Essbase

    1. Настраиваем Essbase.

    см. часть I

    2. Создаем и компилируем Java-класс.

    2.1. Создаем файл ARBORPATH/java/udf/RunCmd.java
    import java.util.*;
    import java.io.*;
    
    public class EssbaseRuRunTime {
    public static void main(com.hyperion.essbase.calculator.Context ctx, String[] args)
    {
    int i,  n = args.length;
    String Str = args[0];
    
    for (i=1; i
    Str = Str + " " + args[i];
    }
    
    try {Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(Str);
    int exitVal = proc.waitFor();
    System.out.println(args[0]+" ExitValue: " + exitVal);
    }
    catch(Exception e)
    {
    System.out.println(e.getMessage());
    System.out.println(args[0]);
    }
    
    }
    }
    
    2.2 Компилируем класс из каталога, где он расположен
    javac RunCmd.java
    jar cf RunCmd.jar RunCmd.class
    
    Примечание: компилировать версией Java, которая инсталирована с Essbase

    3. Настраиваем безопасность

    3.1. В файл ARBORPATH/java/udf.policy добавляем следующие строки:
    grant codeBase "file:${java.home}/udf/RunCmd.jar" {
            permission java.security.AllPermission;
    };
    

    4. Регистрируем Java-функцию в Essbase

    4.1. Выполняем слудующий MaxL скрипт
    create function '@jRunCmd'
    as 'RunCmd.jRun'
    spec '@jRunCmd(arg1, arg2); @jRunCmd(arg1, @List(arg2, arg3,...));'
    comment 'Execute shell command';
    

    4.2. Перегружаем Essbase

    Пример запуска CDF из бизнес-правила
    Текст правила
    VAR vA;
    FIX(Act, BegBalance…..)
    "FY10"
              (
               vA = @jRunCmd(
                              "../java/udf/scripts/alter_sub_var.sh"
                            , @LIST ("Cons_Scenario", @Name({vScenario}))
                            );      
               );
    ENDFIX
    
    Текст ALTER_SUB_VAR.SH:
    ./startMaxl.sh ../java/udf/scripts/alter_sub_var.mxl $1 $2
    
    Текст ALTER_SUB_VAR.MXL:
    login LOGINNAME identified by PASSWORD on SERVER;
    
    alter system set variable $1 $2;
    
    exit;
    


    Полезные ресурсы
    Документация Developing defined calculation functions
    Блог hack4essbase.wordpress.com
    Блог essbaselabs.blogspot.com

    13 июн. 2010 г.

    Использование CDF (часть I)

    Что такое CDF?

    CDF (custom defined functions) - это java-программы, которые можно использовать в скриптах расчетов (calc script) Essbase и бизнес-правилах Planning.

    Что действительно необходимо на каждом проекте, так это запускать MaxL-скрипты или пакетные файлы (bat, cmd, sh) из бизнес-правил. Например запустить обновление replicated partition, загрузить данные и т.д.

    Что нужно сделать, чтобы CDF работала:
    1. Настроить Essbase
    2. Создать и скомпилировать Java-класс
    3. Настроить безопасность

    Настраиваем Essbase.

    1.1. Создаем папку ARBORPATH/java/udf
    1.2. Изменяем настройку безопастности Java CDF
    Необходимо в файле ARBORPATH/java/udf.policy снять комментарий с последней строки:
    // **************************************************** 
    
    // Permissions for all other classes.
    // By default UDF sandbox is almost the same as applet environment, 
    // with some additional restrictions.
    grant {
                ……..
     permission java.util.PropertyPermission "java.vm.version", "read";
     permission java.util.PropertyPermission "java.vm.vendor", "read";
     permission java.util.PropertyPermission "java.vm.name", "read";
    
     // Uncomment the following line if you want to remove all restrictions
     permission java.security.AllPermission;
    };


    Создаем и компилируем Java-класс.

    2.1. Создаем файл ARBORPATH/java/udf/EssbaseRuRunTime.java
    import java.util.*;
    import java.io.*;
    
    public class EssbaseRuRunTime {
    public static void main(com.hyperion.essbase.calculator.Context ctx, String[] args)
    {
    int i,  n = args.length;
    String Str = args[0];
    
    for (i=1; i
    Str = Str + " " + args[i];
    }
    
    try {Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(Str);
    int exitVal = proc.waitFor();
    System.out.println(args[0]+" ExitValue: " + exitVal);
    }
    catch(Exception e)
    {
    System.out.println(e.getMessage());
    System.out.println(args[0]);
    }
    
    }
    }
    
    2.2 Компилируем класс из каталога, где он расположен
    javac –classpath ../essbase.jar EssbaseRuRunTime.java
    jar cf EssbaseRuRunTime.jar EssbaseRuRunTime.class
    
    Примечание: компилировать версией Java, которая инсталирована с Essbase

    Настраиваем безопасность

    3.1. В файл ARBORPATH/java/udf.policy добавляем следующие строки:
    grant codeBase "file:${java.home}/udf/EssbaseRuRunTime.jar" {
            permission java.security.AllPermission;
    };
    
    3.2. Перегружаем Essbase

    Пример запуска CDF из calc-script
    FIX
       ... что-то считаем
    ENDFIX
    
    RUNJAVA EssbaseRuRunTime "../java/udf/scripts/alter_sub_var.sh" "BudYear" &Act_Year;
    
    FIX
       ... что-то считаем
    ENDFIX
    
    Примечание: внутри FIX нельзя запускать EssbaseRuRunTime

    Полезные ресурсы
    Документация Developing defined calculation functions
    Блог hack4essbase.wordpress.com
    Блог essbaselabs.blogspot.com