Bài viết: Hàm người dùng và mảng

Liên hệ QC

TranThanhPhong

Ngày mai trời lại sáng!
Thành viên danh dự
Tham gia
16/3/07
Bài viết
2,104
Được thích
19,153
Giới tính
Nam
Tác giả: Lê Văn Duyệt

Chúng ta nói một ít về hàm người dùng vì phần này có liên quan đến vấn đề mảng chúng ta đang nói ở trên.

Hàm (function) có thể hiểu đơn giản như sau:

Hàm là một chương trình máy tính (Computer Program) để tính tóan và trả về giá trị cho (các) ô mà bạn nhập vào.


Array3.JPG


Khi viết một hàm người dùng chúng ta nên xác định kiểu biến truyền cho hàm.

Ví dụ:
Function MoIW(Formula As String, Decimals As Integer)

Nếu tham số truyền không đúng kiểu, một thông báo lỗi #Value! sẽ được trả về.

Tương tự ở trên chúng ta cũng nên xác định kiểu trả về của hàm người dùng.

Function MoIW(Formula As String, Decimals As Integer) As Double

Để trả về một giá trị lỗi từ một hàm thông thường chúng ta viết như sau:

If(TimThayLoi) Then TenHam=”Thong bao loi”: Exit Function

Nhưng đây không phải là cách tốt nhất để xử lý (handle) lỗi. Chúng ta dùng CVErr(Giá trị lỗi) để trả về giá trị lỗi mà Excel có thể xử lý.

If(TimThayLoi)Then TenHam=CVErr(xlErrNA): Exit Function

Đối với một số hàm, một số tham số không bắt buộc truyền vào cho hàm. Đối với trường hợp này chúng ta sẽ dùng từ khóa Optional để khai báo.

Function MoIW(Formula As String, Optional Decimals As Integer) As Double

Để kiểm tra người dùng có nhập vào biến này hay không chúng ta có thể dùng IsMissing để kiểm tra.

[GPECODE=vba]Function Test1(L1 As Long, L2 As Long, Optional P1 As Variant, Optional P2 As Variant) As String

Dim S As String

If IsMissing(P1) = True Then
S = "P1 Is Missing."
Else
S = "P1 Is Present (P1 = " & CStr(P1) & ")"
End If

If IsMissing(P2) = True Then
S = S & " " & "P2 Is Missing"
Else
S = S & " " & "P2 Is Present (P2 = " & CStr(P2) & ")"
End If

Test1 = S

End Function[/GPECODE]

Lưu ý:

  • Hàm IsMissing nhằm kiểm tra xem người dùng có nhập vào hay không. Nhưng hàm này chỉ áp dụng nếu bạn khai báo kiểu Variant. Trong trường hợp các kiểu dữ liệu khác hàm sẽ trả về False.
  • Khai báo Optional không được dùng cho User Defined Types (biến kiểu người dùng-UTDs).
  • Các khai báo Optional phải đặt cuối cùng. Ví dụ ta không thể đặt khai báo Optional như thế này:

Function CongTruNhanChia(Optional PhepToan As String="+", sng1 As Single, sng2 As Single) As Single
[h=1]MẢNG SỬ DỤNG TRONG HÀM[/h]
Bạn có thể tạo một hàm và dùng mảng như một đối số (Argument), hoặc trả về một mảng các kết quả.

Range được truyền cho hàm và có thể được sử dụng như một mảng.

Nếu một đối số Range được truyền cho một hàm, thì Range có thể được xử lý như một mảng trong VBA. Không cần thiết phải khai báo Dim.

Ví dụ: Function MyLinest(known_x, known_y)

Truyền số lượng không xác định các đối số cho hàm.

Các bạn để ý, khi chúng ta sử dụng hàm SUM chúng ta có thể truyền vào nhiều đối số.

Ví dụ: =SUM("A1:A10”, "B3:C5”)

Đây chính là trường hợp chúng ta muốn đề cập đến.

Gặp trường hợp này chúng ta sẽ dùng từ khóa ParamArray.

ParamArray cho phép bất kỳ số lượng tham số truyền cho một Procedure.
Chỉ có phần tử ParamArray là có thể có hoặc không (option). Các tham số trước ParamArray là bắt buộc.


  • Một số nguyên tắc khi sử dụng ParamArray:
  • Biến ParamArray phải là một mảng của các phần tử kiểu Variant.
  • Biến ParamArray phải là tham số cuối cùng trong danh sách tham số.
  • Không có tham số nào được khai báo với Optional trong danh sách. Đó là vì ta không thể dùng chung, tức là vừa có khai báo dùng Optional và vừa có khai báo dùng ParamArray. Bạn chỉ có thể dùng một trong chúng mà thôi.
  • Chỉ được sử dụng một ParamArray trong một Procedure mà thôi.
  • Do tham số ParamArray là một mảng, nên nó luôn được khai báo với ByRef.
  • Mảng ParamArray là mảng được bắt đầu bằng 0 bất chấp việc khai báo Option Base 1 của module. Nếu không có biến nào được truyền thì LBound bằng 0 và UBound là -1.
  • Biến kiểu người dùng (UDT) không thể là một phần tử của ParamArray.

[GPECODE=vba]
Function SumUp(Rng As Range, ParamArray Args() As Variant) As Double
Dim Sum As Double
Dim Ndx As Long
Sum = WorksheetFunction.Sum(Rng)
For Ndx = LBound(Args) To UBound(Args)
If IsNull(Args(Ndx)) = False Then
If IsArray(Args(Ndx)) = False Then
If IsObject(Ndx) = False Then
If IsError(Ndx) = False Then
Sum = Sum + Args(Ndx)
End If
End If
Else
Sum = Sum + WorksheetFunction.Sum(Args(Ndx))
End If
End If
Next Ndx
SumUp = Sum
End Function
[/GPECODE]


Trả về một mảng các giá trị

Ví dụ: Hàm trả về mảng dòng 3 phần tử

[GPECODE=vba]Function MyLINEST(known_ys, known_xs)

Dim Results(3)
Results(1) = 1
Results(2) = 2
Results(3) = 3
MyLlNEST = Results

End Function[/GPECODE]

Ví dụ: Hàm trả về mảng dòng 3 phần tử (dùng từ khóa Array)

[GPECODE=vba]Function MyLINEST(known_ys, known_xs)

MyLINEST = Array(1, 2, 3)

End Function[/GPECODE]


Ví dụ: Hàm trả về mảng 3 dòng và 4 cột

[GPECODE=vba]Function Test() As Variant
Dim V() As Variant
Dim N As Long
Dim R As Long
Dim C As Long
ReDim V(1 To 3, 1 To 4)
For R = 1 To 3
For C = 1 To 4
N = N + 1
V(R, C) = N
Next C
Next R
Test = V
End Function[/GPECODE]

Nếu dùng từ khóa Array, chỉ trả về mảng chỉ có một chiều nếu muốn trả về một mảng hai chiều chúng ta phải dùng Array(Array(…))



http://www.giaiphapexcel.com/vbb/content.php?205
 
Upvote 0
Web KT
Back
Top Bottom