Recientemente trabajé en un proyecto en el que nuestro cliente está vendiendo un producto en los EE. UU. Basado en Access con SQL Server, funciona importando datos a SQL y luego analizándolos con informes de Access. Lamentablemente, cada cliente puede tener un formato de clave principal como un entero largo y otros donde es una cadena (combinación de números y cadenas), descubrimos rápidamente que causaba problemas con los informes que no se ordenaban correctamente. Los informes fueron diseñados con enteros en mente y las cadenas alteraron el orden. Necesitábamos encontrar una solución sin requirir agregar código a nuestra interfaz de Access para manejar el problema, sino que más bien usar el poder de SQL Server para servir los datos independientemente del formato utilizado en la clave primaria.

Vistas al rescate

Una cosa interesante acerca de vincular las vistas y tablas de SQL Server en Access: puede asignarles el nombre que desee. Lo Aproveche por la fuente de la tabla vinculada con una vista, si la clave primaria es una cadena o dejarla como la tabla original si era un número entero. Tener los mismos nombres de tabla en Access independientemente de la fuente significaba no tener que cambiar mi código.

Manejamos enlaces usando una tabla de SQL Server

Juan escribió en su blog sobre la creación de enlaces de tablas desde SQL Server, donde usamos código para leer registros en una tabla llamada tblTablePermissions para crear los enlaces en nuestra interfaz de Access usando el código VBA. Por lo general, nos vinculamos solo al comienzo del proyecto o cuando se agrega una nueva tabla al servidor, pero para este proyecto tenía que ir un paso más allá cambiando el nombre de la tabla con el nombre de la vista en tblTablePermissions si el cliente usa una cadena para clave primaria.

Hay dos campos en tblTablePermissions, uno llamado Table_Name y otro llamado AccessName, nuestro código usa el primero para saber qué tabla o vista usar como fuente y el segundo para el nombre de la tabla en Access. Todo lo que hice fue crear un script simple que mi cliente puede ejecutar para intercambiar los nombres de las tablas con los nombres de las vistas para cada instalación que lo necesitara.

Aquí está el guión que utilicé:

--Update tblTablePermissions For Numeric Type Code--
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
DELETE FROM [dbo].[tblTablePermissions]
WHERE [Table_Name] = ('tablename1')
or [Table_Name] = ('tablename2')
or [Table_Name] = ('tablename3')
GO
IINSERT INTO [dbo].[tblTablePermissions] ([Table_Name], [Access_Name], [IndexedColumns], [UserSelect], [UserInsert], [UserUpdate], [UserDelete])
VALUES ('vw_tablename1', 'tablename1', '', 'True', 'True', 'True', 'True'),
('vw_tablename2', 'tablename2', 'field1,field2,field3', 'True', 'True', 'True', 'True'),
('vw_tablename3', 'tablename3', 'field1,field2', 'True', 'True', 'True', 'True')
GO

En mi script anterior, primero elimino las tablas de tblTablePermissions que deseo intercambiar con vistas y luego uso una instrucción de inserción para agregar las vistas que reemplazarán las tablas, observe que los nombres de las vistas son diferentes pero el campo Access_Name es el mismo que en los eliminados, lo que permite que mi código de access funcione independientemente del tipo de campo de clave principal que se utilice.

Cómo usé CAST para traducir la clave primaria

En las vistas, utilicé la función CAST para convertir el tipo de campo de una cadena en un entero:

CREATE VIEW vw_tablename1
AS
SELECT RangeID,
UseFlagAsNeeded,
CAST(Type AS int) AS Type,
Line,
Ownership,
Include,
Public,
Limit,
RangeA,
RangeB,
RangeC,
SSMA_TimeStamp
FROM dbo.tablename1;
GO

¡Nuestro cliente ahora puede configurar fácilmente cada instalación en función de los datos del cliente!