Предполагается, что операторы Declare без атрибута PtrSafe не совместимы с 64-разрядной версией Office 2010-2013. И правильный код для работы на х-32 и х-64 следующий:
Код
#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
Johny, со своим посредственным знанием сего языка, просмотрел... Некоторые моменты знакомы. Но в общем то, я использую VBA в основном в Excel (в т.ч. и выше выложенный код). В Access редко. То что разная адресация памяти, Data type - LongLong, несовместимость элементов управления ActiveX и COM-объектов, вопросы о совместимости интерфейса API - это понятно. Кроме возможных проблем к компиляцией (?будут ли), не понял в чем принципиальная разница использования кода для х32 и х34. этого
Код
#if VBA7 then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#end if
от этого
Код
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Johny, дело в том, что как раз "от этого" работает и на х32 и на х64, в excel2010 и в Excel2013. По крайней мере у меня В связи с чем и вопрос нужен ли If.
Сорри... Да, в 32-битно PtrSafe просто проигнорируется. А вот если вы запилите в x64 Офисе без PtrSafe, то будет ошибка. Но вопрос - зачем тогда делать проверку, если в x86 Офисе не будет ошибки? Да потому что вы не сможете использовать LongPtr и так далее в 32-битном Офисе! Поэтому и разграничения.
Здесь все интереснее Насколько я понял для х64 добавился тип LongLong. И для работы и на х32 и на х64 был введен тип LongPtr (который в зависимости от разрядности будет или LongLong или Long). НО! в чём "интереснее" -я использую Long и для х32 и для х64 (2013). Работает. Вопрос можно ли использовать тип данных Long для Excel х64 (2010-2013)? и забыть про LongLong если не нужны большие целые числа. Возможно ответ в следующем: "Операторы Declare с ключевым словом PtrSafe представляют собой рекомендованный синтаксис. Операторы Declare, содержащие слово PtrSafe, работают корректно в среде разработки VBA7 как на 32-разрядных, так и на 64 разрядных платформах" https://msdn.microsoft.com/ru-ru/library/office/gg264421.aspx
т.е. VBA6 и более ранние (до 2010 офиса) возможно работать с PtrSafe не будут? Не могу проверить эту теорию, нет более ранних версий офиса
bedvit написал: VBA6 и более ранние (до 2010 офиса) возможно работать с PtrSafe не будут?
не возможно, а не будут. И об этом официально написано на сайте Майкрософт. Поэтому и появились все эти разграничения. PtrSafe и PtrLong появился в VBA7 вместе с 2010 офисом. Он отвечает(если коротко) за передачу в функцию API нужной адресации в зависимости от разрядности - Long или LongLong.
Следовательно ответом на Ваш первый вопрос это и является: всплывет это там, где будет офис ниже 2010.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
32-битный Эксель может максимум использовать 4 GB памяти, которую ему даёт ОС, а 64-битный - теоретически - 2^64 байт. Практически же, конечно, такого нет. Здесь, например, сказано, что Windows 7 Professional может использовать до 192 GB.
В теории да, Excel x64 использует всю оперативную память которая стоит на ПК. А Excel x32, поправлю Johny - только 2Гб. На практике могу это подтвердить. Это была причина №1 перейти на х64. Некоторые отчеты, которые выдавали сообщение о нехватке памяти или просто висли, теперь работают без проблем. В отличии от Access, обсуждаемый в соседней теме. Из минусов - две версии не поставишь, только х32 или х64, и соответствующие проблемы с совместимостью. Но на самом деле они не заметны. Была инфо, что двоичный формат .xlsb при сохранении в одной версии не будет открываться в другой. Ан нет, работает. Кроме Vba ничего не пришлось менять при переходе. Зато нет проблем с размером данных + формат .xlsb (мой любимый )
bedvit написал: А Excel x32 (поправлю Johny) только 2Гб.
4 GB. Это объём, который даёт операционка любой программе (мы говорим о x86). Это виртуальная память. И операционка управляет соответствием между этой виртуальной памятью и физической. Прежде чем править, прочитайте соответствующую литературу или предоставьте доказательство вашей правоты.
https://msdn.microsoft.com/ru-ru/library/office/ff726673.aspx Достаточный объем памяти 32-разрядная версия Excel поддерживает до 2 ГБ ОЗУ. Тем не менее, компьютер, на котором работает приложение Excel, также потребляет определенный объем ресурсов памяти. Соответственно, если на компьютере установлено ровно 2 ГБ ОЗУ, приложение Excel не сможет полностью использовать допустимый объем памяти в 2 ГБ, поскольку часть ресурсов будет зарезервирована для операционной системы и других выполняемых программ. Для оптимальной производительности приложения Excel на 32-разрядном компьютере рекомендуется установить не менее 3 ГБ ОЗУ.
В 64-разрядной версии Excel ограничение в 2 ГБ ОЗУ отсутствует. Дополнительные сведения см. в разделе "Крупные наборы данных и 64-разрядная версия Excel" статьи Производительность в Excel 2010: улучшения производительности и ограничений.
Johny написал: который даёт операционка любой программе (мы говорим о x86)
ну это важное замечание, вообще-то. И вроде как не говорили об x86. Excel x64 на x86 - здесь максимум оперативка выделит 2 (или 3?) Гб памяти, Excel x64 на x64, Excel x32 на x64 - 4 и более Гб. Так?
Exsel х32 может использовать только 2Гб, независимо от операционки, да же на winx64 (и памяти, например, 8Гб), х64 максимум установленной оперативки (естественно которую "видит" операционка).
The_Prist, уместно ли будет (верно ли) использовать Long в коде на х64? не приведет ли это к некорректной адресации к функциям API? Если уместно, выходит единственный недостаток - это невозможность использования на более ранних версиях чем 2010 Office (ну нет желания переписывать через If...)
bedvit написал: (верно ли) использовать Long в коде на х64?
пока Дмитрий не ответил: я так понимаю, зависит от типа того параметра, который мы используем при объявлении библиотеки. Некоторые параметры, по идее, могут использовать Long в обоих случаях (на 32 и 64), а некоторые - нет. Насколько понимаю? LongPtr для указателей и дескрипторов (типа HWND ??? и т.п.) вот тут про оба варианта весьма подробно https://msdn.microsoft.com/ru-ru/library/office/Gg264421.aspx
Да, все верно. Есть функции, которые принимают тип Long и в 32 и в 64-битных версиях. Но если в 64 функция принимает LongLong, то в 32 она сможет только Long. И если в 64 объявить как Long или пытаться передавать параметр типа Long - в лучшем случае функция вернет неверный результат. В худшем - Excel просто вывалится в ошибку и попросится закрыться. Поэтому как ни крути - но если собрались использовать только на 2010 и выше имеет смысл все с Ptr использовать:
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
И, в таком случае все переменные и константы, которые будут использованы для работы с функцией API, лучше объявить As Variant. Так 100% избежите ошибки приведения типов и вылета Excel.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...