Совместимость 32- и 64-разрядных версий Office 2010

Сводка. Для пользователей, работающих с данными объемом 2 ГБ и более, теперь доступна 64-разрядная версия Microsoft Office 2010. В этой статье рассмотрена совместимость 32-разрядной и новой 64-разрядной версий, а также старых 32-разрядных приложений Office и решений для них (7 печатных страниц).

Дата последнего изменения: 24 апреля 2015 г.

Применимо к: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | SharePoint Server 2010 | VBA | Visual Basic for Applications 7.0 (VBA 7.0) | Word 2010

В этой статье
Введение в 32- и 64-разрядные версии Microsoft Office 2010
Сравнение 32-разрядных систем с 64-разрядными
Введение в базу кода VBA 7
Совместимость элементов управления ActiveX и надстроек COM
Совместимость интерфейсов API
Использование атрибутов условной компиляции
Вопросы и ответы
Заключение
Дополнительные ресурсы

Опубликовано: март 2010 г.

Автор: корпорация Майкрософт

Содержание

  • Введение в 32- и 64-разрядные версии Microsoft Office 2010

  • Сравнение 32-разрядных систем с 64-разрядными

  • Введение в базу кода VBA 7

  • Совместимость элементов управления ActiveX и надстроек COM

  • Совместимость интерфейсов API

  • Использование атрибутов условной компиляции

  • Вопросы и ответы

  • Заключение

  • Дополнительные ресурсы

Введение в 32- и 64-разрядные версии Microsoft Office 2010

Система Microsoft Office 2010 доступна в 32- и 64-разрядной версии. 64-разрядная версия позволяет работать с гораздо большими объемами данных. Это особенно заметно при работе с большими числами в Microsoft Excel 2010.

С выходом новой 64-разрядной версии Microsoft Office 2010 выпускается новая версия Microsoft Visual Basic для приложений (VBA), известная как Microsoft Visual Basic для приложений 7.0 (VBA 7), которая сможет работать с 32- и 64-разрядными приложениями. Следует отметить, что изменения, описанные в этой статье, применимы только к 64-разрядной версии Microsoft Office 2010. Использование 32-разрядной версии Office 2010 позволяет применять решения, встроенные в предыдущие версии Microsoft Office, без их изменения.

Примечание

При стандартной установке Office 2010 устанавливается 32-разрядная версия, даже на 64-разрядных системах. Следует явно выбрать установку 64-разрядной версии Office 2010.

В VBA 7 следует обновить операторы существующего интерфейса API Windows (операторы Declare) для работы с 64-разрядной версией. Кроме того, следует обновить указатели адреса и дескрипторы окон в типах, определенных пользователем, которые используются в этих операторах. Это описывается более подробно далее в этой статье, как и проблемы совместимости 32- и 64-разрядной версии Office 2010 и возможные решения.

Сравнение 32-разрядных систем с 64-разрядными

Приложения, созданные с помощью 64-разрядной версии Office 2010, могут ссылаться на большие адресные пространства и таким образом использовать больше физической памяти, что снижает затраты на перемещение данных в физическую память и из нее.

Помимо ссылок на определенные места (называемых указателями) в физической памяти, которые приложение использует для хранения данных или программных операторов, адреса можно также использовать для ссылок на идентификаторы окон (называемых дескрипторами). В зависимости от того, используется ли 32-разрядная или 64-разрядная система, определяется размер указателей и дескрипторов (в байтах).

При запуске существующих решений с 64-разрядной версией Office 2010 есть две основных проблем.

  • Собственные 64-разрядные процессы в Office 2010 не могут загружать 32-разрядные двоичные файлы. Это происходит при использовании существующих элементов управления Microsoft ActiveX и надстроек.

  • В VBA ранее не было типа данных указателя, и поэтому разработчики использовали 32-разрядные переменные для хранения указателей и дескрипторов. Теперь при использовании операторов Declare эти переменные усекают 64-разрядные значения, возвращаемые вызовами интерфейса API.

Введение в базу кода VBA 7

VBA 7 — это новая база кода, которая заменяет предыдущую версию VBA. Язык VBA 7 существует как для 32-разрядных, так и 64-разрядных версий Office 2010. Он предоставляет две константы условной компиляции: VBA7 и Win64. Константа VBA7 обеспечивает обратную совместимость кода, проверяя, использует ли приложение VBA 7 или предыдущую версию VBA. Константа Win64 используется для проверки, выполняется ли код как 32-разрядный или 64-разрядный. Использование обеих этих констант компиляции показано далее в этой статье.

За некоторыми исключениями, приведенными далее в этой статье, макросы в документе (в том числе книгах и презентациях), работавшие в 32-разрядной версии приложения, будут работать и при загрузке документа в его 64-разрядной версии.

Совместимость элементов управления ActiveX и надстроек COM

Существующие 32-разрядные элементы управления ActiveX, как от корпорации Майкрософт, так и от других производителей, несовместимые с 64-разрядной версией Office 2010. Для элементов управления ActiveX и COM-объектов существует три возможных решения.

  • Если есть исходный код, можно самому создать 64-разрядную версию.

  • Можно обратиться к производителю для получения обновленной версии.

  • Можно выполнить поиск альтернативного решения.

В 64-разрядной версии Office 2010 невозможно загрузить 32-разрядные двоичные файлы, а значит, и стандартные элементы управления MSComCtl (TabStrip, Toolbar, StatusBar, ProgressBar, TreeView, ListViews, ImageList, Slider, ImageComboBox) и элементы управления MSComCt2 (Animation, UpDown, MonthView, DateTimePicker, FlatScrollBar). Эти элементы управления устанавливались с предыдущими версиями Microsoft Office и устанавливаются с 32-разрядной версией Office 2010. Следует найти альтернативу существующим решениям VBA для Microsoft Office, которые используют эти элементы управления при переносе кода в 64-разрядную версию Office 2010. В 64-разрядной версии Office 2010 не предусмотрены 64-разрядные версии стандартных элементов управления.

Совместимость интерфейсов API

Сочетание VBA и библиотек типов предоставляет множество возможностей для создания приложений Microsoft Office. Однако иногда следует взаимодействовать напрямую с операционной системой и другими компонентами компьютера, например, при управлении памятью или процессами, при работе с интерфейсом пользователя (окнами и элементами управления) или при изменении реестра Windows. В этих случаях лучше всего использовать внешние функции, встроенные в библиотеки DLL. В VBA это возможно с помощью вызовов API с использованием операторов Declare.

Примечание

Майкрософт предоставляет файл Win32API.txt, который содержит 1500 операторов Declare и средство для копирования и вставки оператора Declare в код. Но эти операторы предназначены для 32-разрядных систем, и их нужно преобразовать в 64-разрядные операторы, используя сведения, представленные далее в этой статье. Компиляция существующих операторов Declare в 64-разрядной версии VBA будет невозможна, пока они не будут помечены как безопасные для нее с помощью атрибута PtrSafe. Примеры таких преобразований можно найти на веб-сайте специалиста MVP по Excel Яна Карела Питерсе (Jan Karel Pieterse) по адресу http://www.jkp-ads.com/articles/apideclarations.asp.

В статье Руководство пользователя для инспектора совместимости кода Microsoft Office описано полезное средство для проверки использования (в случае необходимости) атрибута PtrSafe и соответствующего типа возвращаемого значения в синтаксисе операторов Declare для интерфейса API.

Операторы Declare похожи на один из следующих примеров в зависимости от того, вызывается ли подпрограмма (без возвращаемого значения) или функция (с возвращаемым значением).

	Public/Private Declare Sub SubName Lib "LibName" Alias "AliasName" (argument list)
    Public/Private Declare Function FunctionName Lib "Libname" alias "aliasname" (argument list) As Type

Функция SubName или FunctionName заменяется фактическим именем процедуры в DLL-файле и представляет имя, которое используется при вызове процедуры в коде VBA. Можно также указать аргумент AliasName для имени процедуры, если это необходимо. Имя DLL-файла, который содержит вызываемую процедуру, следует за ключевым словом Lib. И, наконец, список аргументов содержит параметры и типы данных, которые следует передать процедуре.

Следующий оператор Declare открывает подраздел реестра Windows и заменяет его значение.

    Declare Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long

Запись Windows.h (дескриптор окна) для функции RegOpenKeyA выглядит следующим образом.

    LONG RegOpenKeyA ( HKEY hKey, LPCSTR lpSubKey, HKEY *phkResult );

В Microsoft Visual C и Microsoft Visual C++ предыдущий пример компилируется без ошибок для 32-разрядной и 64-разрядной версии. Это происходит потому, что HKEY определен как указатель, размер которого отражает размер памяти платформы, в которой компилируется код.

В предыдущих версиях VBA не было определенного типа данных указателя, поэтому использовался тип Long. Так как тип данных Long всегда 32-разрядный, при использовании в системе с 64-разрядной памятью старшие 32 разряда могут усекаться, или запись может происходить в другие адреса памяти. Обе этих ситуации могут привести к непредвиденному поведению или сбою системы.

Чтобы устранить эту проблему, в VBA теперь есть настоящий тип данных указателя: LongPtr. Этот новый тип данных позволяет записывать оператор Declare правильно:

    Declare PtrSafe Function RegOpenKeyA Lib "advapire32.dll" (ByVal hKey as LongPtr, ByVal lpSubKey As String, phkResult As LongPtr) As Long

Этот тип данных и новый атрибут PtrSafe позволяют использовать оператор Declare в 32- и 64-разрядных системах. Атрибут PtrSafe показывает компилятору VBA, что оператор Declare предназначен для 64-разрядной версии Office 2010. Без этого атрибута при использовании оператора Declare в 64-разрядной системе возникнет ошибка компиляции. Обратите внимание, что атрибут PtrSafe в 32-разрядной версии Office 2010 необязателен. Это позволяет существующим операторам Declare работать как обычно.

В следующей таблице описывается новый квалификатор и тип данных, а также другой тип данных, два оператора преобразования и три функции.

Тип

Элемент

Описание

Квалификатор

PtrSafe

Обозначает, что оператор Declare совместим с 64-разрядными системами. Этот атрибут обязателен для 64-разрядных систем.

Тип данных

LongPtr

Тип данных переменной, состоящей из 4 байт в 32-разрядных версиях и из 8 байт в 64-разрядных версиях Office 2010. Это рекомендуемый способ объявления указателя или дескриптора в новом коде, а также в старом коде, если он будет выполняться в 64-разрядной версии Office 2010. Эта возможность поддерживается только в среде выполнения VBA 7 в 32- и 64-разрядных системах. Обратите внимание, что этой переменной можно назначать числовые значения, но не числовые типы.

Тип данных

LongLong

Это 8-байтовый тип данных, доступный только в 64-разрядных версиях Office 2010. Этому типу можно назначать числовые значения, но не числовые типы (чтобы избежать усечения).

Оператор преобразования

CLngPtr

Преобразует простое выражение в тип данных LongPtr.

Оператор преобразования

CLngLng

Преобразует простое выражение в тип данных LongLong.

Функция

VarPtr

Преобразователь вариантов. Возвращает тип LongPtr для 64-разрядных версий и тип Long для 32-разрядных версий (4 байта).

Функция

ObjPtr

Преобразователь объектов. Возвращает тип LongPtr для 64-разрядных версий и тип Long для 32-разрядных версий (4 байта).

Функция

StrPtr

Преобразователь строк. Возвращает тип LongPtr для 64-разрядных версий и тип Long для 32-разрядных версий (4 байта).

В следующем примере показано, как использовать эти элементы в операторе Declare.

    Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long

Предполагается, что операторы Declare без атрибута PtrSafe не совместимы с 64-разрядной версией Office 2010.

Как было указано ранее, есть две новые константы для условной компиляции: VBA7 и Win64. Для обеспечения обратной совместимости с предыдущими версиями Microsoft Office используется константа VBA7 (это более распространено), чтобы не допустить использование 64-разрядного кода в более ранних версиях Microsoft Office. Если код для 32- версии отличается от такого же кода для 64-разрядной версии (например, для вызова математического интерфейса API в случае 64-разрядной версии используется LongLong, а в случае 32-разрядной версии — Long), нужно использовать константу Win64. В следующем примере кода показано использование этих двух констант.

    #if Win64 then
       Declare PtrSafe Function MyMathFunc Lib "User32" (ByVal N As LongLong) As LongLong
    #else
       Declare Function MyMathFunc Lib "User32" (ByVal N As Long) As Long
    #end if
    #if VBA7 then
       Declare PtrSafe Sub MessageBeep Lib "User32" (ByVal N AS Long)
    #else
       Declare Sub MessageBeep Lib "User32" (ByVal N AS Long)
    #end if

Подводя итоги, можно сказать, что при написании 64-разрядного кода, который будет использоваться в предыдущих версиях Microsoft Office, следует применять константу условной компиляции VBA7. Однако при написании 32-разрядного кода в Office 2010 он работает как и в предыдущих версиях Microsoft Office без применения константы компиляции. Если требуется обеспечить использование 32-разрядных операторов для 32-разрядных версий и 64-разрядных операторов для 64-разрядных версий, лучше всего использовать константу условной компиляции Win64.

Использование атрибутов условной компиляции

Далее представлен пример старого кода VBA, который нужно обновить. Имейте в виду, что типы данных в старом коде изменяются для использования типа LongPtr, так как они ссылаются на дескрипторы и указатели.

Старый код VBA

    Declare Function SHBrowseForFolder Lib "shell32.dll" _
      Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
      
    Public Type BROWSEINFO
      hOwner As Long
      pidlRoot As Long
      pszDisplayName As String
      lpszTitle As String
      ulFlags As Long
      lpfn As Long
      lParam As Long
      iImage As Long
    End Type

Новый код VBA

    #if VBA7 then    ' VBA7 
    Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" _
      Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
    
    Public Type BROWSEINFO
      hOwner As LongPtr
      pidlRoot As Long
      pszDisplayName As String
      lpszTitle As String
      ulFlags As Long
      lpfn As LongPtr
      lParam As LongPtr
      iImage As Long
    End Type
     
    #else    ' Downlevel when using previous version of VBA7
    
    Declare Function SHBrowseForFolder Lib "shell32.dll" _
      Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
    
    Public Type BROWSEINFO
      hOwner As Long
      pidlRoot As Long
      pszDisplayName As String
      lpszTitle As String
      ulFlags As Long
      lpfn As Long
      lParam As Long
      iImage As Long
    End Type
     
    #end if
    Sub TestSHBrowseForFolder ()
        Dim bInfo As BROWSEINFO
        Dim pidList As Long
    
        bInfo.pidlRoot = 0&
        bInfo.ulFlags = &H1
        pidList = SHBrowseForFolder(bInfo)
    End Sub

Вопросы и ответы

Ниже приведены вопросы и ответы по 32- и 64-разрядной версиям Microsoft Office.

  • Когда следует использовать 64-разрядную версию Microsoft Office?
    В основном это зависит от того, какое ведущее приложение используется (Excel, Word и т. д.). Например, приложение Excel в 64-разрядной версии Microsoft Office может обрабатывать листы гораздо больших размеров.

  • Можно ли устанавливать 64- и 32-разрядную версии Microsoft Office одновременно?
    Нет.

  • Когда следует преобразовывать параметры Long в LongPtr?
    Сведения функциях, которые нужно вызвать, можно найти в документации по API Windows на сайте MSDN. Маркеры и указатели должны быть преобразованы в параметр LongPtr. Например, в документации по RegOpenKeyA указана такая подпись:

    LONG WINAPI RegOpenKeyEx(
      __in        HKEY hKey,
      __in_opt    LPCTSTR lpSubKey,
      __reserved  DWORD ulOptions,
      __in        REGSAM samDesired,
      __out       PHKEY phkResult
    );
    

    Определение параметров:

    Параметр

    Описание

    hKey [in]

    Маркер для открытия раздела реестра.

    lpSubKey [in, optional]

    Название открываемого подраздела реестра.

    ulOptions

    Этот параметр зарезервирован и должен быть равен нулю.

    samDesired [in]

    Маска, задающая необходимые права доступа к разделу.

    phkResult [out]

    Указатель на переменную, получающую маркер к открытому разделу.

    В документе Win32API_PtrSafe.txt оператор Declare определяется так:

    Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As LongPtr, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As LongPtr) As Long
    
  • Следует ли преобразовывать указатели и маркеры в структуры?
    Да. См. сведения о типе MSG в файле Win32API_PtrSafe.txt:

    Type MSG
        hwnd As LongPtr
        message As Long
        wParam As LongPtr
        lParam As LongPtr
        time As Long
        pt As POINTAPI
    End TypeF
    
  • Когда следует использовать функции strptr, varpt и objptr?
    Эти функции используются для получения указателей на строки, переменные и объекты соответственно. В 64-разрядной версии Microsoft Office эти функции будут возвращать 64-разрядный параметр LongPtr, который может быть передан операторам Declare. Использование этих функций осталось таким же, как и в предыдущих версиях VBA. Единственное различие состоит только в том, что теперь они возвращают параметр LongPtr.

Заключение

Добавление 64-разрядной версии Office 2010 позволяет перемещать большие объемы данных и повышать производительность. При написании 32-разрядного кода можно использовать 64-разрядную версию Microsoft Office без каких-либо изменений. Но при написании 64-разрядного кода следует убедиться, что код содержит определенные ключевые слова и константы условной компиляции, чтобы обеспечить его обратную совместимость с предыдущими версиями Microsoft Office и выполнение правильного кода при совмещении 32- и 64-разрядных кодов.

Дополнительные ресурсы

Дополнительные сведения об операторах Declare см. в следующих источниках.