Bài 7.4. Hàm logic, cấu trúc lệnh (SELECT CASE, IF-THEN, FOR-NEXT...)

MyVTV Add-ins

befaint

|||||||||||||
Tham gia ngày
6 Tháng một 2011
Bài viết
11,469
Được thích
13,729
Điểm
5,168
(Danh mục các hàm trong VBA)

4. Hàm logic, cấu trúc lệnh (SELECT CASE, IF-THEN, FOR-NEXT...)

4.1. AND
PHP:
Conditions_1 And conditions_2 [… And conditions_n]
Trả về kết quả True nếu tất cả các điều kiện đưa vào là True.
PHP:
Sub AND_Fn()
    Dim bValue As Boolean, i As Long
    i = 4
    If i > 1 And i < 9 Then
        MsgBox "Value is: " & i
    End If
End Sub
4.2. OR
PHP:
Conditions_1 Or conditions_2 [… Or conditions_n]
Trả về TRUE nếu cos bất kỳ điều kiện nào là TRUE.
PHP:
Sub OR_Fn()
    Dim bValue As Boolean, i As Long
    i = 4
    If i > 3 Or i < 0 Then
        MsgBox "Value is: " & i
    End If
End Sub
4.3. IF-THEN-ELSE
PHP:
If condition_1 Then
   result_1
ElseIf condition_2 Then
  result_2
...
ElseIf condition_n Then
   result_n
Else
   result_else
End If
Trả về một giá trị nếu một điều kiện trả về TRUE hoặc một giá trị khác nếu nó trả về FALSE
Condition(s):
Các điều kiện đưa vào sẽ được xét theo thứ tự được liệt kê (từ trên xuống).
Khi một điều kiện được tìm thấy là đúng, lệnh tương ứng sẽ được thực hiện. Tất cả các điều kiện khác sẽ không được xét nữa.
Result(s): Các kết quả trả về tương ứng với điều kiện thỏa mãn.
Nếu không có điều kiện nào được đáp ứng, thì phần Else của câu lệnh IF-THEN-ELSE sẽ được thực hiện.
Các phần ElseIf và Else là tùy chọn, không bắt buộc
Nếu Result viết cùng một dòng với IF-THEN thì bỏ qua End If
PHP:
Sub IfThen_Statement_1()
Dim sChk As String, sValue As String
sChk = "A"
If sChk = "A" Then
    sValue = "Day la ket qua: " & sChk
End If
MsgBox sValue
End Sub

PHP:
Sub IfThen_Statement_2()
Dim sChk As String, sValue As String
sChk = "A"
If sChk = "A" Then
    sValue = "Day la ket qua: " & sChk
ElseIf sChk = "B" Then
    sValue = "Day la ket qua: " & sChk
ElseIf sChk = "C" Then
    sValue = "Day la ket qua: " & sChk
Else
    sValue = "Day la ket qua: " & sChk
End If
MsgBox sValue
End Sub

PHP:
Sub IfThen_Statement_3()
Dim sChk As Integer
sChk = 10
If sChk > 1 Then MsgBox "OK"
End Sub
4.4. SELECT CASE
PHP:
Select Case Expression
   Case condition_1
      result_1
   Case condition_2
      result_2
   ...
   Case condition_n
      result_n
   Case Else
      result_else
End Select
Tương tự cấu trúc lệnh If Then Else, trả về một giá trị nếu một điều kiện trả về TRUE.
Expression: Là một chuỗi hoặc giá trị số. Là giá trị cần so sánh với danh sách các điều kiện.
Condition(s): Các điều kiện được đánh giá theo thứ tự được liệt kê. Khi một điều kiện được tìm thấy là đúng, nó sẽ thực thi lệnh tương ứng và không đánh giá các điều kiện thêm nữa.
Result(s): Các kết quả trả về tương ứng với điều kiện thỏa mãn.
Nếu không có điều kiện nào thỏa mãn, thì phần Else của câu lệnh CASE sẽ được thực thi.
Phần Else là tùy chọn không bắt buộc.
PHP:
Sub CASE_Statement_1()
Dim sChk As Byte, sValue As String
sChk = 1
Select Case sChk
    Case 0
        sValue = "Day la ket qua dau tien"
    Case 1
        sValue = "Day la ket qua thu hai"
    Case Else
        sValue = "Day la ket qua con lai"
End Select
MsgBox sValue
End Sub

PHP:
Sub CASE_Statement_2()
Dim sChk As Long, sValue As String
sChk = 100
Select Case sChk
    Case Is < 100
        sValue = "Day la ket qua dau tien"
    Case Is < 200
        sValue = "Day la ket qua thu hai"
    Case Else
        sValue = "Day la ket qua con lai"
End Select
MsgBox sValue
End Sub

PHP:
Sub CASE_Statement_3()
Dim sChk As Long, sValue As String
sChk = 100
Select Case sChk
    Case 1 To 99
        sValue = "Day la ket qua dau tien"
    Case 100 To 199
        sValue = "Day la ket qua thu hai"
    Case Else
        sValue = "Day la ket qua con lai"
End Select
MsgBox sValue
End Sub

PHP:
Sub CASE_Statement_4()
Dim sChk As String, sValue As String
sChk = "B"
Select Case sChk
    Case "A"
        sValue = "Day la ket qua dau tien"
    Case "B"
        sValue = "Day la ket qua thu hai"
    Case Else
        sValue = "Day la ket qua con lai"
End Select
MsgBox sValue
End Sub
4.5. FOR...NEXT
PHP:
FOR counter = start TO end [Step increment]
   {...statements...}
NEXT [counter]
Vòng lặp duyệt qua biến đếm
counter: Biến đếm của vòng lặp
start: Giá trị đầu tiên của biến đếm
end: Giá trị cuối cùng của biến đếm
increment: Không bắt buộc. Là bước nhảy của biến đếm counter. Nó có thể là một số dương hoặc âm.
Nếu không được chỉ định, thì bước nhảy được mặc định có giá trị =1
statements: Các câu lệnh được thực hiện trong mỗi vòng lặp được duyệt.
PHP:
Sub ForNext_Statement_1()
Dim iCount As Long
For iCount = 1 To 3
    MsgBox "iCount is: " & iCount
Next iCount
End Sub

PHP:
Sub ForNext_Statement_2()
Dim iCount As Long
For iCount = 3 To 1 Step -1
    MsgBox "iCount is: " & iCount
Next iCount
End Sub

PHP:
Sub ForNext_Statement_3()
Dim iCount1 As Long, iCount2 As Long
For iCount1 = 1 To 3
    For iCount2 = 4 To 5
        MsgBox "Result is: " & iCount1 & " - " & iCount2
    Next iCount2
Next iCount1
End Sub
4.6. DO WHILE…LOOP
PHP:
Do While condition
   {...statements...}
Loop
Vòng lặp duyệt qua điều kiện đưa vào
Condition: Điều kiện được xét mỗi khi qua vòng lặp.
Nếu điều kiện được xét trả về True, câu lệnh trong vòng lặp được thực hiện. Nếu điều kiện xét trả về False thì vòng lặp bị chấm dứt.
statements: Các câu lệnh được thực hiện trong mỗi vòng lặp được duyệt.
PHP:
Sub DoWhile_Statement_1()
Dim iCount As Long
iCount = 1
Do While iCount < 5
    MsgBox iCount
    iCount = iCount + 1
Loop
End Sub

PHP:
Sub DoWhile_Statement_2()
Dim iCount1 As Long, iCount2 As Long
iCount1 = 1
Do While iCount1 < 5
    iCount2 = 6
    Do While iCount2 < 8
        MsgBox "Result is: " & iCount1 & " - " & iCount2
        iCount2 = iCount2 + 1
    Loop
    iCount1 = iCount1 + 1
Loop
End Sub
4.7. WHILE...WEND
PHP:
WHILE condition
   {...statements...}
END
Vòng lặp duyệt qua điều kiện đưa vào. Giống cấu trúc lệnh DO WHILE…LOOP
Condition: Điều kiện được xét mỗi khi qua vòng lặp.
Nếu điều kiện được xét trả về True, câu lệnh trong vòng lặp được thực hiện. Nếu điều kiện xét trả về False thì vòng lặp bị chấm dứt.
statements: Các câu lệnh được thực hiện trong mỗi vòng lặp được duyệt.
PHP:
Sub WhileWend_Statement_1()
Dim iCount As Long
iCount = 1
While iCount < 5
    MsgBox iCount
    iCount = iCount + 1
Wend
End Sub

PHP:
Sub WhileWend_Statement_2()
Dim iCount1 As Long, iCount2 As Long
iCount1 = 1
While iCount1 < 5
    iCount2 = 6
    While iCount2 < 8
        MsgBox "Result is: " & iCount1 & " - " & iCount2
        iCount2 = iCount2 + 1
    Wend
    iCount1 = iCount1 + 1
Wend
End Sub
4.8. SWITCH
PHP:
Switch(ParamArray VarExpr() As Variant)
Switch (expr1, value1, expr2, value2, ... expr_n, value_n)
Xét một danh sách các biểu thức và trả về giá trị tương ứng cho biểu thức đầu tiên trong danh sách có kết quả TRUE
VarExpr(): Danh sách các biểu thức cần được đánh giá. Chức năng SWITCH đang tìm kiếm biểu thức đầu tiên đánh giá TRUE.
Value: Danh sách các giá trị. Chức năng SWITCH sẽ trả về giá trị tương ứng với biểu thức đầu tiên đánh giá TRUE.
PHP:
Sub SWITCH_Statement()
    Dim chkValue As Long, sValue As Long
    chkValue = 2
    sValue = Switch(chkValue = 1, 100, chkValue = 2, 200, chkValue = 3, 300)
    MsgBox sValue '200
End Sub
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
11,602
Được thích
14,587
Điểm
4,868
1. Lênh rẽ nhánh điều kiện:
IF-THEN-ELSE khác SELECT-CASE như thế nào?

2. Vòng lặp DO-WHILE-LOOP khác WHILE-WEND như thế nào

3. Vòng lặp FOR-NEXT giải thích như thế hơi ít. Cần thêm 1 chút về các tính chất. Và nếu có thể thêm FOR-EACH thì càng tốt
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
11,602
Được thích
14,587
Điểm
4,868
Tôi giải thích DO-WHILE-LOOP / WHILE-WEND trước bởi vì chúng quan trọng hơn

Đi thẳng vào vấn đề, WHILE-WEND là cú pháp cũ, không nên dùng nữa. Bạn chỉ cần biết đến nó trong trường hợp đọc các code xưa trên 20 năm.

Để cho rõ hơn, khỏi mất công tranh cãi, tôi có thể nói thẳng rằng DO-WHILE-LOOP thực hiện được tất cả những cái mà WHILE-WEND có thể làm, khong khác một chút nào. VÀ khi dùng DO-WHILE-LOOP thì bạn có thể sử dụng EXIT DO để thoát giữa chừng; lệnh này hoàn toàn khong thể thực hiện được với WHILE-WEND

DO-WHILE cũng là câu lệnh vòng lặp rất đa dạng (đa dạng thì cũng đi đôi với rắc rối; vì vậy có tốt hay khong là tuỳ theo quan niệm riêng)
Bạn có thể
Do While (điều kiện)
code...
Loop
Hoặc
Do
code...
Loop While (điều kiện)
Điểm khác nhau giữa hai cách code trên là cách 2 bảo đảm vòng lặp thực hiện ít nhất 1 lần.

Do While cũng có thể đảo ngược điều kiện bằng cách đổi từ khoá While thành Until
 

anhtuanle123

Thành viên thường trực
Tham gia ngày
8 Tháng sáu 2009
Bài viết
311
Được thích
169
Điểm
668
Tuổi
36
phần vòng lặp này hay nè , lặp đi lặp lại 1 cái gì đấy , mình xin góp vui thêm 2 cách để lặp , nhưng để nghiên cứu thêm thôi , chắc cũng ít xài !^

mượn ví dụ tính tổng của bác befaint

1 : lệnh nhảy goto , nhảy đến 1 vị trí nào đó trong code ,
lệnh này có vẻ gần gũi với lệnh mã máy !


Sub WhileWend_Statement_1()
Dim iCount As Long
iCount = 1
AAA:
MsgBox iCount
iCount = iCount + 1

if iCount <5 then
goto AAA
END IF

End Sub


2 : lặp kiểu đệ quy , lợi dụng tính chất đệ quy ,
đại khái là 1 hàm có thể gọi lại chính nó , nhưng làm kiểu này phải có 1 hàm chạy mồi khởi tạo bên dưới , thứ nữa là chỉ chạy được các vòng lặp nhỏ , lớn quá thì bị tràn @@ !

Option Explicit
Dim
iCount As Long

Sub WhileWend_Statement_1()
If iCount < 5 Then

MsgBox iCount
iCount = iCount + 1
WhileWend_Statement_1

End If
End Sub


Sub run_WhileWend_Statement_1()
iCount = 1
WhileWend_Statement_1
End Sub
 

haog

Thành viên mới
Tham gia ngày
14 Tháng chín 2017
Bài viết
28
Được thích
10
Điểm
103
Cách viết
Conditions_1 And conditions_2 [… And conditions_n]
làm tôi hiểu And như là toán tử, chức không phải hàm. Hay đây là cách gọi mới. Và 3 + 5 có là
"hàm cộng" (+) không.
Nếu đúng là cách gọi mới thì có lẽ khái niệm biểu thức cũng trở nên vô nghĩa.
Mong được khẳng định. Cảm ơn
 

HieuCD

Chuyên gia GPE
Tham gia ngày
14 Tháng chín 2010
Bài viết
8,005
Được thích
16,258
Điểm
4,668
Cách viết

làm tôi hiểu And như là toán tử, chức không phải hàm. Hay đây là cách gọi mới. Và 3 + 5 có là
"hàm cộng" (+) không.
Nếu đúng là cách gọi mới thì có lẽ khái niệm biểu thức cũng trở nên vô nghĩa.
Mong được khẳng định. Cảm ơn
Theo: https://vi.wikipedia.org/wiki/Toán_tử
"Trong toán học, một toán tử (tiếng Anh operator, phân biệt với operation - phép toán) là một hàm"
Tùy tình huống "And" có thể gọi là "Hàm" hay là "Toán tử"
 

ptm0412

Bad Excel Member
Thành viên BQT
Super Moderator
Tham gia ngày
4 Tháng mười một 2007
Bài viết
10,874
Được thích
31,546
Điểm
9,718
Tuổi
59
Nơi ở
Gò Vấp

HieuCD

Chuyên gia GPE
Tham gia ngày
14 Tháng chín 2010
Bài viết
8,005
Được thích
16,258
Điểm
4,668
Trong công thức Excel, And là 1 hàm có 2 hoặc nhiều đối số.
Trong lập trình đa phần gọi là toán tử logic
Gọi toán tử And là hàm And không sai, nhiều người thấy lạ vì lầm tưởng toán tử và hàm khác nhau hoàn toàn
so sánh 2 tình huống
a=( x And y)
b= (x Mod y)
Mod nên gọi là "Hàm" hay "Toán tử"
 

ptm0412

Bad Excel Member
Thành viên BQT
Super Moderator
Tham gia ngày
4 Tháng mười một 2007
Bài viết
10,874
Được thích
31,546
Điểm
9,718
Tuổi
59
Nơi ở
Gò Vấp
so sánh 2 tình huống
a=( x And y)
b= (x Mod y)
Mod nên gọi là "Hàm" hay "Toán tử"
Ờ thì tôi cũng nói là "đa phần" gọi.
b= (x Mod y): Mod là hàm và cú pháp hàm Mod nó như thế chứ không phải tên_hàm(các đối số).
a = (x And y): Cái đầu máy móc và cố chấp của tôi cũng cứ không gọi là hàm, đó là biểu thức có 2 vế: vế trái là 1 giá trị luận lý, vế phải là 1 phát biểu luận lý gồm 2 thành phần And với nhau. Riêng trong vế phải thì And cũng là toán tử vì x và y là 2 giá trị luận lý riêng, kết hợp với nhau bởi 1 toán tử luận lý.
 

haog

Thành viên mới
Tham gia ngày
14 Tháng chín 2017
Bài viết
28
Được thích
10
Điểm
103
Cảm ơn các anh đã có trao đổi
Tùy tình huống "And" có thể gọi là "Hàm" hay là "Toán tử"
Trong công thức Excel, And là 1 hàm có 2 hoặc nhiều đối số. Trong lập trình đa phần gọi là toán tử logic.
Tôi đã đọc thêm cả "Theo: https://vi.wikipedia.org/wiki/Toán_tử" (theo gợi ý)
Tôi cũng nghĩ đến đặc trưng của tin học, ví dụ lệnh gán trong C được coi là Hàm, và đúng nó là hàm nên mới có câu lệnh a=b=c=1+2 (tất nhiên học quá lâu rồi, nếu không phải thì bảo, chứ đừng "ném đá").
Và hàm hay toán tử đều là phép biến đổi từ tập này vào tập kia. Tức là gọi sao cũng được.

Nhưng nếu quan tâm đến "lịch sử" của khái niệm toán tử, có khởi nguồn từ "phép toán" số học, được mở rộng cho các đối tượng như vec to (không gian n chiều), ma trận... thì toán học rất chú ý đến tính giao hoán, kết hợp và phân phối. Cả thứ tự ưu tiên nữa (ví dụ "4 + 5 mod 3" cho kq mấy?) - tính ưu tiên là đặc trưng của "toán tử 2 ngôi". Và không có nghiên cứu tương tự nào cho hàm.
Vậy nên, lấy ví dụ là AND, nếu viết ở dạng "a AND b" thì AND là toán tử. Chỉ được viết trong code.
Còn viết ở dạng "AND(a,b)" thì AND là hàm. Chỉ được viết trong Sheet.
Khi biểu thức có nhiều toán tử thì phải đặc biệt chú ý đến tính ưu tiên của từng toán tử.

Tôi hy vọng ý kiến này và có thể có nhiều các ý kiến khác sẽ góp phần làm cho chuyên đề này, một chuyên đề rất hay, trở nên chuẩn mực hơn.
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
11,602
Được thích
14,587
Điểm
4,868
...Tôi cũng nghĩ đến đặc trưng của tin học, ví dụ lệnh gán trong C được coi là Hàm, và đúng nó là hàm nên mới có câu lệnh a=b=c=1+2 (tất nhiên học quá lâu rồi, nếu không phải thì bảo, chứ đừng "ném đá").
Và hàm hay toán tử đều là phép biến đổi từ tập này vào tập kia. Tức là gọi sao cũng được.
...
Tuy tôi vẫn hay nhắc tới C, nhưng ở đây, tôi cần chỉnh rằng quan niệm "hàm" của C (và cả dòng họ các ngôn ngữ loại ấy) nó khác.
Phép gán trong C là toán tử.
C bắt nguồn từ hệ điều hành Unix cho nên nó giữ khái niệm "chained", tất cả các biểu thức, các lệnh đều có kết quả (output) làm đầu vào (input) cho lệnh kế.
a=b=c=1+2 ==> biểu thức 1+2, kết quả là 3, gán cho c; kết quả của phép gán này là 3, gán cho b; kết quả của phép gán này là 3, gán cho a.
Khi trình dịch dịch một file C thì nó dịch toán tử thẳng ra code. Các hàm được đưa vào danh sách hàm cùng với chữ ký (prototype) của chúng và chờ kết nối.

Lưu ý: C++ (không phải C) cho phép viết hàm chồng toán tử cho nên quan niệm hàm và toán tử trong C++ hơi khó phân biệt.

...
Nhưng nếu quan tâm đến "lịch sử" của khái niệm toán tử, có khởi nguồn từ "phép toán" số học, được mở rộng cho các đối tượng như vec to (không gian n chiều), ma trận... thì toán học rất chú ý đến tính giao hoán, kết hợp và phân phối. Cả thứ tự ưu tiên nữa (ví dụ "4 + 5 mod 3" cho kq mấy?) - tính ưu tiên là đặc trưng của "toán tử 2 ngôi". Và không có nghiên cứu tương tự nào cho hàm.
...
Đừng lầm "nguyên tắc", "luật định", và "nghiên cứu"
Cách làm việc của hàm tuỳ thuộc vào "luật định" của ngôn ngữ. (thực ra toán tử cũng vậy, chỉ là toán tử thì luật định theo chuẩn thống nhất hơn)
ví dụ:
x = F1( f1(a), f2(a), f3(a) )
Nếu các hàm f1, f2, f3 không hề thay đổi tham số của nó (byVal) thì chả có gì đáng nói. Nhưng nếu nó thay đổi (byRef) thì sao?
Với VBA:
Microsoft sẽ có văn bản xác định rõ là hàm nào tính trước (trái sang phải hay phải sang trái)
VBA là của Microsoft cho nên Microsoft toàn quyền quyết định.
Với ngôn ngữ X:
Nếu X có tiêu chuẩn (vi dụ C có tiêu chuẩn ANSI gì gì đó - hình như hiện tại là C17) thì tiêu chuẩn ấy sẽ nói rõ cách sử lý.
Nếu tiêu chuẩn không muốn buộc rõ thì chính tiêu chuẩn sẽ nói "không xác định". Lúc ấy người viết trình dịch có quyền lô gic theo ý mình.

Thứ tự ưu tiên toán tử quan trọng với trình độ nhập môn.
Muón qua cấp cao hơn phải hiểu rõ cách hoạt động của các hàm, luật lô gic tắt, vv...
 
Lần chỉnh sửa cuối:

ptm0412

Bad Excel Member
Thành viên BQT
Super Moderator
Tham gia ngày
4 Tháng mười một 2007
Bài viết
10,874
Được thích
31,546
Điểm
9,718
Tuổi
59
Nơi ở
Gò Vấp
Chuyên sâu thì tôi không dám nói vì không biết. Riêng về And, Or, Not trong VBA thì tôi nghĩ đó là toán tử.
1. Với 3 giá trị logic có quan hệ and (*) với nhau: (and viết thường do chưa xác định là hàm hay toán tử)
- nếu là hàm trên sheet Excel thì And(a, b, c). Hàm And được dùng chỉ 1 lần
- Nếu trong VBA thì phải ghi a And b And c. Nếu And là hàm vậy thì hàm được sử dụng 2 lần, và cú pháp viết như vậy thì hiểu là 2 hàm lồng nhau hay thế nào? Nếu lồng nhau thì lồng kiểu And(a, And(b,c)) hay And(And(a,b),c)? Theo tôi hãy hiểu là toán tử và toán tử có thứ tự ưu tiên tính toán cho đỡ nhức đầu

2. Với các giá trị logic có quan hệ phức tạp vừa and vừa or, thì nếu hiểu là hàm lại càng đau đầu hơn. Ví dụ:
- Hàm Excel =Or(And(a,b),c) thì quá rõ ràng: hàm nào ra hàm đó
- Trong VBA: a And b Or c: Nếu hiểu là hàm thì gây lúng túng ở chỗ đối số của hàm Or là b hay là (a And b)? Làm sao để biết? Nếu 2 hàm lồng nhau thì cái nào ngoài, cái nào trong?
Trong khi đó nếu hiểu là toán tử và căn cứ theo quy tắc ưu tiên của toán tử thì biết ngay. (Hàm thì không có quy tắc ưu tiên, muốn hàm nào ra hàm đó là phải mở đóng ngoặc.)
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
11,602
Được thích
14,587
Điểm
4,868
Tôi không hiểu? 8x trở về trước có tôi trong đó không? Tôi có ngô nghê không? Những phát biểu của tôi có đồng nhất hàm với toán tử không?
Chính từ "8x" cũng là từ mới. Người VN thích dùng x này x nọ chứ nó đâu phải là những mốc tiêu chuẩn phân biệt các thế hệ!

Chương trình khoa học của tôi học ở Trung Học định nghĩa nhiều thứ mà mấy người sau này gọi là "ngô nghê". Thật ra là tại họ không biết rằng VN chịu ảnh hưởng văn hoá của Tàu, Pháp, và Mỹ (riêng chữ viết thì lại chịu ảnh hưởng Bồ đào nha) cho nên cách dịch các từ khoa học bị không đồng nhất. Chỉ riêng cái khí N mà tôi bị buộc phải học 3 tên Ni-tơ, Ni-trô, và Nai-tô-gien.
Chương trình Toán thì những người phê bình là do không biết gì về cải cách giáo dục ở miền Nam giai đoạn ấy. Cải cách thì đương nhiên nó có những cái khó ban đầu (Tây gọi là teething problems). Một chương trình từ đặt nặng lý thuyết sang thực dụng chính Âun Mỹ cũng bị vấn đề. Sách giáo khoa chuyển từ phương pháp dạy theo Pháp sang dạy theo Mỹ. Chưa kể những năm chiến tranh, nhiều thứ bị cắt bớt. Điển hình năm Mậu Thân, chương trình Toán thi Tú tài bị cắt bớt rất nhiều. Thế hệ chúng tôi là thế hệ mà chương trình Toán được chuyển trọng tâm từ cổ điển sang giải tích và đại số. (Tôi có nghe nói trường Kiểu Mẫu Thủ Đức dạy chương trình cập nhật mới của Mỹ - tức là mới hơn hầu hết các trường khác bên Mỹ). Được vài năm thì giải phóng, việc chuyển bị ngưng trệ.
Vì phải trải qua bao nhiêu lần lộn xộn như thế cho nên đối với tôi, những cái tên "Đại số", "Hàm số" chả có gì đặc biệt cả, gọi chúng là "con bò, con heo,..." tôi vẫn học Toán được như thường.

Chuyên sâu thì tôi không dám nói vì không biết. Riêng về And, Or, Not trong VBA thì tôi nghĩ đó là toán tử.
1. Với 3 giá trị logic có quan hệ and (*) với nhau: (and viết thường do chưa xác định là hàm hay toán tử)
- nếu là hàm trên sheet Excel thì And(a, b, c). Hàm And được dùng chỉ 1 lần
- Nếu trong VBA thì phải ghi a And b And c. Nếu And là hàm vậy thì hàm được sử dụng 2 lần, và cú pháp viết như vậy thì hiểu là 2 hàm lồng nhau hay thế nào? Nếu lồng nhau thì lồng kiểu And(a, And(b,c)) hay And(And(a,b),c)? Theo tôi hãy hiểu là toán tử và toán tử có thứ tự ưu tiên tính toán cho đỡ nhức đầu
Trong VBA thì And, Or, Not là toán tử.
And và Or là toán tử hai ngôi (a And b)
Not là toán tử một ngôi (Not a). Giống như dấu trừ (-) khi nó được dùng làm toán tử đổi dấu.
Mod, theo nhiệm vụ và cú pháp thì rõ ràng là toán tử.

Trong worksheet chỉ có những toán tử đơn giản (cộng, trừ, nhân, chia, luỹ thừa, đổi dấu) và toán tử so sánh (=, <=, >=, <>). Tất cả những cái còn lại là hàm.

2. Với các giá trị logic có quan hệ phức tạp vừa and vừa or, thì nếu hiểu là hàm lại càng đau đầu hơn. Ví dụ:
- Hàm Excel =Or(And(a,b),c) thì quá rõ ràng: hàm nào ra hàm đó
- Trong VBA: a And b Or c: Nếu hiểu là hàm thì gây lúng túng ở chỗ đối số của hàm Or là b hay là (a And b)? Làm sao để biết? Nếu 2 hàm lồng nhau thì cái nào ngoài, cái nào trong?
Trong khi đó nếu hiểu là toán tử và căn cứ theo quy tắc ưu tiên của toán tử thì biết ngay. (Hàm thì không có quy tắc ưu tiên, muốn hàm nào ra hàm đó là phải mở đóng ngoặc.)
Thứ tự ưu tiên là chuyện nhỏ. Luật chung thì dấu ngoặc () là ưu tiên cao nhất. Muốn không nhầm thì cứ tọng một đống dấu ngoặc vào.

Chuyện quan trọng là nguyên tắc lô gic tắt (shortcut).
Các hàm dùng trong worksheet có theo luật tắt: ví dụ And(a, b, c) nếu a không thoả thì hàm And sẽ không tính tiếp b và c.
Hàm Choose trong Worksheet đi thẳng vào vị trí index mà không cần phải đi qua cả list.
Nhưng Choose trong VBA tính cả list.
Code:
Function fa()
MsgBox 1
End Function
Function fb()
MsgBox 2
End Function
Function fc()
MsgBox 3
End Function
' -----
Sub t()
a = Choose(3, fa(), fb(), fc())
End Sub
Chạy thử sub t sẽ thấy cả ba hàm fa, fb, fc đều được gọi
Nhưng nếu vào ô A1, gõ =CHOOSE(3, fa(), fb(), fc()) sẽ thấy chỉ fc được chạy.
 

ptm0412

Bad Excel Member
Thành viên BQT
Super Moderator
Tham gia ngày
4 Tháng mười một 2007
Bài viết
10,874
Được thích
31,546
Điểm
9,718
Tuổi
59
Nơi ở
Gò Vấp
Mod, theo nhiệm vụ và cú pháp thì rõ ràng là toán tử.
... Luật chung thì dấu ngoặc () là ưu tiên cao nhất. Muốn không nhầm thì cứ tọng một đống dấu ngoặc vào.
Thế mà tôi lại cho Mod là hàm (chắc bị ám ảnh hàm của worksheet) với cú pháp đặc biệt. Cũng bởi nghĩ nó đặc biệt nên tôi phải "tọng 1 đống dấu ngoặc vào", nên dù là hàm hay toán tử đi nữa cũng không bị sai.
Thí dụ với những tính toán như sau
- 5 Mod 10 Mod 4
- 7 Mod 2 - 1
- 72 - 69 Mod 9
Để chắc ăn thì phải "tọng"
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
11,602
Được thích
14,587
Điểm
4,868
Chôm trên docs của Microsoft:
Để ý: dấu trừ thật ra có thể là toán tử trừ của con toán trừ (subtraction), nhưng cũng có thể là toán tử đổi dấu (negation). Và hai trường hợp này có thứ tự ưu tiên khác nhau.

1617200903448.png


Theo bảng trên, toán tử được phân ra làm 3 thể loại: toán, so sánh, và lô gic.
(bạn nào muốn phản đối về toán tử & thì khoan chờ đọc tiếp)

Dịch:

Khi một biểu thức có nhiều con toán thì từng phần sẽ được tính toán và giải quyết theo một trật tự định sẵn (bởi ngôn ngữ), gọi là luật ưu tiên toán tử.

Khi biểu thức có nhiều toán tử thuộc về nhiều thể loại khác nhau thì thể loại toán sẽ ưu tiên tính trước, kế đó đến lượt thể loại so sánh, và cuối cùng là lô gic.

Tất cả các toán tử so sánh đều có ưu tiên ngang nhau; tức là, chúng sẽ được tính từ trái sang phải, theo trình tự xuất hiện của chúng.

Toán tử toán và toán tử so sánh được tính ưu tiên theo trật tự (của bảng trên).


1617202102200.png

Toán tử nối chuỗi & không phải là thể loại toán số, nhưng trên bình diện ưu tiên của toán tử thì nó đi sau tất cả các toán tử toán số, và trước tất cả các toán tử so sánh.

Toán tử "Like" có đồng hạng ưu tiên với các toán tử so sánh, tuy trên thực tế nó là dạng so sánh theo dạng (với wildcards).

Toán tử "Is" là toán tử so sánh tham chiếu đối tượng. Toán tử này không so sánh đối tượng hay trị; nó chỉ xét xem hai tham chiếu có cùng trỏ vào một đối tượng hay không.
 

haog

Thành viên mới
Tham gia ngày
14 Tháng chín 2017
Bài viết
28
Được thích
10
Điểm
103
Phép gán trong C là toán tử.
Tôi đã thử và đã chạy trên Dev-C++, code như sau
Mã:
    int i, j, k ; i=(j=3)+(k=5);
    cout << "\n i= " << i << " j= " <<j << " k= "<< k;
Kết quả tốt. Nhưng vẫn mong Vetmini hoặc ai có ví dụ tốt hơn xin được tham khảo. Và cũng mong có người chỉ ra những thông tin khẳng định tốt hơn, ví dụ tính ưu tiên của "toán tử =" với các toán tử khác, có thể là 1 trang web nào đó.
Thế mà tôi lại cho Mod là hàm (chắc bị ám ảnh hàm của worksheet) với cú pháp đặc biệt.
Vâng, cái nhầm lẫn này cũng là của tôi. Và dần dần tôi nhận ra: Nhiều toán tử và hàm của Excel là khác nhau trong 2 môi trường sheet hay code. Xin phép anh đưa ra vài ví dụ:
+ Cùng toán tử đổi dấu, nhưng -2^2 trong sheet cho 4, còn trong code cho -4.
+ Hàm trim(text) trong code xóa mọi ký tự trắng thừa ở đầu và cuối text, còn trong sheet, nó có thêm xử lý: thay mọi dãy dấu cách có lẫn trong text thành 1 dấu cách.
+ Hàm And, Or trong sheet "ép các đối số (là số)" thành giá trị logic và cho kết quả kiểu Boolean. Ví dụ =and(-4) cho True. Còn toán tử And, Or xử lý từng bit của các đối số (là số) và cho kết quả là số.
+ v.v...
lệnh nhảy goto , nhảy đến 1 vị trí nào đó trong code ,
Tôi cho rằng lệnh goto là tốt hay xấu là tùy hoàn cảnh dùng. Nếu trong 1 chương trình nghiêm chỉnh thì không nên dùng. Còn dùng nó để giải thích cú pháp một số lệnh lặp thì làm cho người mới học dễ hiểu hơn. Cũng xin phép đưa ra ví dụ
Đoạn chương trình sau
Mã:
Dim i as Byte
do
        'các lệnh nào đó, ví dụ 2 lệnh sau
         i=i+1: debug.print i
loop
là như đoạn
Mã:
Dim i as Byte
10
        'các lệnh nào đó, ví dụ 2 lệnh sau
         i=i+1: debug.print i
goto 10
Và như vậy nó lặp vô hạn. Nên khi chạy, thì phải chạy theo vết. Tuy nhiên tôi khai kiểu i là Byte để nếu vô tình bạn không chạy theo vết thì i sẽ bị "tràn" và chương trình sẽ báo lỗi. Và bạn sẽ dừng được.

Cuối cùng tôi hỏi: cách nào để mở lại 1 trang GPE đã từng mở và viết bài. Tôi đã mất khá lâu mới mở lại được trang này. Khộ. Kể cả tôi đã đánh dấu là "theo dõi trang này" nhưng không biết làm sao để mở lại các trang đang theo dõi. Cảm ơn.
 
Lần chỉnh sửa cuối:

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
11,602
Được thích
14,587
Điểm
4,868
...
Vâng, cái nhầm lẫn này cũng là của tôi. Và dần dần tôi nhận ra: Nhiều toán tử và hàm của Excel là khác nhau trong 2 môi trường sheet hay code. ...
Cái lầm của bạn là ngỡ VBA liên hệ mật thiết với Excel.
Sự thực thì VBA là của Access. Microsoft về sau phổ biến cho các ứng dụng khác của Office có thể sử dụng.
Vì vậy, nguyên tắc hoạt động của VBA chịu ảnh hưởng từ cái gốc Access của nó.

...
Tôi cho rằng lệnh goto là tốt hay xấu là tùy hoàn cảnh dùng. Nếu trong 1 chương trình nghiêm chỉnh thì không nên dùng. Còn dùng nó để giải thích cú pháp một số lệnh lặp thì làm cho người mới học dễ hiểu hơn. ...
Theo quan niệm chung của đa số dân lập trình thì nó xấu nhiều hơn tốt. Nói cách khác, những cái lợi của nó không xứng đáng bù đắp những cái hại nó có thể gây ra.
 
Top Bottom