Ví dụ:
=Count(A1) [với A1 là "a"] 'return 0
=Count(A1) [với A1 là 1] 'return 1
Dưới đây là cách hoạt động của nó được trình bày dưới dạng code:
Mã:
[COLOR=#008000]'tested data
' value result
'count(1) 1 1
'count("a") "a" 0
'count(1/0) #div/0! 0
'count(a1) 1 1
'count(a1) "a" 0
'count(a1) #div/0! 0
'count(a1:a5) {1,2,"a", false,#div/0!} 2
'*Note:
'Han che: Ham fCount hien tai chi co the nhan tham chieu la MOT doi so hoac range
'Algorithms:
'step 1: check input type and value...
'step 2: processing data...
[/COLOR]
Function fCount(ByVal value As Variant) As Long
Dim iTmp As Long
Dim wsf As WorksheetFunction
Set wsf = Application.WorksheetFunction
[COLOR=#008000] 'check input type & value...
[/COLOR] Select Case VarType(value)
Case 8204 [COLOR=#008000]'isrange[/COLOR]
For Each cll In value.Cells
If wsf.IsNumber(cll.value) Then: iTmp = iTmp + 1
Next cll
Case 8192 [COLOR=#008000]'isarray[/COLOR]
For i = 0 To UBound(value)
If wsf.IsNumber(value(i)) Then: iTmp = iTmp + 1
Next i
Case Else [COLOR=#008000]'isvariable...[/COLOR]
If wsf.IsNumber(value) Then: iTmp = iTmp + 1
End Select
fCount = iTmp
Set wsf = Nothing
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là số, giá trị nào không phải là số !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Trở lại lý thuyết toán học, ta có định nghĩa về số như sau:
Khi một giá trị có thể tính toán, thì đó là một [số]
Giờ, ta sẽ phát biểu lý thuyết toán học này dưới dạng code như sau:
Mã:
[COLOR=#008000]'tested data
' value result
'isnumber(1) 1 true
'isnumber("a") "a" false
'isnumber(1/0) #div/0! false
'isnumber(a1) 1 true
'isnumber(a1) "a" false
'isnumber(a1) #div/0! false
'isnumber(empty) empty cell false
'isnumber(true) true (logic) false
'isnumber(false) false (logic) false
'isnumber(a12:a13) {1,2} false
'Note:
'Han che: Hien tai fIsNumber chi nhan gia tri la doi so, hoac Cell.
'Algorithms
'test to get Err.Number
'...continue to examine the exceptions
[/COLOR]
Function fIsNumber(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
value = value * 1
iErrNum = Err.Number
On Error GoTo 0
If [COLOR=#0000ff]iErrNum[/COLOR] = 0 Then
If value <> Empty And value <> True And value <> False Then: fIsNumber = True [COLOR=#008000]'exceptions[/COLOR]
End If
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Trong code trên: Ta đã áp dụng lý thuyết toán học vào trong code, nhưng còn có một số vấn đề phát sinh:
+ Khi giá trị đưa vào là một ô rỗng (empty): excel nó sẽ hiểu là rỗng và tự gán giá trị 0
+ Khi giá trị đưa vào là một giá trị logic (TRUE/ FALSE): excel sẽ biến những giá trị này thành 1/0
--> Cho nên, để code hoạt động đúng như mong đợi, ta sẽ ta đã loại trường ra các trường hợp đặc biệt trên.
Mã:
If value <> Empty And value <> True And value <> False Then: fIsNumber = True [COLOR=#008000]'exceptions[/COLOR]
*MỘT VÀI CÁCH VIẾT CODE KHÁC
Ta có thể viết lại hàm IsNumber (excel) bằng các hàm sẵn có của vba như sau:
Mã:
Function hamIsNumber(ByVal vnt As Variant) As Boolean
If [COLOR=#0000ff]VarType[/COLOR](vnt) = 5 Then: hamIsNumber = True
End Function
Hàm VarType() này do anh sealand chỉ dẫn cho mình, xin cảm ơn !
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là text, giá trị nào không phải là text !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Nhưng cái text ta lấy ra được nó còn rất nhiều hỗn tạp, ví dụ:
+ Ô rỗng
+ Giá trị Logic (TRUE/FALSE)
+ Giá trị lỗi (#DIV/0!, #VALUE!...)
Những giá trị này đâu thể cho là text, cho nên khi đã loại trừ [số] ra rồi, ta loại trừ tiếp, những trường hợp ngoại lệ....
Từ đó, ta đã có thể xác định được giá trị đưa vào có phải là một text hay không !
Giờ ta sẽ trình bày phát biểu trên dưới dạng code như sau:
Mã:
[COLOR=#008000]'tested data
' value result
'istext(1) 1 false
'istext("a") "a" true
'istext(1/0) #div/0! false
'istext(a1) 1 false
'istext(a1) "a" true
'istext(a1) #div/0! false
'istext(empty) empty cell false
'istext(true) true (logic) false
'istext(false) false (logic) false
'istext(a12:a13) {a,b} false
'Note:
'Han che: Hien tai fIsText chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'test value to get Err.Number
'...continue to examine the exceptions
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
'6. ...
[/COLOR]
Function fIsText(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
value = value * 1
iErrNum = Err.Number
On Error GoTo 0
If [COLOR=#0000ff]iErrNum[/COLOR] <> 0 _
And Not IsError(value) _
And VarType(value) <> 8204 _
Then: fIsText = True
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
*MỘT VÀI CÁCH VIẾT CODE KHÁC
Ta có thể viết lại hàm IsText (excel) bằng các hàm sẵn có của vba như sau:
Mã:
Function hamIsText(ByVal value As Variant) As Boolean
If [COLOR=#0000ff]VarType[/COLOR](value) = 8 Then: hamIsText = True
End Function
Hàm VarType() này do anh sealand chỉ dẫn cho mình, xin cảm ơn !
Người ta càng trưởng thành càng tích luỹ được nhiều từ thiên hạ, trong khi bạn lại trở về tập bò. Đã vậy, lại còn dính chưởng nữa chứ. Vis dụ:
Mã:
...............................
Function fIsText(ByVal [B][COLOR=#ff0000]value As Variant[/COLOR][/B]) As Boolean
Select Case checkType(value)
Case 1: [COLOR=#008000]'isrange[/COLOR]
If [B][COLOR=#ff0000]value.Cells.Count[/COLOR][/B] > 1 Then: fIsText = False: Exit Function
GoTo lxulychung
Case 2: [COLOR=#006400]'isvariable[/COLOR]
GoTo lxulychung
Case 3: [COLOR=#008000]'isarray[/COLOR]
Case Else: 'new error code #
End Select
...............................
Bạn tính sao cái đoạn màu đỏ.
Nếu là mình thì chắc mình dùng như sau cũng ổn việc kiểm tra Text
Mã:
Function TestText(ByVal MyVar As Variant) As Boolean
TestText = VarType(MyVar) = 8
End Function
Nói chung, mình ủng hộ các bạn thôi nhưng viết Code kiểu ly khai kiến thức thiên hạ thế này thì từ Cần Thơ ra Hải Phòng chắc phải vòng sang tận chân tượng thần Tự Do mất.
Từ đầu trang 1 đến bây giờ là trang 5. Bạn có thấy chủ thớt quan tâm về code ở bài nào chưa?
Tất cả những lời đối đáp chỉ dùng để biện hộ cho tiêu đề và mục đích. Và cái mục đích là phun code - chấm hết.
Người ta càng trưởng thành càng tích luỹ được nhiều từ thiên hạ, trong khi bạn lại trở về tập bò. Đã vậy, lại còn dính chưởng nữa chứ. Vis dụ:
Mã:
...............................
Function fIsText(ByVal [B][COLOR=#ff0000]value As Variant[/COLOR][/B]) As Boolean
Select Case checkType(value)
Case 1: [COLOR=#008000]'isrange[/COLOR]
If [B][COLOR=#ff0000]value.Cells.Count[/COLOR][/B] > 1 Then: fIsText = False: Exit Function
GoTo lxulychung
Case 2: [COLOR=#006400]'isvariable[/COLOR]
GoTo lxulychung
Case 3: [COLOR=#008000]'isarray[/COLOR]
Case Else: 'new error code #
End Select
...............................
Bạn tính sao cái đoạn màu đỏ.
Nếu là mình thì chắc mình dùng như sau cũng ổn việc kiểm tra Text
Mã:
Function TestText(ByVal MyVar As Variant) As Boolean
TestText = VarType(MyVar) = 8
End Function
Nói chung, mình ủng hộ các bạn thôi nhưng viết Code kiểu ly khai kiến thức thiên hạ thế này thì từ Cần Thơ ra Hải Phòng chắc phải vòng sang tận chân tượng thần Tự Do mất.
Từ đầu trang 1 đến bây giờ là trang 5. Bạn có thấy chủ thớt quan tâm về code ở bài nào chưa?
Tất cả những lời đối đáp chỉ dùng để biện hộ cho tiêu đề và mục đích. Và cái mục đích là phun code - chấm hết.
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là non-text, giá trị nào không phải là non-text !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Hàm IsNonText chỉ đơn giản là ngược lại với hàm IsText mà thôi.
[COLOR=#008000]'tested data
' value result
'isnontext(1) 1 true
'isnontext("a") "a" false
'isnontext(1/0) #div/0! true
'isnontext(a1) 1 true
'isnontext(a1) "a" false
'isnontext(a1) #div/0! true
'isnontext(empty) empty cell true
'isnontext(true) true (logic) true
'isnontext(false) false (logic) true
'isnontext(a12:a13) {a,b} true
'Note:
'Han che: Hien tai fIsNonText chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'test value to get Err.Number
'...continue to examine the exceptions
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
'6. ...
[/COLOR]
Function fIsNonText(ByVal value As Variant) As Boolean
If Not fIsText(value) Then: fIsNonText = [COLOR=#0000ff]True[/COLOR]
End Function
Function fIsText(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
value = value * 1
iErrNum = Err.Number
On Error GoTo 0
If iErrNum <> 0 _
And Not IsError(value) _
And VarType(value) <> 8204 _
Then: fIsText = True
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là blank, giá trị nào không phải là non-blank !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Bởi vì nó đã được 'học' trước, thế nào là blank, thế nào là non-blank.
Giờ mình sẽ mô phỏng lại cách nó nhận biết một giá trị dưới dạng code:
Mã:
[COLOR=#008000]'tested data
' value result
'isblank(1) 1 false
'isblank("a") "a" false
'isblank(1/0) #div/0! false
'isblank(a1) 1 false
'isblank(a1) "a" false
'isblank(a1) #div/0! false
'isblank(empty) empty cell true
'isblank(true) true (logic) false
'isblank(false) false (logic) false
'isblank(a12:a13) {a,b} false
'Note:
'Han che: Hien tai fIsBlank chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'test and check...
'...continue to examine the exceptions
[/COLOR]
Function fIsBlank(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
[COLOR=#0000ff]If value [/COLOR][COLOR=#ff0000]= ""[/COLOR] Then: fIsBlank = True
iErrNum = Err.Number
On Error GoTo 0
If iErrNum <> 0 Then: fIsBlank = False [COLOR=#008000]'is error[/COLOR]
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Khi làm theo code trên, các bạn chú ý một số điểm sau:
Trong code trên, chúng ta đã mượn On Error Resume Next để bắt lỗi code...
Mã:
[COLOR=#0000ff]If value [/COLOR][COLOR=#ff0000]= ""[/COLOR]
+TH1 if có thể so sánh giá trị value với "", trường hợp này ko có vấn đề gì xảy ra...
+TH1 if không thể lấy giá trị của value để so sánh (lúc này value có thể là một giá trị lỗi, một range...) sẽ nảy sinh ra lỗi.
--> Khi xảy ra lỗi, nó sẽ bỏ qua câu lệnh hiện tại, và tiếp tục với các câu lệnh tiếp sau nó...
Khi viết code trên, mình thấy dùng cách đó vẫn có cái gì đó không hay,
Anh chị nào có cách nào hay hơn, vui lòng chỉ em. Thanks ! (cách varType(value)=0 thì em biết rồi).
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là blank, giá trị nào không phải là non-blank !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Bởi vì nó đã được 'học' trước, thế nào là blank, thế nào là non-blank.
Giờ mình sẽ mô phỏng lại cách nó nhận biết một giá trị dưới dạng code:
Mã:
Function fIsBlank(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
[COLOR=#0000ff]If value [/COLOR][COLOR=#ff0000]= ""[/COLOR] Then: fIsBlank = True
iErrNum = Err.Number
On Error GoTo 0
If iErrNum <> 0 Then: fIsBlank = False [COLOR=#008000]'is error[/COLOR]
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Khi làm theo code trên, các bạn chú ý một số điểm sau:
Trong code trên, chúng ta đã mượn On Error Resume Next để bắt lỗi code...
Mã:
[COLOR=#0000ff]If value [/COLOR][COLOR=#ff0000]= ""[/COLOR]
+TH1 if có thể so sánh giá trị value với "", trường hợp này ko có vấn đề gì xảy ra...
+TH1 if không thể lấy giá trị của value để so sánh (lúc này value có thể là một giá trị lỗi, một range...) sẽ nảy sinh ra lỗi.
--> Khi xảy ra lỗi, nó sẽ bỏ qua câu lệnh hiện tại, và tiếp tục với các câu lệnh tiếp sau nó...
Khi viết code trên, mình thấy dùng cách đó vẫn có cái gì đó không hay,
Anh chị nào có cách nào hay hơn, vui lòng chỉ em. Thanks ! (cách varType(value)=0 thì em biết rồi).
Nếu bạn thực hiện trên sheet thì đã có hàm ISBLANK rồi, nhưng nếu bạn mô phỏng theo hàm đó thì tôi cũng đưa cho bạn một phương pháp.
Lẽ ra, nếu không thực hiện trên Range thì chỉ cần kiểm tra nó có rỗng hay không là được, nhưng nếu hàm thực hiện trên Range thì ta bắt buộc phải cho biến của nó phải là biến Range, đồng thời phải kiểm tra xem nó có lỗi hoặc có công thức hay không, nếu nó có những giá trị đó, tất nhiên nó không phải là rỗng.
Mã:
Function IsBlanked(ByVal Value As Range) As Boolean
If IsError(Value) Or Value.HasFormula Then
IsBlanked = False
Else
IsBlanked = Value = vbNullString
End If
End Function
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là số chẵn, giá trị nào không phải là số chẵn !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Bởi vì nó đã được 'học' trước, thế nào là số chẵn, thế nào không phải là số chẵn đã được chứng minh trong phát biểu toán học sau:
Để kiểm tra một giá trị là chẳn hay lẻ thì rất đơn giản, nhưng để nó trả về giá trị giống như IsEven của Excel thì hơi phức tạp một chút.
Giờ mình sẽ mô phỏng lại cách nó nhận biết một giá trị dưới dạng code như sau:
Mã:
[COLOR=#008000]'tested data
' value result
'iseven(1) 1 false
'iseven(2) 2 true
'iseven("a") "a" value
'iseven("b") "b" value
'iseven(a1) 3 false
'iseven(a1) 4 true
'iseven(a1) "a" value
'iseven(a1) " " value
'iseven(a1) empty cell TRUE
'iseven(a1) true/ false value
'iseven(a1) #div/0! div/0
'iseven(a12:a13) {1,2} value
'Note:
'Han che: Hien tai fIsEven chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'step 1: check input value...
' ...continue to examine the exceptions
'step 2: processing data...
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
' ...
[/COLOR]Function fIsEven(ByVal value As Variant) As Variant
If IsError(value) Then: fIsEven = procXlError(value): Exit Function [COLOR=#008000]'error[/COLOR]
If Not fIsNumber(value) Then [COLOR=#008000]'non-number[/COLOR]
Select Case value
Case "": fIsEven = True [COLOR=#008000]'exception[/COLOR]
Case Else: fIsEven = CVErr(xlErrValue)
End Select
Else [COLOR=#008000]'isnumber[/COLOR]
Select Case value Mod 2
Case 0: fIsEven = True
Case Else: fIsEven = False
End Select
End If
End Function
Function fIsNumber(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
value = value * 1
iErrNum = Err.Number
On Error GoTo 0
If iErrNum = 0 Then
If value <> Empty And value <> True And value <> False Then: fIsNumber = True 'exceptions
End If
End Function
Function procXlError(ByVal value As Variant) As Variant
Select Case value
Case CVErr(xlErrName): procXlError = CVErr(xlErrName)
Case CVErr(xlErrDiv0): procXlError = CVErr(xlErrDiv0)
Case CVErr(xlErrValue): procXlError = CVErr(xlErrValue)
Case CVErr(xlErrNum): procXlError = CVErr(xlErrNum)
Case CVErr(xlErrRef): procXlError = CVErr(xlErrRef)
Case CVErr(xlErrNA): procXlError = CVErr(xlErrNA)
Case CVErr(xlErrNull): procXlError = CVErr(xlErrNull)
End Select
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là số chẵn, giá trị nào không phải là số chẵn !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Bởi vì nó đã được 'học' trước, thế nào là số chẵn, thế nào không phải là số chẵn đã được chứng minh trong phát biểu toán học sau:
Để kiểm tra một giá trị là chẳn hay lẻ thì rất đơn giản, nhưng để nó trả về giá trị giống như IsEven của Excel thì hơi phức tạp một chút.
Giờ mình sẽ mô phỏng lại cách nó nhận biết một giá trị dưới dạng code như sau:
Mã:
[COLOR=#008000]'tested data
' value result
'iseven(1) 1 false
'iseven(2) 2 true
'iseven("a") "a" value
'iseven("b") "b" value
'iseven(a1) 3 false
'iseven(a1) 4 true
'iseven(a1) "a" value
'iseven(a1) " " value
'iseven(a1) empty cell TRUE
'iseven(a1) true/ false value
'iseven(a1) #div/0! div/0
'iseven(a12:a13) {1,2} value
'Note:
'Han che: Hien tai fIsEven chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'step 1: check input value...
' ...continue to examine the exceptions
'step 2: processing data...
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
' ...
[/COLOR]Function fIsEven(ByVal value As Variant) As Variant
If IsError(value) Then: fIsEven = procXlError(value): Exit Function [COLOR=#008000]'error[/COLOR]
If Not fIsNumber(value) Then [COLOR=#008000]'non-number[/COLOR]
Select Case value
Case "": fIsEven = True [COLOR=#008000]'exception[/COLOR]
Case Else: fIsEven = CVErr(xlErrValue)
End Select
Else [COLOR=#008000]'isnumber[/COLOR]
Select Case value Mod 2
Case 0: fIsEven = True
Case Else: fIsEven = False
End Select
End If
End Function
Function fIsNumber(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
value = value * 1
iErrNum = Err.Number
On Error GoTo 0
If iErrNum = 0 Then
If value <> Empty And value <> True And value <> False Then: fIsNumber = True 'exceptions
End If
End Function
Function procXlError(ByVal value As Variant) As Variant
Select Case value
Case CVErr(xlErrName): procXlError = CVErr(xlErrName)
Case CVErr(xlErrDiv0): procXlError = CVErr(xlErrDiv0)
Case CVErr(xlErrValue): procXlError = CVErr(xlErrValue)
Case CVErr(xlErrNum): procXlError = CVErr(xlErrNum)
Case CVErr(xlErrRef): procXlError = CVErr(xlErrRef)
Case CVErr(xlErrNA): procXlError = CVErr(xlErrNA)
Case CVErr(xlErrNull): procXlError = CVErr(xlErrNull)
End Select
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Thanks anh Hoàng Trọng Nghĩa,
những phản hồi, chỉ dạy, luôn là những thứ em mong chờ...
mỗi lần post bài, là mỗi lần em bị chửi,
mỗi lần bị chửi, em lại biết thêm vài điều mới...
giờ, em lại học được một hàm mới nữa: IsNumeric .... thật là vui !
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là số lẻ, giá trị nào không phải là số lẻ !
Nhưng làm thế này mà nó có thể biết được nhỉ !
Bởi vì nó đã được 'học' trước, thế nào là số lẻ, thế nào không phải là số lẻ đã được chứng minh trong phát biểu toán học sau:
Để kiểm tra một giá trị là chẳn hay lẻ thì rất đơn giản, nhưng để nó trả về giá trị giống như IsOdd của Excel thì hơi phức tạp một chút.
...
Thoạt nghĩ, ta có thể nghĩ đơn giản như sau, nếu số nào không phải là số chẵn thì là số lẻ thôi.
Uhm, thì thực tế là vậy, nhưng trong Excel, nó không chỉ trả về giá trị là số chẳn hay số số mà còn trả về các giá trị khác như: giá trị lỗi (#DIV/0!, ...), giá trị Logic, giá trị không hợp lệ #VALUE!...
Vậy thì thay vì ta dựa vào cái hàm IsEven để tìm ra số lẻ, rồi lại phải xét trường hợp này, trường hợp nọ, thì giờ ta viết hẳn một hàm tách biệt còn hiệu quả hơn. Giờ mình sẽ mô phỏng lại cách nó nhận biết một giá trị dưới dạng code như sau:
Mã:
[COLOR=#008000]'tested data
' value result
'isodd(1) 1 true
'isodd(2) 2 false
'isodd("a") "a" value
'isodd("b") "b" value
'isodd(a1) 3 true
'isodd(a1) 4 false
'isodd(a1) "a" value
'isodd(a1) " " value
'isodd(a1) empty cell false
'isodd(a1) true/ false value
'isodd(a1) #div/0! div/0
'isodd(a12:a13) {1,2} value
'Note:
'Han che: Hien tai fIsOdd chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'step 1: check input value...
' ...continue to examine the exceptions
'step 2: processing data...
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
' ...
[/COLOR]Function fIsOdd(ByVal value As Variant) As Variant
If IsError(value) Then: fIsOdd = procXlError(value): Exit Function [COLOR=#008000]'error[/COLOR]
If Not IsNumeric(value) Then [COLOR=#008000]'non-number[/COLOR]
Select Case value
Case "": fIsOdd = False [COLOR=#008000]'exception[/COLOR]
Case Else: fIsOdd = CVErr(xlErrValue)
End Select
Else [COLOR=#008000]'isnumber[/COLOR]
Select Case [COLOR=#0000ff]value Mod 2[/COLOR]
Case Is [COLOR=#0000ff]<> 0[/COLOR]: fIsOdd = True
Case Else: fIsOdd = False
End Select
End If
End Function
Function procXlError(ByVal value As Variant) As Variant
Select Case value
Case CVErr(xlErrName): procXlError = CVErr(xlErrName)
Case CVErr(xlErrDiv0): procXlError = CVErr(xlErrDiv0)
Case CVErr(xlErrValue): procXlError = CVErr(xlErrValue)
Case CVErr(xlErrNum): procXlError = CVErr(xlErrNum)
Case CVErr(xlErrRef): procXlError = CVErr(xlErrRef)
Case CVErr(xlErrNA): procXlError = CVErr(xlErrNA)
Case CVErr(xlErrNull): procXlError = CVErr(xlErrNull)
End Select
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
Lưu ý: Code trên áp dụng theo chỉ dẫn của anh Hoàng Trọng Nghĩa, em đã thay hàm tự tạo fIsNumber = Isnumeric của VBA.
Cảm ơn anh đã chỉ dạy cho em biết thêm một hàm mới.
Lưu ý anh Hoàng Trọng Nghĩa: Code trên em sử dụng những hàm mình tự mô phỏng để làm quen với code, nên hiện tại, không sử dụng hàm Isnumeric của vba. Thân !
Theo tôi thì, sau khi đã được ai đó hướng dẫn, thì bạn phải khắc phục, cũng tương tự như hàm ISEVENT thì hàm này ngược lại, vậy cho nên bạn phải theo hướng mới mà áp dụng chứ? Hay bạn cứ vẫn thích "phô trương" phương thức của bạn?
Chỉ là góp ý, còn tùy bạn muốn nghĩ tôi sao cũng được.
Oh, hay quá ! Nó thật là thông minh, nó có thể biết được giá trị nào là giá trị logic, giá trị nào không phải là giá trị logic!
Nhưng làm thế này mà nó có thể biết được nhỉ !
Cũng đơn giản thôi, nếu giá trị trong ô đó là TRUE/ FALSE thì đó là giá trị logic.
Nghe thật là đơn giản, và code cũng đơn giản không kém !
Giờ mình sẽ phát biểu cách hoạt động của hàm trên dưới dạng code:
Mã:
[COLOR=#008000]'tested data
' value result
'islogical(1) 1 false
'islogical("a") "a" false
'islogical(a1) 1 false
'islogical(a1) "a" false
'islogical(a1) " " false
'islogical(a1) empty cell false
'islogical(a1) true/ false true
'islogical(a1) #div/0! false
'islogical(a12:a13) {1,2} false
'Note:
'Han che: Hien tai fIsLogical chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'step 1: test and check...
' ...continue to examine the exceptions
'step 2: processing data...
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
' ...
[/COLOR]Function fIsLogical(ByVal value As Variant) As Boolean
Dim iErrNum As Integer
On Error Resume Next
If value = True Or value = False And value <> "" Then: fIsLogical = True[COLOR=#008000] '<>"" , exception case[/COLOR]
iErrNum = Err.Number
On Error GoTo 0
If iErrNum <> 0 Then: fIsLogical = False
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)
*MỘT VÀI CÁCH VIẾT CODE KHÁC:
Mã:
Function fIsLogical(ByVal value As Variant) As Boolean
If [COLOR=#0000ff]VarType(value)[/COLOR] = vbBoolean Then: fIsLogical = True
End Function
Dưới đây là cách thức hoạt động của hàm đượ phát biểu dưới dạng code:
Mã:
[COLOR=#008000]'tested data
' value result
'abs(1) 1 1
'abs("a") "a" value
'abs(1/0) #div/0! div0
'abs(a1) -1 1
'abs(a1) "a" value
'abs(a1) #div/0! div0
'abs(empty) empty cell 0
'abs(true) true (logic) 1
'abs(false) false (logic) 0
'abs(a12:a13) {a,b} value
'Note:
'Han che: Hien tai fAbs chi nhan gia tri la doi so, Cell, Range.
'Algorithms
'step 1:check input type & value...
'...continue to examine the exceptions
'step 2: processing data...
'1. Number
'2. text
'3. empty
'4. true/ false
'5. xlError
' ...
[/COLOR]Function fAbs(ByVal num As Variant) As Variant
Select Case VarType(num)
Case 8204: fAbs = CVErr(xlErrValue) [COLOR=#008000]'range[/COLOR]
Case 8192: [COLOR=#008000]'array[/COLOR]
Case 10: fAbs = procXlError(num) [COLOR=#008000]'xlError[/COLOR]
Case 11 [COLOR=#008000]'logical[/COLOR]
Select Case num
Case True: fAbs = 1
Case False: fAbs = 0
End Select
Case Else
If IsNumeric(num) Then
Select Case num [COLOR=#008000]'number[/COLOR]
Case Is >= 0: fAbs = num
Case Is < 0: fAbs = -num
End Select
Else
fAbs = CVErr(xlErrValue) [COLOR=#008000]'non-number[/COLOR]
End If
End Select
End Function
Function procXlError(ByVal value As Variant) As Variant
Select Case value
Case CVErr(xlErrName): procXlError = CVErr(xlErrName)
Case CVErr(xlErrDiv0): procXlError = CVErr(xlErrDiv0)
Case CVErr(xlErrValue): procXlError = CVErr(xlErrValue)
Case CVErr(xlErrNum): procXlError = CVErr(xlErrNum)
Case CVErr(xlErrRef): procXlError = CVErr(xlErrRef)
Case CVErr(xlErrNA): procXlError = CVErr(xlErrNA)
Case CVErr(xlErrNull): procXlError = CVErr(xlErrNull)
End Select
End Function
(*Lưu ý: Code chỉ có giá trị mô phỏng, minh họa, không thể so sánh với code chuẩn & và không có giá trị thay thế !)
(*Trường hợp code có sai sót, chưa hay, hoặc có chỗ nào chưa hợp lý, xin vui lòng góp ý và chỉ dẫn thêm... bằng code!)