MyTetra Share
Делитесь знаниями!
Access. Переход с 32-х разрядной версии офиса на 64-х разрядную.
16.03.2019
23:43
Раздел: !Закладки - VBA - Access

Access. Переход с 32-х разрядной версии офиса на 64-х разрядную.


(обращений: 1950 с 28.04.2016)


Разделы: Статьи



Описание: Проблемы, связанные с переходом на 64-х битную версию и пути их решения. Пошарился по интернету, по форумам. Попробовал свести всё в одно место. Версия 1.1 от 20.05.2018


Автор: Дмитрий Сонных (AKA Joss)


Добавил на сайт: Профиль пользователяJoss 28.04.2016


Скачать:

Win32API_PtrSafe.rar (105721 байт) (скачиваний: 167 с 28.04.2016)

Пошарился по интернету, по форумам. Попробовал свести всё в одно место.


Access. Переход с 32-х разрядной версии офиса на 64-х разрядную.


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


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


ВНИМАНИЕ! При попытке запустить 32-разрядный код в 64-разрядной версии Access возникнут ошибки времени выполнения. Например, из-за несоответствия версий пользовательского приложения (32-разрядный код) и одного из 64-разрядных поставщиков ACE, установленных с 64-разрядной версией Microsoft Access, может возникнуть ошибка "Поставщик Microsoft.ACE.OLEDB.12.0 не зарегистрирован на локальном компьютере". Чтобы устранить эту проблему, либо обновите пользовательский код до 64-разрядной версии, либо удалите 64-разрядную версию Access и установите 32-разрядную.


Параллельная установка 64-х и 32-х разрядных выпусков Office 2010 не поддерживается. Это относится и к Access.


Перед развертыванием 64-разрядной версии Access определите, подходит ли такой вариант развертывания для конкретной среды. На совместимость с текущим 32-разрядным решением для Access влияет ряд факторов. Например, при использовании баз данных с удаленным исходным кодом (MDE-, ADE- и ACCDE-файлов) либо при использовании VBA-кода с операторами Declare, надстройками COM и элементами ActiveX необходимо приложить определенные усилия, чтобы эти функции заработали с 64-разрядной версией Access. Для устранения этой проблемы также можно установить 32-разрядную версию Access в 32-разрядной версии Windows либо 32-разрядную версию Access (WOW64) в 64-разрядной версии Windows.


Если Вы собираетесь использовать 64-х разрядные базы данных Access, и в будущем ситуация не изменится, самым естественным вариантом для работы с данными будет выбор драйвера ACE DAO, поскольку он предоставляет наиболее полный набор функций. В конце концов, собственные технологии доступа к данным, как правило, позволяют сократить время разработки, упростить код и обеспечить более высокую производительность. Если будут использоваться расширенные возможности работы с наборами данных и подключения к вспомогательным внешним источникам, рассмотрите возможность использования ADO.NET (или ADO) либо OLE DB. Полную поддержку устаревших возможностей, таких как связанные таблицы и сохраненные запросы, а также новых сложных типов данных, появившихся в Access 2007, обеспечивает только драйвер ACE DAO. Драйвер ACE OLE DB обеспечивает ограниченную поддержку сложных данных. Например, для более эффективной поддержки сложного набора данных (для извлечения наборов записей в наборах данных) необходимо задать параметр подключения "JET OLE DB: Support Complex Data". Если этого не сделать, по умолчанию для сложных полей будут возвращаться списки разделенных значений. Технологии ADO.NET, ADO и ACE ODBC всегда возвращают для сложных полей списки разделенных значений.


Выполнение кода VBA, который был написан до выпуска Office 2010 (VBA версии 6 и более ранних версий), на 64-разрядной платформе может приводить к возникновению ошибок, если код не был модифицирован для работы в 64-разрядных версиях Office. Ошибки будут возникать по той причине, что язык VBA версии 6 и более ранних версий неявно ориентирован на 32-разрядные платформы и обычно содержит операторы объявления, которые запускают в действие функции API Microsoft Windows, использующие 32-разрядные типы данных для указателей и дескрипторов. Так как язык VBA версии 6 и более ранних версий не имеет специального типа данных для указателей и дескрипторов, им используется тип данных Long, который является 32-разрядным 4-байтным типом данных, предназначенным для ссылки на указатели и дескрипторы. Указатели и дескрипторы в 64-разрядных средах являются 8-байтными 64-разрядными числами. Эти 64-разрядные числа не могут храниться в 32-разрядных типах данных.


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


Для устранения этой проблемы и обеспечения правильной работы кода VBA как в 32-разрядных, так и в 64-разрядных средах в язык VBA добавлен ряд функциональных возможностей. Три важных добавления: псевдоним типа LongPtr, тип данных LongLong и ключевое слово PtrSafe.


LongPtr — теперь язык VBA включает псевдоним типа переменной: LongPtr. Фактический тип данных, в который разрешается тип LongPtr, зависит от версии пакета Office, в котором он используется: тип LongPtr разрешается в тип Long в 32-разрядных пакетах Office, и тип LongPtr разрешается в тип LongLong в 64-разрядных версиях пакета Office. Используйте тип LongPtr для указателей и дескрипторов.


LongLong — тип данных LongLong — это 64-разрядные целые числа со знаком, которые доступны только в 64-разрядных версиях пакета Office. Используйте тип LongLong для 64-разрядных целых чисел. Для явного присвоения значений типа LongLong (включая тип LongPtr на 64-разрядных платформах) целочисленным типам данных меньшего размера должны использоваться функции преобразования. Неявное преобразование типа LongLong в целочисленные данные меньшего размера не допускается.


PtrSafe — ключевое слово PtrSafe декларирует, что оператор Declare безотказно выполняется в 64-разрядных версиях пакета Office.


Теперь все операторы Declare должны содержать ключевое слово PtrSafe, когда выполняются в 64-х разрядных версиях пакета Office. Для 32-х разрядных версий это не обязательно. Важно понимать, что просто добавление ключевого слова PtrSafe в оператор Declare означает только, что оператор Declare явно ориентирован на 64-разрядные данные, все типы данных в операторе, которые предназначены для хранения 64 разрядов (включая возвращаемые значения и параметры), все еще нуждаются в изменении, чтобы хранить 64-разрядные числа.


Начиная с Access 2010 для программирования стал доступен VBA 7.


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


Операторы Declare, содержащие слово PtrSafe, работают корректно в среде разработки VBA7 как на 32-разрядных, так и на 64 разрядных платформах. Чтобы обеспечить обратную совместимость в VBA 7 и более ранних версиях, используйте следующую структуру:


#If Vba7 Then

Declare PtrSafe Sub...

#Else

Declare Sub...

#EndIf


Примечание. Я писал текст программ в Access 2003, а уже потом отлаживал в Access 2010. В Access 2003 строки с этой переменной подсвечивались красным, но компилятор Access 2003 их спокойно обрабатывал. В Access 2010 наоборот подсвечивались строки без PtrSafe.


Пример не модифицированного унаследованного оператора Declare в языке VBA5/6 версий Access 97/2000/2002/2003/2007


Declare Function GetActiveWindow Lib "user32" () As Long



Пример оператора Declare языка VBA модифицированного для включения спецификатора PtrSafe, но по-прежнему используется 32-разрядное возвращаемое значение в языке VBA7 версий Access 2010/2013/2016


Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr


Пример оператора Declare языка VBA, модифицированный для включения ключевого слова PtrSafe и обновленный для использования 64-разрядного типа данных (LongPtr)


Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr


Итак, для правильной работы кода в 64-разрядных версиях пакета Office необходимо найти и модифицировать все существующие операторы Declare, чтобы они использовали спецификатор PtrSafe. А внутри этих операторов Declare необходимо найти и модифицировать все типы данных, которые ссылаются на дескрипторы или указатели, чтобы использовать псевдоним нового 64-разрядного совместимого типа LongPtr и типы, необходимые для хранения 64-разрядных целых чисел с новым типом данных LongLong. Кроме того, следует обновить все определенные пользователем типы, содержащие указатели или дескрипторы и 64-разрядные целые числа, чтобы использовать 64-разрядные типы данных, и убедиться в правильности присвоений всех переменных, чтобы предотвратить появление ошибок несоответствия типов.


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

Обратите внимание, что если требуется реализовать другую логику, можно использовать константу условной компиляции Win64


Код с её использованием будет выглядеть следующим образом.


#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


Чтобы написать код, работоспособный как в новой, так и в старой версиях Office, можно использовать комбинацию новых условных констант компилятора VBA7 и Win64.


#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

#If Vba7 Then

Declare PtrSafe Sub...

#Else

Declare Sub...

#EndIf




Дли типов данных LongPtr и LongLong не действует неявное преобразование типов, как для остальных типов данных.


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


-----------------------------------------------------------------------------------------

Тип Элемент Описание

-----------------------------------------------------------------------------------------


Квалификатор 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 байта).



P.S. В приложенном файле Win32API_PtrSafe.txt даны декларации API функций для 64-х битной версии. Но не для всех API!. Остальные придётся декларировать самостоятельно. Деятели от MS считают, что пользователи с этим справятся.


[Back]


Текущий рейтинг:

0 из 5 (проголосовало:0).

Здравствуйте!

Для участия в рейтинге необходимо залогиниться на сайт.

Это сделано для того, чтобы более точно производить оценку статей (чтобы одному и тому же человеку было труднее голосовать несколько раз, портя тем самым статистику.

Эта процедура очень быстрая и, надеюсь, Вас не затруднит :).

Все мысли по поводу работы сайта всегда можно высказать на форуме!

Вход на сайт


Обсуждение статьи: [Добавить комментарий] [Подписаться на комментарии к этой теме]

Из опыта перехода. Профиль пользователяJoss [Пометить сообщение как непрочитанное] [Ответить]

Переводил на 64-х битную версию небольшую программу написанную в Access 2000. Без ActivX и API.

Что замечено.

Если у Вас есть ссылка на библиотеку Microsoft DAO 3.6 Object Library , то замените её на Microsoft Office XX.X Access Database Engine Object Library, так как для 64-х разрядной версии не существует соответствующей 64-х разрядной библиотеки Microsoft DAO 3.6 Object Library

27.04.2016 18:56 (последнее изменение - 28.04.2016 10:26) [История изменения сообщения]


Насчет ядра Microsoft JET Профиль пользователяJoss [Пометить сообщение как непрочитанное] [Ответить]

Что насчет ядра Microsoft JET?


До выпуска Access 2007 в Access использовалось ядро Microsoft Joint Engine Technology (JET). Хотя ядро JET обычно рассматривается как компонент Access, оно является отдельным продуктом. С момента выпуска Microsoft Windows 2000 ядро JET было включено в состав операционной системы Windows, после чего распространялось и обновлялось в составе компонентов Microsoft Data Access Components (MDAC). После выпуска Access 2007 ядро JET было признано устаревшим и было исключено из состава MDAC. Вместо этого ядра в Access теперь используется интегрированное и усовершенствованное ядро ACE, разработка которого началась с создания снимка исходного кода JET.


Ядро ACE полностью обратно совместимо с предыдущими версиями JET, что позволяет выполнять чтение и запись данных в MDB-файлы из предыдущих версий Access. Поскольку ядро теперь отдано группе разработчиков Access, другие разработчики могут быть уверены в том, что их решения для Access не только продолжат работать в будущем, но станут быстрее, надежнее и получат поддержку новых возможностей. Например, с выпуском Access 2010 в ядре ACE, в числе прочих усовершенствований, была реализована поддержка 64-разрядной версии и улучшена интеграция с технологиями и веб-службами SharePoint. Корпорация Microsoft обязуется поддерживать Access в качестве платформы разработки.

28.04.2016 10:31


Дополнение Профиль пользователяJoss [Пометить сообщение как непрочитанное] [Ответить]

Учтите, что типы переменных/свойств в рекордсетах могут зависеть от разрядности версии Access. Например свойство RecordsetCount в 32-х разрядной версии имеет тип Long, а в 64-х разрядной - LongLong.

Решить проблему универсальности программы можно при помощи операторов условной компиляции. Пример задания переменной для RecordsetCount


#if Vba7 then

' Code is running in the new VBA7 editor

#if Win64 then

' Code is running in 64-bit version of Microsoft Office

Dim i as LongLong

#else

' Code is running in 32-bit version of Microsoft Office

Dim i as Long

#end if

#else

' Code is running in VBA version 6 or earlier

Dim i as Long

#end if



Или вот так


#if Vba7 then

' Code is running in the new VBA7 editor

Dim i as LongPtr

#else

' Code is running in VBA version 6 or earlier

Dim i as Long

#end if



11.04.2018 12:58 (последнее изменение - 21.05.2018 12:25) [История изменения сообщения]


Немного о совместимость 32- и 64-разрядных версий Office Профиль пользователяJoss [Пометить сообщение как непрочитанное] [Ответить]

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


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

VBA


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 работать как обычно.


Смотри MSDN - https://msdn.microsoft.com/ru-ru/library/office/ee691831(v=office.14).aspx

21.05.2018 12:38

Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования