58 Public Static Sub StPro() Dim a As Long Dim b As Long a = a + 1 b = b + 1 a = a + b Debug.Print "Lan chay " & Str(b) Debug.Print " ", "a=" & Str(a), "b=" & Str(b) End Sub Kết quả sau 2 lần chạy chương trình con như sau: CHÚ Ý Các biến tĩnh thường được sử dụng khi muốn lưu trữ kết quả những lần chạy của chương trình con. Chú ý rằng dù biến trong chương trình con là biến thông thường hay biến tĩnh thì vẫn luôn mang tính chất cục bộ. 9.5. Cách thức gọi chương trình con. Với trường hợp dự án (Project) gồm nhiều thành phần (các mô-đun chuẩn, các UserForm,…) có chứa mã lệnh, nghĩa là ở đó có thể xây dựng hoặc có nhu cầu sử dụng chương trình con, thì trong cùng một mô-đun, không được phép xây dựng hai chương trình con trùng tên nhau, nhưng quy định này không áp dụng cho các mô-đun khác nhau, nghĩa là có thể tồn tại hai chương trình con có tên giống hệt nhau ở hai mô-đun khác nhau. Trong trường hợp trùng tên này, khi muốn sử dụng chương trình con nào thì phải chỉ rõ nơ i chứa nó, và tốt nhất, khi sử dụng bất cứ chương trình con nào của mô-đun khác thì nên chỉ rõ cả tên mô-đun đó. Gọichươngtrìnhcondạnghàm(Function) Khi gọi chương trình con dạng hàm ( Function), danh sách tham số phải được đặt trong cặp kí tự “( )” sau tên chương trình con. <Tên_mô-đun>.<Tên_hàm>(<danh_sách_tham_số>) CHÚ Ý Mô-đun ở đây có thể là một mô-đun chuẩn (Module), UserForm hoặc một đối tượng mà người dùng đang xét. Danh sách tham số phải được truyền theo đúng thứ tự như ở phần khai báo chương trình con. Ví dụ: mô-đun chuẩn mdlMatcat chứa hàm TinhDTHH(h,b) thì cú pháp gọi hàm đó là: mdlMatcat.TinhDTHH(ph,pb) với ph, pb là những biến được truyền vào trong hàm. Gọichươngtrìnhcondạngthủtục(Sub) Khi gọi chương trình con dạng thủ tục ( Sub), danh sách tham số đặt tiếp sau tên thủ tục và kí tự trống, các tham số không cần đặt trong cặp kí tự “( )”. C C H H Ư Ư Ơ Ơ N N G G I I I I I I : : C C Ơ Ơ B B Ả Ả N N V V Ề Ề N N G G Ô Ô N N N N G G Ữ Ữ L L Ậ Ậ P P T T R R Ì Ì N N H H V V I I S S U U A A L L B B A A S S I I C C 59 <Tên_mô-đun>.<Tên_thủ tục> <danh_sách_tham_số> Ví dụ: trong mô-đun chuẩn mdlDAH chứa thủ tục TinhDTDAH(S) thì cú pháp gọi thủ tục đó là: mdlDAH.TinhDTDAH pS với pS là những biến được truyền vào trong thủ tục. Gọichươngtrìnhconvớicácthamsốgántheotên Trong cách gọi chương trình con theo kiểu thông thường như trên, danh sách tham số truyền vào phải đúng thứ tự như trong phần khai báo của chương trình con đó. Ngoài ra, VB còn cho phép gọi chương trình con với trật tự tham số tuỳ ý mà vẫn đảm bảo sự truyền tham số chính xác thông qua tên của tham số. Ví dụ, với hàm DT(w,h,r) ở phần trên thì hai cách gọi sau là tương đương: DT (100,200,30) DT (r:=30, w:=100, h:=200) Trong dòng thứ nhất, luôn có sự ngầm hiểu trình tự các tham số là: w,h,r, đây chính là trình tự khi định nghĩa hàm DT. Còn ở dòng thứ 2, trình tự theo định nghĩa của hàm DT không có ý nghĩa nữa bởi đã có sự chỉ rõ: Tên biến := Giá trị cần gán. Chú ý đến ký hiệu ( := ) và trình tự bất kỳ của các tham số. Việc sử dụng tham số gán theo tên khi gọi chương trình con đặc biệt tiện lợi khi chương trình con có nhiều tham số tuỳ chọn và người dùng không có ý định sử dụng hết các tham số đó. 9.6. Thoát khỏi chương trình con. Để thoát khỏi hàm sử dụng lệnh Exit Function Để thoát khỏi thủ tục sử dụng lệnh Exit Sub Ngay khi gặp hai hàm này trong thân của chương trình con, toàn bộ các dòng lệnh phía sau nó sẽ bị bỏ qua và chương trình sẽ thoát ngay khỏi chương trình con đó. 10. Tổ chức các chương trình con theo hệ thống các mô-đun chuẩn Với việc thiết kế hệ thống theo phương pháp cấu trúc hóa, toàn bộ chương trình thường được chia thành các khối chương trình nhỏ hơn, mỗi khối chương trình đảm nhận một chức năng chung nào đó. Tiếp theo, để dễ dàng cho việc xây dựng chương trình, các chức năng chung lại được chia thành các phần nhỏ hơn nữa, và lặp lại cho đến khi nào mỗi phần này có thể minh họa bằng một chươ ng trình con. Trong lập trình VBA, các khối chức năng thường được tổ chức thành các mô-đun chuẩn ( Module). Trong mô-đun chuẩn sẽ bao gồm các chương trình con (hàm và thủ tục) phản ánh sự chi tiết hoá cho các khối chức năng này. Ngoài ra, trong mô-đun chuẩn người dùng có thể khai báo các kiểu dữ liệu tự định nghĩa, các biến dùng chung, các hằng số, … Ví dụ: để xây dựng một chương trình kiểm toán mặt cắt cột BTCT, có thể xây dựng các mô- đun và các chương trình con theo hình vẽ dưới đây dưới đây 60 Hinh_Hoc (Module) TinhDTHH_MCatBT TinhDTHH_MCatCT TinhDTHH_TinhDoi Tinh_Duyet (Module) LapTH_TaiTrong TTGH_CuongDo TTGH_SuDung C C H H Ư Ư Ơ Ơ N N G G I I I I I I : : C C Ơ Ơ B B Ả Ả N N V V Ề Ề N N G G Ô Ô N N N N G G Ữ Ữ L L Ậ Ậ P P T T R R Ì Ì N N H H V V I I S S U U A A L L B B A A S S I I C C 61 Hình III-16: Tổ chức dự án theo cấu trúc chức năng 11. Làm việc với UserForm và các thành phần điều khiển 11.1. Các vấn đề chung Trong một dự án VBA, các mô-đun chuẩn cho phép xây dựng các khối chương trình xử lý dữ liệu hoặc các khai báo về dữ liệu. Sự giao tiếp nhập-xuất dữ liệu giữa người dùng và chương trình có thể được thực hiện thông qua giao diện của ứng dụng nền. Tuy nhiên, trong nhiều trường hợp giao diện nhập-xuất dữ liệu của ứng dụng nền chưa thể đáp ứng đượ c nhu cầu tương tác dữ liệu một cách chi tiết cũng như tiện lợi cho người sử dụng, và khi đó, cần tạo ra các giao diện nhập-xuất riêng thông qua việc sử dụng các UserForm trong dự án VBA. Nói cách khác, giao tiếp giữa người sử dụng chương trình với chương trình viết bằng VBA được gọi là giao diện của chương trình và cách xây dựng giao diện như sau: Ø Ø Sử dụng ngay ứng dụng nề n để làm giao diện, cách này sẽ trình bày cụ thể trong các chương sau. Ø Ø Sử dụng UserForm. Ø Ø Kết hợp cả hai phương án trên. Các UserForm thực chất là mẫu các hộp thoại (cửa sổ) được tạo ra theo yêu cầu của người dùng. Trên một UserForm luôn chứa những thành phần phục vụ cho nhu cầu tương tác giữa người dùng và chương trình: nhập các dữ liệu cần thiết, ra lệnh xử lý, lựa ch ọn dữ liệu theo tình huống, hiển thị kết quả xử lý một cách trực quan,… Những thành phần đó được gọi là các điều khiển (Control). ĐểtạoraUserForm,làmtheotrìnhtựsau: 1. Xác định sự cần thiết phải tạo giao diện nhập-xuất dữ liệu riêng: Giao diện do ứng dụng nền cung cấp không đủ hoặc không thích hợ p cho việc nhập dữ liệu hoặc xuất kết quả của chương trình. Đ iều khiển cho phép nhập dữ liệu dạng văn bản Đ iều khiển cho phép người dùng ra lệnh thông qua việc kích chuột. Đ iều khiển cho phép chèn hình ảnh minh hoạ. Điều khiển lựa chọn dữ liệu 62 2. Xác định cách thức và trình tự tương tác của người sử dụng trên giao diện: để có thể bố trí các điều khiển sao cho thuận tiện đối với người dùng, ví dụ như theo thói quen điều khiển của đa số người sử dụng là từ trái sang phải, từ trên xuống dưới. 3. Xác định số lượng UserForm cần phải tạo cho quá trình nhập dữ liệu cũ ng như việc hiển thị kết quả: chỉ nên sử dụng vừa đủ và phân theo chủ đề của công việc, ví dụ nên phân tách giao diện nhập dữ liệu với giao diện trình bày kết quả và các điều khiển (nút bấm) khác. 4. Xác định các loại dữ liệu cần nhập vào, các dữ liệu theo tình huống và các minh hoạ bằng hình ảnh kèm theo để giải thích rõ cho người sử dụng ý nghĩa của các thông s ố cần được nhập vào. Căn cứ vào các loại dữ liệu cần nhập trên để xác định các thành phần điều khiển phù hợp và đưa vào UserForm tương ứng. Cần chú ý rằng, các điều khiển, ngoài việc đáp ứng yêu cầu về mặt chức năng, chúng cũng cần được trình bày và giải thích một cách dễ hiểu và có tính thẩm mỹ. Hình III-17: Ý nghĩa các loại dữ liệu cần nhập vào được minh họa bằng hình ảnh. 5. Lựa chọn các điều khiển phục vụ cho việc xác nhận dữ liệu sau khi nhập xong hoặc ra lệnh cho quá trình xử lý các dữ liệu này bắt đầu thực hiện. Thông thường các điều khiển này là hệ thống các nút bấm (Button) để xác nhận các dữ liệu đã nhập xong, yêu cầu bắt đầu xử lý hoặc hủy bỏ các dữ liệu đã nhập. . thân của chương trình con, toàn bộ các dòng lệnh phía sau nó sẽ bị bỏ qua và chương trình sẽ thoát ngay khỏi chương trình con đó. 10. Tổ chức các chương trình con theo hệ thống các mô-đun chuẩn. toàn bộ chương trình thường được chia thành các khối chương trình nhỏ hơn, mỗi khối chương trình đảm nhận một chức năng chung nào đó. Tiếp theo, để dễ dàng cho việc xây dựng chương trình, các. thì trong cùng một mô-đun, không được phép xây dựng hai chương trình con trùng tên nhau, nhưng quy định này không áp dụng cho các mô-đun khác nhau, nghĩa là có thể tồn tại hai chương trình con