Thủ Thuật Access
Làm sao chạy được code cả trong access 32 bit và access 64 bit - Phiên bản có thể in

+- Thủ Thuật Access (http://thuthuataccess.com/forum)
+-- Diễn đàn: Access Nâng Cao (http://thuthuataccess.com/forum/forum-11.html)
+--- Diễn đàn: Thủ thuật VBA (http://thuthuataccess.com/forum/forum-17.html)
+--- Chủ đề: Làm sao chạy được code cả trong access 32 bit và access 64 bit (/thread-10148.html)



Làm sao chạy được code cả trong access 32 bit và access 64 bit - haquocquan - 12-09-17

Có chút việc nhờ các PRO:
Tôi có module dưới đây, đang chạy trong access 32bit. Nay muốn chạy được cả trong 32bit và 64bit thì phải làm thế nào.
Cám ơn nhiều


Mã:
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function MessageBoxW Lib "user32" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Public Function MsgBoxUni(ByVal PromptUni As Variant, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal TitleUni As Variant = vbNullString) As VbMsgBoxResult

'BStrMsg, BStrTitle : La chuoi Unicode
    Dim BStrMsg, BStrTitle
    'Hàm StrConv Chuyen chuoi ve ma Unicode
    BStrMsg = StrConv(PromptUni, vbUnicode)
    BStrTitle = StrConv(TitleUni, vbUnicode)
    
    MsgBoxUni = MessageBoxW(GetActiveWindow, BStrMsg, BStrTitle, Buttons)
End Function



RE: Làm sao chạy được code cả trong access 32 bit và access 64 bit - maidinhdan - 12-09-17

(12-09-17, 05:18 PM)haquocquan Đã viết: Có chút việc nhờ các PRO:
Tôi có module dưới đây, đang chạy trong access 32bit. Nay muốn chạy được cả trong 32bit và 64bit thì phải làm thế nào.
Cám ơn nhiều


Mã:
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function MessageBoxW Lib "user32" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Public Function MsgBoxUni(ByVal PromptUni As Variant, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal TitleUni As Variant = vbNullString) As VbMsgBoxResult

'BStrMsg, BStrTitle : La chuoi Unicode
    Dim BStrMsg, BStrTitle
    'Hàm StrConv Chuyen chuoi ve ma Unicode
    BStrMsg = StrConv(PromptUni, vbUnicode)
    BStrTitle = StrConv(TitleUni, vbUnicode)
    
    MsgBoxUni = MessageBoxW(GetActiveWindow, BStrMsg, BStrTitle, Buttons)
End Function

Anh sửa lại như sau:
Mã PHP:
#If VBA7 Then
    Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Private 
Declare PtrSafe Function MessageBoxW Lib "user32" (ByVal hwnd As LongByVal lpText As StringByVal lpCaption As StringByVal wType As Long) As LongPtr
#Else
    Private Declare Function GetActiveWindow Lib "user32" () As Long
    Private 
Declare Function MessageBoxW Lib "user32" (ByVal hwnd As LongByVal lpText As StringByVal lpCaption As StringByVal wType As Long) As Long
#End If

Public Function MsgBoxUni(ByVal PromptUni As VariantOptional ByVal Buttons As VbMsgBoxStyle vbOKOnlyOptional ByVal TitleUni As Variant vbNullString) As VbMsgBoxResult

'BStrMsg, BStrTitle : La chuoi Unicode
    Dim BStrMsg, BStrTitle
    '
Hàm StrConv Chuyen chuoi ve ma Unicode
    BStrMsg 
StrConv(PromptUnivbUnicode)
    BStrTitle StrConv(TitleUnivbUnicode)
    
    MsgBoxUni 
MessageBoxW(GetActiveWindowBStrMsgBStrTitleButtons)
End Function 

Giải thích:
Lỗi liên quan đến dùng hàm do dùng hàm API, cụ thể là các giá trị truyền vào và đọc hiểu số bit của hệ thông không thống nhất.
Vì dụ:
+ Nếu ta viết trên Office 32 bit(Chỉ chạy trên 32bit):
Mã PHP:
Declare Function GetActiveWindow Lib "user32" () As Long 

+ Nếu ta viết trên Office 64 bit( Chạy trên 64bit nhưng vẫn sử dụng một giá trị trả về 32-bit):
Mã PHP:
Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long 

+ Nếu ta viết trên Office 64 bit( Chạy trên 64bit và sử dụng một giá trị trả về 64-bit):
Mã PHP:
Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr 


Lưu ý:
* Từ khóa PtrSafe khẳng định rằng tuyên bố Khai báo là an toàn để chạy trong các phiên bản 64-bit của Office.
* Long (Khi dùng trên 32bit)
* LongPtr(Khi dùng trên 64bit)

Từ ví dụ này ta có một cú pháp chung cho 332 và 64bit:
Cách 1: Hệ điều hành và office đều là 64bit
Mã PHP:
#If Vba7 Then 
Declare PtrSafe Sub... 
#Else 
Declare Sub... 
#EndIf 

- VBA7 là Version 7 tương ứng office 2010

Cách 2: Hê điều hành và Office không cùng số bit
Mã PHP:
#if Vba7 then 
'  Code is running in the new VBA7 editor 
    #if Win64 then 
    ' 
 Code is running in 64-bit version of Microsoft Office 
    
#else 
    '  Code is running in 32-bit version of Microsoft Office 
    #end if 
#else 
Code is running in VBA version 6 or earlier 
#end if 

Chi tiết về sự thay đổi kiểu giá trị sau từ khóa As (Long(32bit) và LongPtr(64bit))thì xem Link này; https://msdn.microsoft.com/VBA/Language-Reference-VBA/articles/64-bit-visual-basic-for-applications-overview

Kết Luận: Câu thần chú chung khi sử dụng câu lệnh Khai báo trong VBA
Hầu như không cần phải thay đổi mã VBA khi sử dụng ở 64 bit hoặc 32 bit, trừ khi bạn sử dụng câu lệnh Khai báo để gọi API Windows bằng loại dữ liệu 32 bit như long, cho con trỏ và núm điều khiển. Trong hầu hết trường hợp, việc thêm PtrSafe vào Khai báo và thay thế long bằng LongPtr sẽ giúp cho câu lệnh Khai báo tương thích với cả 32 lẫn 64 bit. Tuy nhiên, cách này có thể không khả thi trong một số trường hợp hiếm gặp, khi không có API 64 bit nào để Khai báo. Để biết thêm thông tin về những thay đổi về VBA cần được thực hiện để giúp VBA chạy trên Office 64 bit, xem mục Tổng quan về Visual Basic for Applications 64 bit.