Autor Tema: ¿Referenciar o no referenciar? Esa es la cuestión  (Leído 4120 veces)

Desconectado xavi

  • Administrador
  • Habitual
  • *****
  • Mensajes: 220
¿Referenciar o no referenciar? Esa es la cuestión
« en: Mayo 04, 2020, 10:12:43 am »
Palabras clave: librerías, bibliotecas, referencias, Object
Autor: xavi
Extraído de: experiencia propia

27/07/2022 ¡Actualizado!
Ver la nueva versión

Si bien se han publicado diferentes ejemplos sobre la forma de gestionar las referencias de nuestras aplicaciones, yo nunca he con seguido que funcionen. Para mi es complicado entender que, si un código no se ejecuta por referencias, el propio código *que no puede ejecutarse* lo pueda corregir. Así que presento la solución que yo he aplicado.

En mis aplicaciones es muy usual que se interactue con Excel por lo que, durante el desarrollo, es mucho más cómodo tener marcada la referencia de Excel para tener a mano los comandos con el IntelliSense  y las constantes.
El problema es la disparidad de versiones que Office que conviven y que los chicos de Microsoft han resuelto bastante bien la "subida" de referencias pero en absoluto la "bajada".
Tabla de versiones
200712.0
201014.0
201315.0
201616.0


En los siguientes escenarios se marca la referencia en desarrollo y no se desmarca al enviar la aplicación al cliente.

Escenario 1
Desarrollamos en Office 2013
Cliente dispone de Office 2013 o 2016

Al enviar nuestra aplicación al cliente, aquellos PC's con Office 2013 mantendrán la versión 15.0 de la librería; los que tuvieran 2016, "subirían" a 16.0

Escenario 2
Desarrollamos en Office 2016
Cliente dispone de Office 2013 o inferiores

Al enviar la aplicación al cliente, todos los PC's mantendrán la versión 16.0 y, como ninguno de ellos la tiene instalada, obtendremos un error y no podremos ejecutar la aplicación.

Caso especial
Aplicaciones desarrolladas en versiones antiguas (97, 2000) que tienen referencias a otras aplicaciones Office de esas versiones (8.0, 9.0) no son capaces de "subir" la versión cuando se ejecutan en, por ejemplo, una versión 2010.

Así pues, podemos tener un problema entre la comodidad de programar con las referencias y la distribución de las aplicaciones.

Dado que tener todas las versiones de las librerías de Office  se antoja complicado, la solución pasa por entregar la aplicación sin las referencias de Office. Para cambiar a trabajar sin referencias es necesario cambiar nuestra táctica de declaración. Lo que hasta ahora declarábamos como Excel.Application habrá que declararlo como Object. Ello nos privará del IntelliSense y del acceso a las constantes específicas de la aplicación Office que queramos utilizar.

¿Como solucionamos eso? Expongo mi técnica.

Supongo que todos sabemos como funcionan las directivas de compilador (aquí faltaría un link) por lo que nos podemos apoyar en ellas para crear nuestra propia directiva.

En un módulo independiente definimos nuestras propias constantes a modo de directiva:

' Constante de utilización de librerías de Office
#Const UseOL_XLS = False
#Const UseOL_OLK = False


A continuación ponemos una directiva:

#If UseOL_XLS Then
  Public xlsApp As Excel.Application
#Else
  Public xlsApp As Object
#End If


Nota: desde este momento yo dejo de declarar xlsApp cada vez que lo necesito. Habitualmente solo trabajo con un fichero de Excel por que lo que puedo utilizar una variable Public. En caso de necesitar declarar en un procedimiento específico otra instancia de Excel utilizaría la misma técnica:

#If UseOL_XLS Then
  Dim xlsAppOtro As Excel.Application
#Else
  Dim xlsAppOtro As Object
#End If


Durante el desarrollo marco la referencia de Excel y cambio la constante UseOL_XLS a True para poder acceder a los métodos y constantes de Excel.

¿Y las constantes específicas de la otra aplicación?
Pues para las constantes hay que ir manteniendo una lista en la zona #Else de manera que, cuando no tengamos marcada la librería, siga funcionando.

Ejemplos de constantes:

    Public Const xlVeryHidden = 2
    Public Const xlPrintNoComments = -4142
    Public Const xlLandscape = 2
    Public Const xlAutomatic = -4105
    Public Const xlDownThenOver = 1
    Public Const xlPrintErrorsDisplayed = 0
    Public Const xlDown = -4121
    Public Const xlUp = -4162
    Public Const xlLeft = -4159
    Public Const xlRight = -4161
    Public Const xlCenter = -4108
    Public Const xlBottom = -4107
    Public Const xlToLeft = -4159
    Public Const xlToRight = -4161
    Public Const xlEdgeLeft = 7
    Public Const xlEdgeTop = 8
    Public Const xlEdgeBottom = 9
    Public Const xlEdgeRight = 10
    Public Const xlInsideVertical = 11
    Public Const xlInsideHorizontal = 12
    Public Const xlContinuous = 1
    Public Const xlColorIndexAutomatic = -4105
    Public Const xlHairline = 1
    Public Const xlMedium = -4138
    Public Const xlThick = 4
    Public Const xlThin = 2
   

La precaución que debemos tener a la hora de programar es la de añadir cualquier nueva constante que utilicemos.

¿Y a la hora de distribuir?
Sencillo.
- Quitar la referencia de Excel
- Cambiar la constante UseOL_XLS a False
- Compilar por si me hubiera dejado alguna constante no definida o alguna "cosa rara" en cuyo caso lo corregiría

Con esta forma de trabajar me he ahorrado tener un montón de "dobles declaraciones" y estar poniendo/quitando la adecuada:

Dim xlsApp As Excel.Application
'Dim xlsApp As Object

Truco:¿Como mantengo mi lista de #constantes?
Yo lo tengo en un módulo independiente dónde, en el encabezado, consta la versión del módulo. Cada vez que añado una constante lo registro en el log de cambios y subo el número de versión. El módulo lo exporto a una determinada carpeta. Además llevo un registro de versiones de todos los módulos en un Excel.

Cuando debo actualizar una aplicación, lo primero es revisar las versiones de los módulos por si tuviera versiones más actuales. Si el módulo de directivas de mi archivo es más moderno del de la aplicación, simplemente importo el nuevo módulo.

Espero que os sirva para "salvar" el problema de las referencias.
« Última modificación: Julio 28, 2022, 12:06:15 am por xavi »