** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Tus Funciones Favoritas & Aportaciones & Artí­culos
  Mensajes nuevos Mensajes nuevos RSS - Compatibilidad 64 bits VBA
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoCompatibilidad 64 bits VBA

 Responder Responder Página  12>
Autor
Mensaje
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Tema: Compatibilidad 64 bits VBA
    Enviado: 11/Agosto/2016 a las 09:38
En su día me leí este articulo de Microsoft:

https://msdn.microsoft.com/es-es/library/office/ee691831(v=office.14).aspx

ENLACE  

Y sinceramente no termino de aclararme.
Dice el artículo a modo de resumen:

En resumen, si escribe un código de 64 bits y pretende usarlo en versiones anteriores de Microsoft Office, se recomienda usar la constante de compilación condicional VBA7. Sin embargo, si escribe código de 32 bits en Office 2010, ese código funciona como en versiones anteriores de Microsoft Office sin necesidad de usar la constante de compilación. Si desea asegurarse de que está usando instrucciones de 32 bits para versiones de 32 bits e instrucciones de 64 bits para versiones de 64 bits, la mejor opción es usar la constante de compilación condicional Win64.

Yo expongo mi caso real.
Hasta hace unos días seguía manejando la versión Access 2003 (Sí, ya lo sé, ya me vale la bobada) pues hace años que no escribo código y no he tenido la necesidad de variar ningún programa que tengo por ahí operativo.
Hace unos días me grabñe por fin la version Access 2010.
Tengo un programa familiar hecho en A2003.
He creado una base de datos vacía de A2010 y he importado todos los objetos (Muchos formularios, modulos, macros...de todo) a la nueva base  ACCDB

El codigo contiene declaraciones de API etc etc.

Mi pregunta es...si yo creo una ACCDE... ¿Me aseguro que correrá perfectamente sin cambiar una linea de codigo en sistemas con Access de 64 Bits? ¿Y en WIndows (Ahora la maoría) de 64 bits tambien?

Es que en el resumen del articulo, me confunde lo de "
si escribe un código de 64 bits ".
¿Yo como puedo saber si estoy escribiendo codigo de 64 a de 32 bits?.
Yo me he limitado a importar los objetos y codigo de una base de 2003 a una ACCDB de 2010 y luego convertirla en ACCDE.

Espero vuestras respuestas.

P.D
Yo conocía esas compilaciones condicionales, de hecho había respondido a alguna pregunta presentando este enlace, pero reconozco que no termino de entenderlo.

Expulsado de la cárcel por robar los barrotes
Arriba
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 10:12
Aclaro un poco más.
Con esa ACCDE lo he probado en mi ordenador: Funciona (Tengo WIndows XP 32 Bits Office 32 Bits)
La he probado en el portátil de la parienta (Tambien XP de 32) Access 2010 de 32 bits.Funciona
La ha probado mi amigo Iñaki Hualde: Windows 10 de 64 y Access 2010 de 32 (Funciona)
La he probado en el ordenador de la tienda, Windows 10 de 64, Access 2010 64 y casca.

Ya os diré el error, ya que lo he probado vía on line con el RealVNC y no quería entrener a la administrativa que estaba trabajando con el ordenador. EL domingo lo pruebo en vivo y en directo.

Por eso, me ha desconcertado el tema... y supongo que el "casque" venga de correr bajo un Office de 64 bists y no precisamente bajo un Windows de 64 bits...

Y una cuestión relacionada....una vez grabada una versión de Office...¿Como sabemos, o donde pone o se lee, que es de 32 o de 64 bits?
Expulsado de la cárcel por robar los barrotes
Arriba
prga Ver desplegable
Moderador
Moderador


Unido: 16/Noviembre/2004
Localización: España
Estado: Sin conexión
Puntos: 3250
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 10:27
Hola.
Nunca he utilizado ni instalado una versión de office de 64 bits, pero en Archivo-Ayuda aparece el número de versión y que es de 32 bits ( access2010.) En el 2013 está en Archivo-cuenta-acerca de..
Espero que sea esta la duda preguntada.
Un saludo a todos
Arriba
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 10:44
Hola prga y gracias por contestar. Sí, esa una duda complementaria a la cuestión principal que planteo en este hilo. Un saludo. Me sirve de mucho.
Expulsado de la cárcel por robar los barrotes
Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 12162
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 11:48
Buenas,

"Escribir un código de 64 bits" lo entiendo como escribir un código con las particularidades específicas de un Office 64 bits.

Existen algunas particularidades en el momento de utilizar ciertas variables y declaraciones en entorno de 64 bits. 

Tengo un cliente que utiliza la versión de 64 bits en todas sus máquinas (aunque ya sabemos que Microsoft solo aconseja la instalación de 64 bits en servidores... pero esa es otra guerra). Para que las aplicaciones funcionen correctamente tanto en las máquinas del cliente como en la mia (32 bits) es necesario realizar algunos cambios en las llamadas a las API. También la declaración de algunas variables Long se debe cambiar de Long a LongPtr (long de 64 bits). Para las llamadas a la API hay que declararlas como PtrSafe por lo que se requiere utilizar la constante de compilación condicional WIN64 (ya se que has dicho conocerlas pero aqui lo dejo). 

En definitiva: no es que haya que programar en 32 o 64 bits. Yo prefiero, para casos conocidos, programar para 32 y 64 bits


Esto sería la llamada normal a una API:

Public Declare Function SetTimer Lib "User32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long

Para que funcione en un Office 64 bits deberemos cambiar a (en rojo los cambios):

Public Declare PtrSafe Function SetTimer Lib "User32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As Long

Y, para que funcione indistintamente, utilizamos WIN64:

#If Win64 Then
    Public Declare PtrSafe Function SetTimer Lib "User32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As Long
#Else
    Public 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

Publicado originalmente por buho buho escribió:

Mi pregunta es...si yo creo una ACCDE... ¿Me aseguro que correrá perfectamente sin cambiar una linea de código en sistemas con Access de 64 Bits? ¿Y en WIndows (Ahora la mayoría) de 64 bits tambien?
No a la primera pregunta y depende a la segunda.
No a la primera por lo explicado antes.
Y depende a la segunda porque Windows 64 bits no implica forzosamente Office 64 bits.
Al final solo es relevante la versión de Office.

Publicado originalmente por buho buho escribió:

¿Yo como puedo saber si estoy escribiendo codigo de 64 a de 32 bits?
El código es, en un 99.9% idéntico. Solo cambian las declaraciones.

¿Te vale?

Un saludo

Xavi, un minyó de Terrassa

Mi web
Arriba
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 12:23
Gracias Xavi. Lo.sospechaba según los resultados que había obtenido en las pruebas.
En definitiva creo entenderte que si quiero que corra mi programa en ordenadores donde esté instalado el Office de 64 Bits o el.de 32 indistintamente me toca cambiar SI o SI todas las declaraciones de API mediante la compilación condicionada de Win64..
Pues tengo unas cuantas me cachis en la mar...

Voy a leerme bien el artículo pies hay APIS de Windows que efectivamente utilizan parámetros long y devuelven long .... Lo de ptrsafe lo entiendo pero creía que había que cambiar los long, todos, por longlong....en 64 Bits....

Es que en el.ejempo que has puesto hay parámetros que los dejas como long y otros con longptr...¿Porque?.

Gracias....estoy escribiendo con el móvil y no puedo escribir bien y a la vez visualizar tu respuesta.
Luego lo veo en casa.
Expulsado de la cárcel por robar los barrotes
Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 12162
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 12:47
Yo también estaba convencido de lo del LongLong pero en las aplicaciones que he desarrollado con compatibilidad no lo he encontrado. En cuanto a lo de cambiar sólo algunas de las declaraciones Long LongPtr... pues no sabria decirte. Creo que fue por el método de ensayo-error. Yo lo hago mediante una máquina virtual (utilizo VirtualBox) de 64 bits con office 64 bits. Hago las modificaciones en mi máquina (32 bits) para obtener código compatible y, una vez probado que no casca, paso la aplicación a la máquina virtual. Si hay que hacer alguna modificación se hace y, una vez funciona, devuelvo la aplicación al entorno 32 bits para la prueba final.

En cuanto a la cantidad de lineas a modificar... pues copy-paste & replace. No se me ocurre otra. Estaba mirando si la nueva versión de MZ-Tools (magnífica por otra parte) decía algo al respecto pero o no está o no lo se encontrar.
Xavi, un minyó de Terrassa

Mi web
Arriba
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 13:18
Gracias Xavi luego lo leo en casa con más calma porque este teléfono es insufrible.
En cualquier caso y ahora que nadie nos oye ni nos lee estas cuestiones deberían estar resueltas de manera interna por la propia Microsoft.

De hecho compiladores y linkadores de Clipper recuerdo que ellos mismos adaptaban el código automáticamente entre diferentes versiones del compilador.
Poco los hubiera costado crear un módulo interno dentro de VBA que discriminará automáticamente la versión de 32 o 64 bits donde corriera una aplicación y consecuente actuara el propio Access sin cambiar nada de código de las declaraciones de la API de Windows.

Me tocará efectivamente copiar y pegar adaptar las APIS y probar en diferentes máquinas y escenarios.

Venga chavalote muchas gracias por todo
Expulsado de la cárcel por robar los barrotes
Arriba
Bacterio Ver desplegable
Moderador
Moderador
Avatar

Unido: 16/Octubre/2004
Localización: España
Estado: Sin conexión
Puntos: 2077
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 13:23
Los Long que deben convertirse a LongPtr son los handles, punteros, etc, para que VBA7 los trate como long o longlong según estemos en un Office de 32 o 64 bits respectivamente.

Para lo de Long vs LongLong vs LongPtr yo suelo acudir a http://www.pinvoke.net/. Es fácil derivar el nuevo declare a partir de VB.NET sabiendo que "IntPtr" es equivalente a "LongPtr" y que un "Integer" de VB.NET equivale a "long" de VBA

<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function SetTimer (ByVal hWnd As IntPtr, ByVal nIDEvent As IntPtr, ByVal uElapse As UInteger, ByVal lpTimerFunc As IntPtr) As IntPtr
End Function



Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As LongPtr, ByVal lpTimerFunc As LongPtr) As LongPtr





Editado por Bacterio - 11/Agosto/2016 a las 13:53
Arriba
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 14:08
Bueno...ya en casa....lo he leído mejor.
Agradecer a Xavi sus respuestas y experiencias.
Y por supuesto tambien a Ricardo, nuestro querido y recordado D. Bacterio, por la deferencia de llamarme por teléfono y explicarme de viva voz todo esto.
Mil gracias Ricardo, te lo agradezco de corazón...y de paso nos hemos puesto un poco al día de nuestras respectivas vidas...

Bueno, pues yo por lo menos lo tengo ya claro del todo. 
A parte de eso Ricardo ha mostrado el camino en esa página de declaraciones de API para NET para, por similutud, saber qué parametros de la funcion etc debemos declarar (Dejar) como long (donde apareza Integer en NET) y cambiar a LongPtr lo que en NET esté como IntPtr
De esa manera, buscando el la pagina, la API correspondiente, vamos a tiro hecho....y nos dejamos de especular.

En fin, mil gracias a prga, Xavi y Ricardo.

No cierro hilo por si alguien queire añadir un poco mas de su experiencia personal al respecto.

P.D
Lo que voy a hacer es no complicarse la vida...exigir a la gente que quiera probar el programa gratuito, una versión de 32 Bits... y punto.
Y con calma y si tengo ganas, pasar las 20 0 25 declaraciones de API que tengo en el programa, por la compilación condicional.


Saludos a todos


Expulsado de la cárcel por robar los barrotes
Arriba
Bacterio Ver desplegable
Moderador
Moderador
Avatar

Unido: 16/Octubre/2004
Localización: España
Estado: Sin conexión
Puntos: 2077
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 14:16
Otro asunto es la confusión que genera Win64 vs VBA7. Dado que Microsoft empezó a publicar versiones de 64 bits a partir de Office 2010, a menudo se usa uno cuando se podría/debería usar el otro.

En el caso de la api que estamos tomando como ejemplo, ¿cómo deberíamos hacer la declaración?, ¿con Win64 o VBA7?

#If VBA7 then
Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As LongPtr, ByVal lpTimerFunc As LongPtr) As LongPtr
#else
Public 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

#If Win64 then
Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As LongPtr, ByVal lpTimerFunc As LongPtr) As LongPtr
#else
Public 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

En mi opinión, la forma correcta sería la primera: VBA7, dado que Office adaptará lo declarado como "LongPtr" según estemos en uno u otro caso.

En el caso concreto, ambos funcionan porque no existen versiones de 64 bits anteriores a Office 2010. Y todos los Office 2010 y posteriores ya son VBA7.

El uso de la constante de compilación Win64 creo que va en otra línea. Por ejemplo, si tenemos dos dll's con distinto nombre. Por ej

#if Win64 then
   Declare PtrSafe Function MyMathFunc Lib "MyLibx64" (ByVal N As LongLong) As LongLong
#else
   Declare Function MyMathFunc Lib "MyLibx86" (ByVal N As Long) As Long
#end if

Una cosa a tener en cuenta es que todo esto no acaba en la declaración de la api, a menudo se traslada al resto del código, tendremos que ajustar la declaración de todas las variables que usemos en las llamadas. 

#If VBA7 Then
Public Declare PtrSafe Function apiGetFocus Lib "user32" Alias "GetFocus" () As LongPtr
#Else
Public Declare Function apiGetFocus Lib "user32" Alias "GetFocus" () As Long
#End If

Private Sub Test1

#If VBA7 Then
Dim hWnd as longPtr
#else
Dim hWnd as long
#End If

hWnd = GetFocus

End Sub

y algunas cosas un poco más raras cuando se ve afectada la declaración de la función por sus parámetros o el tipo devuelto

#If VBA7 Then
Public sub OcultarVentana(byval hWnd as longPtr)
#Else
Public sub OcultarVentana(byval hWnd as long)
#End If

'...

End Sub


Coincido con el Buho: si estás en condiciones de exigir Office de 32 bits, te olvidas del asunto y no te complicas la vida. En ocasiones no te queda más remedio si usas un componente externo que sólo está disponible para 32 bits.


Editado por Bacterio - 11/Agosto/2016 a las 14:17
Arriba
Emilio Ver desplegable
Administrador
Administrador

Santander

Unido: 08/Agosto/2004
Localización: España
Estado: Sin conexión
Puntos: 18819
Enlace directo a este mensaje Enviado: 11/Agosto/2016 a las 15:44
Mi experiencia en el curro, ahora estoy haciendo pruebas para la migración Confused es que además de las API's, falla el OLEDB con el propio Access, fuerza el cambio, manual, de la referencia a DAO, y algunos de los ActiveX propios de Office se han de reemplazar Angry
Saludos a todos desde Huelva

http://www.mvp-access.es/emilio/
Arriba
buho Ver desplegable
Administrador
Administrador
Avatar
Abuelo FELIZ

Unido: 10/Abril/2004
Localización: Valladolid
Estado: Sin conexión
Puntos: 11317
Enlace directo a este mensaje Enviado: 12/Agosto/2016 a las 00:20
Publicado originalmente por Bacterio Bacterio escribió:

<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function SetTimer (ByVal hWnd As IntPtr, ByVal nIDEvent As IntPtr, ByVal uElapse As UInteger, ByVal lpTimerFunc As IntPtr) As IntPtr
End Function

Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As LongPtr, ByVal lpTimerFunc As LongPtr) As LongPtr



Ricardo...¿Por qué uElapse lo has declarado como LongPtr en VBA si en Net estaba como UInteger?
Expulsado de la cárcel por robar los barrotes
Arriba
emiliove Ver desplegable
Moderador
Moderador


Unido: 16/Junio/2009
Localización: Mexico
Estado: Sin conexión
Puntos: 5044
Enlace directo a este mensaje Enviado: 12/Agosto/2016 a las 00:54
Arriba
guarracuco Ver desplegable
Moderador
Moderador
Avatar

Unido: 24/Abril/2004
Localización: EEUU
Estado: Sin conexión
Puntos: 3090
Enlace directo a este mensaje Enviado: 12/Agosto/2016 a las 02:04
Mi aplicacion hecha en XP funciona en MAccess 2016 sin problema alguno. Solo la compilacion condicional para las llamadas a APIs y listo.
https://tucondominioaldia.net
Arriba
 Responder Responder Página  12>
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable