數據庫計算
Essbase中單元格的數據可以是外部輸入或計算而得,單元格因而分為輸入單元格和計算單元格。計算單元格的計算方法可以通過大綱中維度成員的合並計算符和公式腳本定義,此稱為大綱計算定義。
例1:張大明家在上海市區和浦東各有一套房,1月5日時張大明收到市區房子的水費和電費賬單,然后繳付;張大明的妻子王翠花同時也收到並繳付了浦東房子的賬單。兩地的水電單價和用量均不一樣。
在HomeFinancial應用程序中,對應的單元格錄入數據如下表的數據。表中,灰底的單元格是輸入單元格,其中的數據是手工錄入;而公共事業費,作為父級成員應由其子代成員作合並計算,所以對應表中黑底的單元格就是計算單元格。

Essbase中子代成員合並到父級成員的計算可以通過合並計算符設置。在維庫編輯HomeFinancial應用程序。選中維度結構中任何非1代成員,都有一項【Consolidation】屬性,這就是合並計算符。雙擊此屬性進行編輯,如下圖,在下拉列表中有7種合並計算符供選擇,下表列出了這些計算符的含義。創建成員時,默認的合並計算符是加法“+”。


在例1中,公共事業費需要按如下公式進行合並:
公共事業費 = 電單價 × 電用量 + 水單價 × 水用量
那么是否將公共事業費子成員的合並計算符改成下圖設置就夠了呢?圖中成員名稱后是合並計算符。

此思路是對的,但做法在Essbase中行不通。原因是Essbase中同級成員並非按數學中先乘除后加減的順序計算,而是單純按照成員排序順序計算。如果按圖中那樣,公共事業費的計算就變成了:
公共事業費 = (電單價 × 電用量 + 水單價) × 水用量
要糾正這個錯誤有兩種方法。其一是在維度結構上做文章,按下圖重新設計維度結構,得到正確的計算順序如下:

第二種方法是使用成員公式。通過成員公式可以編寫腳本定義計算,成員公式會覆蓋子代成員的合並計算。而且Essbase提供了豐富的計算函數和完善的腳本語法,在成員公式中能實現各種復雜的計算。
在維度結構中選擇公共事業費成員,修改它的【Member Formula(BSO)】屬性,在公式編輯器中輸入腳本:
= "水單價" * "水用量" + "電單價" * "電用量";
如果要編寫復雜的腳本,推薦使用EAS Console。EAS Console中的公式編輯器更強大,可以提示計算函數和運算符,可以幫助驗證腳本語法。Essbase的計算函數和語法可參看官方手冊。

有了成員公式,子代成員的合並計算符就沒有意義了。出於嚴謹性考慮,可以將子代成員的合並計算符設為“~”,即子成員不參與合並計算。

回到例1最初的那個表格,橫軸和縱軸分別是兩個維度,仔細觀察表中的計算單元格,會發現存在兩個疑問。
第一個疑問,表中兩個維度,代表了兩種計算方向,這兩種方向的計算結果是不一致的。具體來說,最右下角的單元格,代表的是整個家庭公共事業費的合計。如按箭頭方向①,即沿Account維度計算,根據成員公式,結果是584.5;反之,按箭頭方向②,即沿Home維度計算,根據合並計算符,結果是300.5。

顯然第二種計算方向是正確的,那么如何讓Essbase按我們希望的方式計算呢?答案是控制Essbase的計算順序。就是要先計算Account維度,得到表中最下面一行單元格的數據,然后計算Home維度,得到表中最右邊一列單元格的數據。后計算的結果會覆蓋前面計算的結果,即是說會以300.5作為右下角單元格的最終計算結果。Essbase根據如下條件判斷維度間的計算順序。
- 如果大綱中同時包含Account和Time兩種類型的維度,且Account維中使用到成員公式,計算順序為:
-
- Account維度
- Time維度
- 密集維度,根據在大綱中排序計算
- 稀疏維度,根據在大綱中排序計算
- 其他情況下,計算順序為:
-
- 密集維度,根據在大綱中排序計算
- 稀疏維度,根據在大綱中排序計算
因此,維度的存儲類型和在大綱中的排序是控制計算順序的兩個重要手段。如HomeFinancial按照Account > Year > Home > Scenario的順序計算,這樣就能保證產生正確的計算結果。如果不清楚數據的計算順序,可以在執行計算命令后,從Essbase的日志文件中查看。
此外,若要改變維度中個別成員的計算順序。比如需要公共事業費在Home維度后計算,即需要表格右下角單元格的計算結果是584.5。那么可以啟用公共事業費的【Two Pass Calculation】屬性。此屬性表明成員需要二次計算,Essbase會在按正常順序計算一遍后,再用公共事業費的成員公式對相關單元格進行第二次計算。
第二個疑問,是電單價和水單價。按Home維度上的計算方法,使用加分“+”做合並計算,計算結果在父級成員上是無意義的。我們已經將電單價和水單價的合並計算符置為“~”,使之不在Account維度上進行合並計算,那么如何讓它們不在其他維度上進行合並呢?實際上,這里想要說明的是合並計算符“~”與“^”的區別,因為這兩個計算符常讓人困惑和混淆。這個例子中,要讓電單價和水單價在Home、Year、Scenario上都不執行合並計算,需要將合並計算符設成“^”,如下圖。

改成“^”后,電單價和水單價相關單元格在計算過程中不會產生任何合並計算值。只有使用公式腳本或輸入值才能向這些單元格寫入數據。

除了記錄日常收支流水外,我們還要為HomeFinancial加入計算現余額的功能。因此在Account維度的現金流層次下加入了4個成員。
- 期初現金:某一時期開始的現金量;
- 凈收入:總收入減總支出;
- 調整:當發現收支跟現金余額對不上時,用於調整;
- 期末現金:某一時期最后的現金量;
例2:下表記錄的是張大明在2013年Q1季度的現金流。

在1月1日時張大明有現金500000元,整個1月份他花了10000元,賺了30000元,則凈收入有20000元。1月31日結束時他應該有現金520000元,但由於漏記,或者銀行交易產生的手續費,張大明發現實際的金額是519980元,於是補錄了20元的調整項。所以有如下等式:
凈收入 = 收入 – 支出
期末現金 = 期初現金 + 凈收入 + 調整
要在Essbase中實現凈收入和期末現金的計算,可以使用成員公式。在維庫中編輯凈收入的成員公式屬性,輸入腳本:
= "收入" - "支出";
編輯期末現金的成員公式屬性,輸入腳本:
= "期初現金" + "凈收入" + "調整";
到1月結束時張大明所擁有的現金,同時也就是2月最初所擁有的現金。於是又有如下等式:
期初現金 = 上期的期末現金
將期初現金的成員公式修改為:
IF(NOT @ISMBR("1月1日"))
"期初現金"=@PRIOR("期末現金",1);
ENDIF;
此腳本要求我們在1月1日輸入期初現金,之后每一時期的期初現金都等於上一時期的期末現金。
定義了3個成員的公式后,接着要討論一下這3個成員的計算順序問題。前面我們使用例1來說明維度間的計算順序,即同一類型的維度,計算順序是由它們在大綱中的排序順序決定的。這一規則也同樣適用於同一維度中成員間的計算順序。在同一維度的成員間,Essbase按照由低級到高級,由前到后的順序計算。所以現金流這部分成員的計算順序如下圖。

下表用箭頭標示了單元格的計算路徑。

按照這樣的計算路徑,期初現金的成員公式會引用到晚於它計算的期末現金,從而產生錯誤的計算結果。例如當計算2月的期初現金時,1月的期末現金還未計算,結果得到空值。

將引用成員置於被引用成員之前,造成計算順序錯誤的現象稱為“前置引用”。要解決此問題,方法是讓期末現金和期初現金一起計算,修改期初現金的公式腳本為:
IF(NOT @ISMBR("1月1日"))
"期初現金"=@PRIOR("期末現金",1);
ENDIF;
"凈收入" = "收入" - "支出";
"期末現金" = "期初現金" + "凈收入" + "調整";
然后移除凈收入和期末現金的成員公式。依此計算公式,當1月期初現金計算時,1月的凈收入和期末現金同時被計算。那么在計算2月期初現金時,就可以得到正確的計算結果。
接着計算2月和3月的現金流。在Q1季度,期初現金應該是1月的期初現金,期末現金應該是3月份的期末現金,凈收入和調整是3個月的合計。同理,整個2013年,期初現金是Q1的期初現金,期末現金是Q4的期末現金,凈收入和調整是4個季度的合計。
可見,期初現金和期末現金在Year維度上采用了一種特殊的合並方式——分別取第一個子成員值和最后一個子成員值。在現實應用場景中,常常會碰到與時間相關的計算,如同比、環比、累計等。Essbase提供了大量有關Time類型維的計算函數和方法。本例中,除了使用成員公式,可以使用時間平衡(Time Balance)計算實現期初和期末計算。時間平衡計算要求數據庫中必須含有Time類型維度,且僅能用在Account類型維度上使用。時間平衡計算不會影響Time類型外其他維度的合並方式。時間平衡有3種計算,含義如下表。

在維庫中,將期初現金的【Time Balance】屬性設為First;將期末現金的【Time Balance】屬性設為Last。
時間平衡計算還有一個屬性【Skip Value】,此屬性控制是否要忽略空值Missing或零值。比如現金流是從2月開始,1月的期初現金是空值。如果期初現金的【Skip Value】屬性是None,不忽略空值和零值,則Q1的期初現金會是1月的空值;如果是Missing,則計算Q1的期初現金時會忽略1月的空值,取2月的值。

在有了大綱計算后,每次錄入和修改數據,Essbase是不會自動按合並計算符和成員公式進行計算的。必須執行計算命令,Essbase才會計算相關單元格。計算命令可寫在計算腳本中,計算腳本可精確控制計算范圍和順序,還可覆蓋大綱計算。可以為數據庫創建多個計算腳本,執行不同的計算腳本以實現不同的計算。每個數據庫都有一個默認計算腳本。
在EAS Console中,右擊HomeFinancial下的y2013數據庫,菜單中選擇【設置】>【默認計算】。可看到在默認計算腳本中,使用了CALC ALL語句計算整個數據庫,根據需要我們可以修改默認計算腳本。要創建新的計算腳本,在y2013數據庫的右鍵菜單中選【創建】>【計算腳本】。
執行計算腳本的途徑有多種,如通過MaxL Shell,Smart View,EAS Console等。要在EAS Console中執行計算腳本,通過右鍵菜單選【執行計算】,然后選需要執行的腳本。
