Chương 3: Để sử dụng Win API từ VBA

Yukino Ichikawa

Thành viên
3.8 Các điểm chính để sử dụng Win API
(tiếp theo)

Point5: Tính toán bit
Trong giá trị trả về của hàm API có trường hợp nó mang ý nghĩa là bit đặc biệt mà không phải là byte. Điều này cần có kỹ thuật để tính toán bit và chúng ta sẽ bàn cụ thể hơn khi xem xét ví dụ về hàm GetVersionEx ở các chương sau.

Point6: Dịch chuyển bit
Đơn vị để lưu trữ dữ liệu trên máy tính được biết tới là bit. Và do đó đi kèm với nó chúng ta sẽ có thủ pháp dịch chuyển bit. Ví dụ số 8 trong hệ cơ số 10 khi biểu diễn dưới dạng nhị phân sẽ có dạng như sau: 00001000.
Bạn cần đăng nhập để thấy hình ảnh

Bây giờ chúng ta thử dich chuyển một bit sang bên phải. Khi đó bit ngoài cùng bên trái sẽ được lấp đầy bởi 0.
Kết quả là chúng ta sẽ được: 00000100 tức là 4 trong hệ cơ số 10.
Bạn cần đăng nhập để thấy hình ảnh

Nếu như 8 trong hệ cơ số 10 mà dịch chuyển 1 bit sang trái thì ta sẽ có số: 00010000 tức là 16 trong hệ cơ số 10.
Bạn cần đăng nhập để thấy hình ảnh

Tóm lại, nếu dịch chuyển sang phải n bit ta sẽ có: số = số / 2^n.
Ngược lại, nếu dịch chuyển sang trái n bit ta sẽ có: số = số * 2^n.

Trong ngôn ngữ C ta có toán tử dịch chuyển bit là << và >> . Thế nhưng chúng ta lại không có phép dịch chuyển bit trong VBA. Tuy nhiên khi nắm được cách nghĩ, chúng ta có thể thực hiện tính toán bit như ở trên tôi đã nêu. Thế nhưng khi nào thì cần tính toán dịch chuyển bit, tôi nghĩ đó là điều khó. Ở các chương sau, chúng ta sẽ gặp một ví dụ về tính toán bit khi nói tới hàm GetDiskFreeSpaceEx.
 

vanthanhVBA

Thành viên
3.8 Các điểm chính để sử dụng Win API
(tiếp theo)

Point7: Xử lý lỗi của Win API
Hầu hết hàm API khi thất bại thì mã lỗi sẽ được thiết định qua hàm GetLastError. Thế nhưng từ VBA dù có gọi hàm GetLastError thì cũng không thể thu được thông tin lỗi. Thay vào đó, bằng VBA, chúng ta có thể thu được thông tin lỗi của API thông qua thuộc tính LastDllError của Err Object.

Note: Trong Win API, khi một hàm thành công thì mã lỗi cũng có thể được thiết định.​

Memo 1: Có nên khai báo kiểu giá trị của hằng số là Long?​
Ở phần cuối, hãy cho phép tôi được nói chuyện về trị số 32bit.​
Trong thế giới Win32 API, để tránh hiện tượng tràn số, hầu hết các trường hợp thì trị số thường được yêu cầu là kiểu Long. Vì lý do đó, khai báo hằng số sẽ theo như dưới đây:​
Mã:
Const PROCESS_QUERY_INFORMATION = &H400&
Trong code trên chúng ta để ý ở cuối giá trị hằng số, ta viết thêm dấu (&), điều đó có nghĩa là ta đang định nghĩa trị số đó thuộc về kiểu Lonng. Đó chính là lý do để không dẫn tới phát sinh vấn đề cho dù ta có chèn hằng số [PROCESS_QUERY_INFORMATION] vào tham số của hàm API mà ở đó nó yêu cầu kiểu giá trị là Long. Tuy nhiên, nếu bây giờ ta viết như sau:​
Mã:
Const PROCESS_QUERY_INFORMATION = &H400
Trong trường hợp này, giá trị của hằng số PROCESS_QUERY_INFORMATION vẫn được hiểu là 400 trong hệ 16, tức là 1024 trong hệ cơ số 10. Thế nhưng kiểu giá trị lại là Integer. Nếu hàm API có tham số (đối số) yêu cầu là kiểu Long, ta truyền hằng số này vào thì vẫn không phát sinh vấn đề. Vậy thì ta cũng chẳng cần phải ý thức là nên viết đầy đủ dấu [&] vào phía cuối giá trị, đằng nào thì cũng có phát sinh lỗi đâu nhỉ.​
Tuy nhiên, ở đây để làm rõ kiểu Long cho nên chúng ta nên viết rõ ràng dấu [&] vào cuối trị số.​
Hãy xem lại chủ đề giới thiệu về . Tôi sẽ dùng kiến thức đó để làm rõ với các bạn nội dung này nhé:​
Ví dụ 1:
Const PROCESS_QUERY_INFORMATION = &H400&
Sub test()
    MsgBox VarType(PROCESS_QUERY_INFORMATION)
End Sub
Kết quả ta được là 3, tức là kiểu Long. Nhưng bây giờ tôi sửa code trên thành:​
Ví dụ 2:
Const PROCESS_QUERY_INFORMATION = &H400
Sub test2()
    MsgBox VarType(PROCESS_QUERY_INFORMATION)
End Sub
Kết quả ta thu được là 2, tức là kiểu Integer.​
Memo 2: Hàm chuyển đổi hệ cơ số 10 thành hệ cơ số 2.​
Trong excel đã có các hàm WorkSheetFunction làm được điều này, chuyển hệ cơ số 10 sang hệ cơ số 2. Hoặc chuyển từ cơ số 2 sang hệ cơ số 16... Ở đây tôi xin giới thiệu một hàm tự tạo của tôi. Các bạn hãy đọc code và thử tự lý giải nhé.​
Mã:
Function IsBin(Dec As Long) As String
    Dim i As Long, soluongbit As Long, myBin As String
    'Neu vuot qua pham vi cua Log thi ket thuc
    If Dec < 0 Or Dec >= 2 ^ 32 Then Exit Function
    'Neu trong he co so 10 la 0 thi he nhi phan cung la 0
    If Dec = 0 Then
        IsBin = 0
        Exit Function
    End If
    'Tinh so luong bit duoc su dung
    For i = 0 To 31 Step 1
        If Dec < 2 ^ i Then
            soluongbit = i - 1
            Exit For
        End If
    Next i
    'Xu ly tuan tu ke tu bit dau tien ben trai lui ve ben phai
    For i = soluongbit To 0 Step -1
        myBin = myBin & CStr((Dec / (2 ^ i)) Mod 2)
    Next i
    IsBin = myBin
   
End Function
 
Top