Sửa lỗi VBA 'Must be Updated for Use on 64-bit Systems'

intermediate📊 Microsoft Excel2026-07-18| Microsoft Excel 2010, 2013, 2016, 2019 và Microsoft 365 (phiên bản 64-bit) trên Windows.

Error Message

Compile error: The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then
#vba#excel#64-bit#loi-bien-dich#khai-bao-api

Vấn đề

Có thể bạn đã gặp lỗi này sau khi nâng cấp phần cứng hoặc chuyển sang Microsoft 365. Lỗi xảy ra do Office 64-bit xử lý địa chỉ bộ nhớ khác với các phiên bản 32-bit cũ hơn. Trong khi các hệ thống 32-bit sử dụng con trỏ (pointer) 4 byte, các hệ thống 64-bit sử dụng con trỏ 8 byte.

Mã VBA cũ của bạn chứa các câu lệnh Declare được thiết kế để gọi các hàm từ Windows DLLs. Vì các câu lệnh cũ này không được xây dựng cho việc đánh địa chỉ bộ nhớ 64-bit, trình biên dịch VBA sẽ chặn chúng để ngăn chặn lỗi hỏng bộ nhớ hoặc làm Excel bị treo hoàn toàn. Thực tế là mã của bạn đang cố gắng đưa một địa chỉ 8 byte vào một "ngăn chứa" 4 byte.

Quy trình gỡ lỗi

Khi lỗi xảy ra, trình soạn thảo VBA thường làm nổi bật một dòng cụ thể bắt đầu bằng Declare. Dòng này đang cố gắng giao tiếp với một Windows API, chẳng hạn như user32.dll hoặc kernel32.dll.

Để khắc phục điều này, trình biên dịch 64-bit tìm kiếm hai sửa đổi cụ thể:

  • Từ khóa PtrSafe: Điều này thông báo cho VBA rằng: "Tôi đã kiểm tra mã này và nó an toàn để chạy trong môi trường 64-bit."
  • Kiểu dữ liệu LongPtr: Đây là một kiểu dữ liệu động. Nó tự động điều chỉnh thành 4 byte trên Office 32-bit và 8 byte trên Office 64-bit.

Giải pháp: Cập nhật mã của bạn

1. Cách sửa nhanh (Chỉ dành cho 64-bit)

Nếu nhóm của bạn chỉ sử dụng Office 64-bit, bạn có thể cập nhật cú pháp trực tiếp. Chỉ cần chèn PtrSafe sau từ khóa Declare.

Mã 32-bit cũ:

Declare Function GetTickCount Lib "kernel32" () As Long

Mã 64-bit đã cập nhật:

Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long

2. Cách sửa triệt để (Tương thích đa nền tảng)

Trong hầu hết các văn phòng, một số người dùng có thể vẫn đang sử dụng các bản cài đặt cũ hơn. Bạn có thể sử dụng biên dịch có điều kiện (conditional compilation) để giúp macro của mình hoạt động với tất cả mọi người. Cách này sử dụng hằng số #If VBA7, vốn được giới thiệu từ Office 2010 để xử lý chính xác những thay đổi về kiến trúc này.

#If VBA7 Then
    ' Phần này chạy trên Office 2010 và mới hơn (32-bit và 64-bit)
    Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
    Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else
    ' Phần này chạy trên Office 2007 và cũ hơn
    Declare Function GetTickCount Lib "kernel32" () As Long
    Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If

3. Xác định các con trỏ và định danh

Việc thêm PtrSafe mới chỉ là một nửa chặng đường. Bạn cũng phải thay đổi Long thành LongPtr cho bất kỳ biến nào chứa địa chỉ bộ nhớ hoặc một "handle" (định danh). Nếu bạn bỏ sót những thứ này, Excel có thể bị treo ngay khi hàm được gọi.

Hãy tìm các tham số phổ biến sau trong các lệnh gọi API của bạn:

  • hWnd: Định danh cửa sổ (Window handles).
  • hDC: Định danh ngữ cảnh thiết bị (Device context handles).
  • lpv hoặc lp: Bất kỳ biến nào có tiền tố là "lp" (Long Pointer).
  • lParam và wParam: Các tham số thông điệp.

Dưới đây là giao diện của một hàm hẹn giờ phức tạp sau khi được cập nhật:

#If VBA7 Then
    Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
#Else
    Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
#End If

Các bước xác minh

Sau khi cập nhật mã, đừng chỉ hy vọng nó sẽ hoạt động. Hãy làm theo các bước sau để xác minh bản sửa lỗi:

  • Mở VBA Editor và vào Debug > Compile VBAProject. Nếu nó biên dịch mà không hiện thông báo lỗi, cú pháp của bạn đã hợp lệ.
  • Kiểm tra macro. Nếu bạn thấy lỗi "Type Mismatch", có khả năng bạn đã chuyển đổi một số tiêu chuẩn (như biến đếm) sang LongPtr trong khi lẽ ra nó phải giữ nguyên là Long.
  • Nếu có thể, hãy mở tệp trên máy tính 32-bit cũ. Điều này đảm bảo logic #If VBA7 của bạn không gây lỗi cho những người dùng khác.

Những điểm chính cần lưu ý

  • Long so với LongPtr: Long luôn là 32-bit. LongPtr là kiểu dữ liệu "thông minh"—nó sẽ tăng lên 64-bit khi cần thiết. Hãy sử dụng LongPtr cho bất cứ thứ gì liên quan đến địa chỉ bộ nhớ.
  • VBA7 so với Win64: Sử dụng #If VBA7 để kiểm tra các phiên bản Office hiện đại. Chỉ sử dụng #If Win64 nếu bạn cần viết mã dành riêng cho môi trường 64-bit.
  • Kiểm tra tài liệu: Khi nghi ngờ, hãy tìm kiếm hàm đó trên tài liệu Win32 API của Microsoft. Nếu một tham số được liệt kê là HANDLE hoặc PTR, hãy sử dụng LongPtr.

Related Error Notes