Requisito de Access, función Replace en modo múltiple

zanys Mensajes publicados 50 Estado Miembro -  
zanys Mensajes publicados 50 Estado Miembro -

Hola,

trabajo con Access 2007-2016 y a través de consultas.

He construido una consulta que me da la tabla a continuación:

Campo1

20

21

22

23

....

...

y debo transformar los valores del campo1 en otra columna campo2

20 --> 60

22 --> 62

24 --> 64

23 --> 63

....

etc

Pensaba hacer en SQL un replace anidado...

tipo: Replace(Replace(campo1, '20', '60'), '21', '61') AS campo2

pero tengo 16 modificaciones que hacer (16 anidaciones de replace) y por lo tanto, recibo un bonito mensaje que indica que al exceder los 1024 caracteres no puede funcionar en modo creación... al menos, si he entendido bien... así que pierdo todos mis campos después del campo1 cuando paso a modo creación...

¿Hay alguna otra manera con la función replace que evite hacer anidaciones y evitar este mensaje de superación?

Gracias por tu valiosa ayuda.

Amablemente,

Zanys

7 respuestas

Bruno83200_6929 Mensajes publicados 724 Fecha de registro   Estado Miembro Última intervención   170
 

Hola,

Le aconsejo este método.

Crear una tabla de correspondencia


Cree una tabla TableCorrespondencia con dos columnas:

AntiguaValor (20, 21, 22, 23, 24...)
NuevaValor (60, 61, 62, 63, 64...)

Luego utilice una unión:

SELECT t1.campo1, Nz(tc.NuevaValor, t1.campo1) AS campo2 FROM su_tabla t1 LEFT JOIN TableCorrespondencia tc ON t1.campo1 = tc.AntiguaValor

0
zanys Mensajes publicados 50 Estado Miembro 5
 

Muchas gracias por esta solución.

Confieso que lo pensé... pero pensé que podríamos hacer un "replace multiple" sin anidamientos, tipo replace (campo, (val1, nueva_val1), (val2, nueva_val2), ....)

Voy a probar esta solución de tabla de correspondencia.

Gracias de nuevo.

1
zanys Mensajes publicados 50 Estado Miembro 5
 

Bueno, en realidad, he hecho así...

Mi proyecto es un poco más complejo...

pero aun así he creado una tabla de correspondencia...

He vinculado el antiguo valor (AOFUNCTION de la tabla VIBDAO) al antiguo valor incluido en mi tabla de correspondencia... y extraigo el nuevo valor asociado de la tabla de correspondencia...

lo que me da en SQL:

con al final:

Funciona bastante bien, excepto que tengo antiguos valores (AOFUNCTION) vacíos... y en ese caso, la línea completa no se muestra, y me gustaría que se mostrara... con el antiguo valor vacío y el nuevo valor vacío...

He intentado en mi tabla de correspondencia crear dos celdas vacías para el antiguo y el nuevo valor, pero no funciona...

No es muy comprensible, creo, pero bueno...

Sigo con mis investigaciones...

(¿Para qué sirve el Nz?)

0
Bruno83200_6929 Mensajes publicados 724 Fecha de registro   Estado Miembro Última intervención   170
 

¡Perfecto! Veo exactamente tu problema. Estás utilizando un INNER JOIN que excluye las filas donde AOFUNCTION está vacío/nulo, mientras que quieres conservarlas.

Solución: Reemplazar INNER JOIN por LEFT JOIN
Aquí está lo que debes modificar en tu consulta:
En lugar de:

INNER JOIN [Tabla de correspondencia funciones] ON VIBDAO.AOFUNCTION = [Tabla de correspondencia funciones].[Antigua función]

Usa:

LEFT JOIN [Tabla de correspondencia funciones] ON VIBDAO.AOFUNCTION = [Tabla de correspondencia funciones].[Antigua función]

Explicación de las uniones

INNER JOIN: Solo devuelve las filas donde hay una coincidencia en ambas tablas
LEFT JOIN: Devuelve TODAS las filas de la tabla izquierda (VIBDAO), incluso si no hay coincidencia en la tabla derecha

Acerca de la función Nz()
La función Nz() (Null a Cero) reemplaza los valores nulos por un valor por defecto:

-- Sintaxis Nz(expresión, valor_si_nulo) -- Ejemplo Nz([Nueva función], "") AS AOFUNCTION

Esto te dará:

Si AOFUNCTION tiene una coincidencia → muestra el nuevo valor
Si AOFUNCTION está vacío/nulo → muestra una cadena vacía ""

Tu consulta modificada debería parecerse a:

SELECT VIBDAO.AOID AS OBJIDENT, "Z038" AS [Antiguo AOTYPE], "4BAT" AS AOTYPE, VIBDAO.AONR, Left(VIBDAO.AOID, 14) AS PARENTNODE, "" AS ANCIEN_CODIGO, VIBDAO.XAO, VIBDAO.DOORPLT, Nz([Tabla de correspondencia funciones].[Nueva función], "") AS AOFUNCTION FROM VIBDAO LEFT JOIN [Tabla de correspondencia funciones] ON VIBDAO.AOFUNCTION = [Tabla de correspondencia funciones].[Antigua función]

¡Esto debería resolver tu problema y mostrar todas las filas, incluso aquellas con AOFUNCTION vacío!


0
Zanys
 

Ohhhh…. Qué decir… un enorme gracias por tomarte el tiempo para explicarme la solución…

Confieso que estoy de vacaciones, pero a mi regreso al trabajo el 21 de julio, lo probaré… pero estoy segura de que funcionará.

Realmente un enorme gracias por la solución y las explicaciones, ¡es muy amable!

0
Bruno83200_6929 Mensajes publicados 724 Fecha de registro   Estado Miembro Última intervención   170
 

Estoy muy feliz de haber podido ofrecerte mi ayuda. ¡Atentamente!

0
Zanys
 

Hola,

de vuelta en mi trabajo, he probado...

Tengo la impresión de que tengo que modificar todos los INNER JOIN en LEFT JOIN? ¿Es así?

0
Zanys
 

Ah no, tanto por mí... no funciona bien solo con el último LEFT JOIN...

0
zanys Mensajes publicados 50 Estado Miembro 5
 

Por otro lado, tengo otro problema con el mismo proyecto...

He creado 6 consultas 2-1 2-2 2-3 .... etc. que, con una macro, me devuelven automáticamente 6 archivos de Excel distintos...

Me gustaría que una macro ejecutara estas 6 consultas pero al final, pusiera automáticamente el contenido de estas 6 consultas en un solo archivo de Excel... ¿Es posible?

0