Excel VBA 基礎(05.2) - 用戶表單&異常處理
來自專欄 財務自動化利器-從VBA到d3js
上期的代碼已經包括在文件當中。如果就代碼本身有任何疑問,請在下方留言。
思路本身不難理解,主要是解決方案本身的創意。財務領域所遇到的日常數據處理問題為VBA工程提供了豐富的素材。編程與財務的結合猶如醇香的紅酒配上濃郁的乾酪,相得益彰,似乎天造地設為彼此而生。多練習,多思考,在實踐中打磨你的編程技巧,面對諸多日常問題,你終會找到專屬於你的最優的解決方案。
在上期 事件的基礎上我們來介紹,用戶表單的相關知識,並穿插介紹異常處理的內容。
用戶表單在網頁上的應用大家應該相當熟悉。作為接收用戶輸入的主要工具,文本框、密碼框以下拉列表等等用戶表單組件,在此不一一細表。
Excel為我們提供了兩種用戶表單模式,
一種是直接插入到工作表當中的表單
通過開發工具中的 插入 按鈕,選擇相應的表單控制項。
例如,當我在當前工作表中插入一個自定義按鈕時(表單控制項左上第一個),系統自動提示我 為按鈕控制項的 單擊 事件指定一個回調函數。還記得上期 事件與回調函數 的定義么?
通過這種模式可以將後台的代碼屏蔽起來,給普通用戶調用VBA中實現的自定義功能提供了便利。
此部分可以參考文檔
窗體、 窗體控制項和工作表上的 ActiveX 控制項概述這種方案相當便利,但是難以應對稍複雜的用戶需求。此時我們可以採用VBE工程當的用戶窗體模塊。
此時,可以通過滑鼠拖動 工具箱中的控制項 創建自己所需的用戶表單
上面的表單與本期案例相關。
各控制項屬性可以通過程序設置或者通過屬性瀏覽器進行相應調整
在右邊窗口選中相應控制項後,可以在左下的屬性瀏覽器中調整屬性, 其中包括字體 位置等屬性。
雙擊用戶表單時會自動跳轉到表單的工程代碼部分,如下圖所示。
說完整體概括之後,可以參考 官方的教程,非常基礎非常詳細
Chapter 20: Creating Advanced User Forms以及官方文檔
用戶窗體對象
本期示例 5.2.1 , 合併報表調整分錄
問題描述,集團合併報表當中由於各子公司位於不同國家,所採用的ERP系統也各不相同。前期數據處理完畢後需要進行報表合併。
Overview 工作表存放匯總信息。 列標G1-G9為子公司的匯總數據。 列標Col1-Col6當中,為合併抵銷分錄所在列。
合併過程中可能涉及到上千個不同的科目,為了便於管理合併抵銷分錄,我們需要將所錄入的分錄存儲在單獨工作表當中並且通過公式與匯總表關聯起來。
存放分錄的工作表名為 Bookings, 結構如下,其中第一列為分錄說明,第二列為對應列標
最終效果動態圖如下。
要求
- 雙擊某科目所指定列所對應的單元格觸發事件,顯示用戶表單。
- 用戶表單下拉列表數據依據工作表內容自動生成,並具有自動填充功能,如上圖輸入 Trail 自動篩選具有 Trail的科目
- 按鈕Equalizer的功能是使借貸平衡。
- 數字欄如果以 等號開頭時要求實現簡單的運算功能 如 =49+51 則得出100。
- 依據輸入數據,自動生成分錄,並通過公司與前表關聯。
此項目源於實踐中報表合併程序的一部分。本示例採用了早期的版本,無Option Explicit,請見諒。
之前一直有朋友跟我反映,項目代碼量大,難於消化。
這使我想起了去年備戰司法考試的看到的一個考生問題:八月份臨考前容易懈怠,怎麼才能熬下去? 回答:如果熬不下去,那麼明年再來吧。
學習的每個階段都會遇到瓶頸,絕大多數人都因畏難止步於某個階段,是否跨出這一大步,取決你自己。
各個項目都有其內在邏輯,在理解其實現原理之後務必抽出時間要自己動手敲一遍。真正編程的感覺遠遠不是看教程本身能夠體會到的。每一條語句都有它的道理,只有經歷過從大腦到屏幕的過程才代表真正掌握了程序設計的知識。
其次,現實中的項目本身的複雜程度,決定了我們代碼的規模。解決困難的問題,享受思考的樂趣也不正是我們學習VBA編程的初衷么?
本期代碼說完。分析業務邏輯,
雙擊顯示錶單,對應工作表事件 Worksheet_BeforeDoubleClick,通過此事件獲取觸發雙擊事件的單元格,由此獲取行列信息,即所對應科目代碼,以及合併列的名稱。
所用到各個組件的屬性與方法請自行查看文檔,由於用戶表單相對而言不常用,故只需會查閱文檔即可。用戶表單中的下拉列表從Overview工作表中讀取數據,並相應修改下拉列表的Items對象。自動填充功能對應 下拉列表 的 Change 事件,即 當用戶鍵入數據時自動更新下拉列表的Items對象。
輸入數值的文本欄,以等號開頭時進行計算。此功能在此詳細講解。
文本欄的結果以字元串形式傳遞,如果此時用戶輸入 abc 類似的非數字型字元在我們通過cdbl進行數值轉換時系統會 報錯。
如,在立即窗口中輸入並運行如下命令, 即可查看到 異常信息
? cdbl("12as")
由於異常的出現會阻斷程序的正常運行,我們有如下異常解決方式
在模塊/程序作用域指定
On Error Resume Next 忽略異常 繼續執行下一句
或是
On Error GoTo ... 遇到異常 轉跳到...
程序編寫調試的時候不推薦 加上On Error Resume Next,因為此時不再顯示異常提示,也無法針對性處理異常。此方法只適用於特定場景。
重點來看看 On Error GoTo
結合上述例子, 來分析程序運行
Private Function pareseValue(ByVal s As String) As Double On Error GoTo dblparesehdl s = Trim(s) If Left(s, 1) = "=" Then s = Right(s, Len(s) - 1) pareseValue = Application.Evaluate(Replace(Replace(s, " ", ""), ",", ".")) Else pareseValue = CDbl(Replace(Replace(s, " ", ""), ".", ",")) End If pareseValue = Round(pareseValue, 2) dblparesehdl: If Err.Number <> 0 Then pareseValue = 0 End IfEnd Function
當 用戶 輸入 "12as" 時,由於無前置 等號,進入第二選擇分支,此時cdbl因無法轉換報錯。
函數作用域當中,我們聲明 On Error GoTo dblparesehdl。發生錯誤時,自動轉到dblparesehdl 所標記的行, 【異常處理標記行的標記名稱通常採用 handler/handle/hdl】,並且執行該行及該行以下代碼。
Err.Number <> 0
如果錯誤代碼不等於0,則表示程序運行出現異常。此時我們將無意義的輸入指定為0。
我們在編寫程序的過程中也可以通過 Err.Raise 來拋出異常,或是 通過 Debug.Assert 判斷是否滿足指定條件,來中斷程序執行。兩種模式都在之前的文章中出現過。
示例文件後附。
http://qiou.eu/xl/Case_5.2.1.xlsm有任何問題請在下方留言。
本專欄所有文章著作權歸屬本人。未經本人書面許可,除知乎日報外,任何人不得轉載。
推薦閱讀:
※周大福財務分析(1)-業績分析
※Excel表格的美化
※藍色游標最近3年的業績含金量到底怎麼樣
※一文教你輕鬆讀懂上市公司的財務報表
※同業分析Excel2.0(真.可用版本)
TAG:VBA | MicrosoftExcel | 財務分析 |