• Làm sao chạy được code cả trong access 32 bit và access 64 bit
  • Làm sao chạy được code cả trong access 32 bit và access 64 bit

    haquocquan > 12-09-17, 05:18 PM

    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, 11:15 PM

    (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-...s-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.