VBA Nâng cao: NOT, OR, XOR và AND toán tử logic tối quan trọng cho tư duy lập trình

Liên hệ QC

HeSanbi

Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
Tham gia
24/2/13
Bài viết
2,382
Được thích
3,536
Giới tính
Nam
Hôm nay tôi chia sẻ đến các bạn một kiến thức, mà hầu như các Lập trình viên sơ cấp, không được giảng rỏ về 4 toán tử NOT, OR, AND XOR căn bản trong mọi ngôn ngữ lập trình.

NOT, OR, AND XOR không phải trả về giá trị đúng sai như các bạn thường vận dụng. Vì chúng là toán tử, chính xác thì chúng là toán tử tính toán chỉ khác cộng, trừ, nhân, chia, ..., chúng tính toán dựa vào phép toán bitwise.
Nhưng ít sách vở căn bản nào giải thích rõ cho các bạn biết bản chất của chúng.

Chính vì vậy mà hôm nay tôi chia sẻ thêm kiến thức tuy căn bản nhưng lại là tiền đề cho những cấu trúc mã Nâng cao sau này. Vì chúng là cơ sở tạo các cấu trúc mã với giải thuật, thuật toán sau rộng hơn trong Lập trình. Vì chúng không chỉ có trong một ngôn ngữ là VBA.

Để bắt đầu chủ đề các bạn cần xem kiến thức cơ bản về các toán tử logic NOT, OR, AND XOR tại Wikipedia:
(Tiếng Anh) https://en.wikipedia.org/wiki/Bitwise_operation
(Tiếng Việt) https://vi.wikipedia.org/wiki/Phép_toán_thao_tác_bit

Trong phép toán thao tác bit (bitwise) gồm có: Dịch chuyển bit, xóa bit, và quay bit.
Các toán tử logic hội tụ đủ các thao tác này nên ta tận dụng như các ví dụ dưới dây.


CÁC VÍ DỤ:
Ví dụ 1: Cho một hộp đựng có thể chứa Táo, Cam, Chanh, Bưởi, Ổi. Nếu trong hộp đựng đã chứa Táo, Cam, Chanh thì thêm Bưởi Ổi.

Với mã dưới đây là một giải pháp chứ không phải giải thuật để giải bài toán trên:

JavaScript:
Sub ThemTraiCay1()
  Dim Thung, TraiCay, i, j, b As Border
  Const Tao = 1, Cam = 2, Chanh = 3, Buoi = 4, Oi = 5
  Thung = Array(Tao, Cam, Chanh)
  TraiCay = Array(Tao, Cam, Chanh, Buoi, Oi)
  For j = 0 To UBound(TraiCay)
    b = True
    For i = 0 To UBound(Thung)
      If Thung(i) = TraiCay(j) Then b = False: Exit For
    Next
    If b Then
      ReDim Preserve Thung(1 To UBound(Thung) + 1): Thung(UBound(Thung)) = TraiCay(j)
    End If
  Next
End Sub


Với mã dưới đây là giải thuật để giải bài toán trên nhanh và hiệu quả khi sử dụng toán tử OR:
JavaScript:
Sub ThemTraiCay2()
  Dim Thung, TraiCay
  Const Tao = 2 ^ 0, Cam = 2 ^ 1, Chanh = 2 ^ 2, Buoi = 2 ^ 3, Oi = 2 ^ 4
  Thung = Tao + Cam + Chanh
  TraiCay = Tao Or Cam Or Chanh Or Buoi Or Oi
  Thung= Thung Or TraiCay

  Debug.Print "  Tao: "; Tao And Thung
  Debug.Print "  Cam: "; Cam And Thung
  Debug.Print "Chanh: "; Chanh And Thung
  Debug.Print " Buoi: "; Buoi And Thung
  Debug.Print "   Oi: "; Oi And Thung
End Sub


Ví dụ 2: Loại bỏ Cam và Chanh trong thùng trái cây, ta dùng toán tử AND và NOT.
JavaScript:
Sub LoaiBoTraiCay1()
  Dim Thung, TraiCay
  Const Tao = 2 ^ 0, Cam = 2 ^ 1, Chanh = 2 ^ 2, Buoi = 2 ^ 3, Oi = 2 ^ 4
  Thung = Tao + Cam + Chanh + Buoi + Oi
  Thung = Thung And Not Chanh And Not Cam
  Debug.Print "  Tao: "; Tao And Thung
  Debug.Print "  Cam: "; Cam And Thung
  Debug.Print "Chanh: "; Chanh And Thung
  Debug.Print " Buoi: "; Buoi And Thung
  Debug.Print "   Oi: "; Oi And Thung
End Sub


Ví dụ 3: Tìm trái cây giống nhau trong hai thùng trái cây ta dùng toán tử AND:
JavaScript:
Sub TrungTraiCay1()
  Dim Thung1, Thung2, TraiCay
  Const Tao = 2 ^ 0, Cam = 2 ^ 1, Chanh = 2 ^ 2, Buoi = 2 ^ 3, Oi = 2 ^ 4
  Thung1 = Tao + Cam + Chanh + Buoi
  Thung2 = Chanh + Buoi + Oi
  TraiCay = Thung1 And Thung2
  Debug.Print "  Tao: "; Tao And TraiCay
  Debug.Print "  Cam: "; Cam And TraiCay
  Debug.Print "Chanh: "; Chanh And TraiCay
  Debug.Print " Buoi: "; Buoi And TraiCay
  Debug.Print "   Oi: "; Oi And TraiCay
End Sub


Các bạn sẽ thấy tôi đã khai báo các mục Trái Cây là lũy thừa cơ số 2, tức là đơn vị bit 0 và 1
JavaScript:
Const Tao = 2 ^ 0, Cam = 2 ^ 1, Chanh = 2 ^ 2, Buoi = 2 ^ 3, Oi = 2 ^ 4

Hoặc dạng HEXADECIMAL:
JavaScript:
Const Tao =&H1, Cam = &H2, Chanh = &H4, Buoi = &H8, Oi = &H10

Đặt chi trái cây, ví dụ Cam, Chanh và Bưởi cùng một chi:
JavaScript:
Const Citrus = Cam + Chanh + Buoi

Thay vì sử dụng dấu +, hãy sử dụng OR:
JavaScript:
Const Citrus = Cam OR Chanh OR Buoi

Tại sao OR mà không phải +, chỉ cần bạn thêm Chanh vào là sẽ rõ, toán tử OR sẽ gộp chứ không cộng dồn:
JavaScript:
Const Citrus = Cam + Chanh + Chanh + Buoi
Là một giá trị chỉ chứa Cam, nhưng không thuộc các mục khai báo khác.

JavaScript:
Const Citrus = Cam OR Chanh OR Chanh OR Buoi
Thì giá trị vẫn là Cam + Chanh + Buoi

Các bạn cũng có thể sử dụng số âm để đặt các mục, phủ định của một số không ÂM là số ÂM, nên ta sử dụng toán tử NOT:
JavaScript:
Const Tao = NOT 2 ^ 0, Cam =NOT 2 ^ 1, Chanh =NOT 2 ^ 2, Buoi =NOT 2 ^ 3, Oi =NOT 2 ^ 4






Vì chưa có thời gian để viết bài thêm: nên tạm thời tôi dừng ở đây.
****Bài viết sẽ được tiếp tục cập nhật thêm****
 
Lần chỉnh sửa cuối:
Hôm nay tôi chia sẻ đến các bạn một kiến thức, mà hầu như các Lập trình viên sơ cấp, không được giảng rỏ về 4 toán tử NOT, OR, AND và XOR căn bản trong mọi ngôn ngữ lập trình.

NOT, OR, AND và XOR không phải trả về giá trị đúng sai như các bạn thường vận dụng. Vì chúng là toán tử, chính xác thì chúng là toán tử tính toán chỉ khác cộng, trừ, nhân, chia, ..., chúng tính toán dựa vào phép toán bitwise.
Nhưng ít sách vở căn bản nào giải thích rõ cho các bạn biết bản chất của chúng.

Chính vì vậy mà hôm nay tôi chia sẻ thêm kiến thức tuy căn bản nhưng lại là tiền đề cho những cấu trúc mã Nâng cao sau này. Vì chúng là cơ sở tạo các cấu trúc mã với giải thuật, thuật toán sau rộng hơn trong Lập trình. Vì chúng không chỉ có trong một ngôn ngữ là VBA.

Để bắt đầu chủ đề các bạn cần xem kiến thức cơ bản về các toán tử logic NOT, OR, XOR và AND tại Wikipedia:
(Tiếng Anh) https://en.wikipedia.org/wiki/Bitwise_operation
(Tiếng Việt) https://vi.wikipedia.org/wiki/Phép_toán_thao_tác_bit


Ví dụ:
Ví dụ 1: Cho một hộp đựng có thể chứa Táo, Cam, Chanh, Bưởi, Ổi. Nếu trong hộp đựng đã chứa Táo, Cam, Chanh thì thêm Bưởi và Ổi.

Với mã dưới đây là một giải pháp chứ không phải giải thuật để giải bài toán trên:

JavaScript:
Sub ThemTraiCay1()
  Dim Thung, TraiCay, i, j, b As Border
  Const Tao = 1, Cam = 2, Chanh = 3, Buoi = 4, Oi = 5
  Thung = Array(Tao, Cam, Chanh)
  TraiCay = Array(Tao, Cam, Chanh, Buoi, Oi)
  For j = 0 To UBound(TraiCay)
    b = True
    For i = 0 To UBound(Thung)
      If Thung(i) = TraiCay(j) Then b = False: Exit For
    Next
    If b Then
      ReDim Preserve Thung(1 To UBound(Thung) + 1): Thung(UBound(Thung)) = TraiCay(j)
    End If
  Next
End Sub

Với mã dưới đây là giải thuật để giải bài toán trên nhanh và hiệu quả:
JavaScript:
Sub ThemTraiCay2()
  Dim Thung, TraiCay
  Const Tao = 2 ^ 0, Cam = 2 ^ 1, Chanh = 2 ^ 2, Buoi = 2 ^ 3, Oi = 2 ^ 4
  Thung = Tao + Cam + Chanh
  TraiCay = Tao Or Cam Or Chanh Or Buoi Or Oi
  Thung= Thung Or TraiCay

  Debug.Print "  Tao: "; Tao And Thung
  Debug.Print "  Cam: "; Cam And Thung
  Debug.Print "Chanh: "; Chanh And Thung
  Debug.Print " Buoi: "; Buoi And Thung
  Debug.Print "   Oi: "; Oi And Thung
End Sub


Vì chưa có thời gian để viết bài thêm: nên tạm thời tôi dừng ở đây.
****Bài viết sẽ được tiếp tục cập nhật thêm****
Đang không hiểu thấy chạy thử thì Táo, Cam, Chạy không có cộng thêm bưởi vào! thấy vẫn 1, 2,4 đúng ra phải 25, 26, 28 không biết phải không?
1678096581161.png
 
Upvote 0
Đang không hiểu thấy chạy thử thì Táo, Cam, Chạy không có cộng thêm bưởi vào! thấy vẫn 1, 2,4 đúng ra phải 25, 26, 28 không biết phải không?
Bạn chưa đọc qua Wikipedia về phép toán Bitwise, để hiểu được giải thuật trên. Bitwise không phải toán cộng hay trừ mà là dịch chuyển bit, quay bit.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn chưa đọc qua Wikipedia về phép toán Bitwise, để hiểu được giải thuật trên. Bitwise không phải toán cộng hay trừ mà là dịch chuyển bit, quay bit.
bác có update mới phiên bản này chưa bác. Thật sự em ko nghĩ là Excel có thế toàn năng như thế. Tks bác đã nâng tầm excel
 
Upvote 0
Web KT
Back
Top Bottom