Al final me he creado un código muy sencillito (dada mi inexperiencia) en VBA que me ha hecho el trabajo.
He creado una tabla intermedia, y sacando los datos de la consulta que mostré arriba (con un par de columnas añadidas por especificaciones del cliente), los he ido añadiendo y alterando la tabla según fuese necesario.
Dejó aquí el código por si puede ser de utilidad para alguien:
Código:
Public Function ActualizarGestionTarifasNoRecibidas()
DoCmd.SetWarnings False 'Quitar Warnings para que no nos avise de las anexiones ni los cambios
On Error GoTo Err_ActualizarGestionTarifasNoRecibidas
Dim db As Database
Dim SQLText As String
Dim rst1 As DAO.Recordset
Dim rst2 As DAO.Recordset
Dim i As Integer 'Contador del blucle
Dim NCabecera As String 'Contenedor de la cabecera actual
Dim rst2Cabecera As String 'Valor real de la cabecera actual
Set db = CurrentDb()
Set rst1 = db.OpenRecordset("_GestionTarifasNoRecibidas", dbReadOnly)
If Not (rst1.BOF And rst1.EOF) Then 'Comprobar que hay registros en el rst (no estamos ni en el BOF ni en el EOF)
Do While Not rst1.EOF 'Mientras no lleguemos al final
SQLText = " SELECT * FROM GestionTarifasNoRecibidas " _
& " WHERE IdPersonas = " & rst1![IdPersonas] & " ORDER BY IdPersonas"
Set rst2 = db.OpenRecordset(SQLText)
If Not (rst2.BOF And rst2.EOF) Then 'True significa que la persona ya existe en la tabla
For i = 1 To ((rst2.Fields.Count) - 5) 'Máximo de cabeceras hasta el momento
NCabecera = "Cabecera" & i 'Valor de la cabecera actual -> Cabecera1, Cabecera2 ... CabeceraN
If Not IsNull(rst2.Fields(NCabecera)) Then
rst2Cabecera = rst2.Fields(NCabecera) 'Valor real de la cabecera actual
If (rst2Cabecera = rst1![Cabecera]) Then
Exit For 'Salir del bucle si la cabecera está dada de alta
End If
If (rst2Cabecera = "") Then 'Primera cabecera vacía (porque se haya borrado alguna previa o algo parecido
DoCmd.RunSQL "UPDATE GestionTarifasNoRecibidas SET " & NCabecera & " = '- ' + '" & Replace(rst1![Cabecera], "'", "''") & "' WHERE IdPersonas = " & rst1![IdPersonas] & " " ' Asignamos la Cabecera a la Persona
Exit For 'Salimos del bucle una vez añadida la cabecera
End If
Else 'Si el valor de la cabecera es nulo es que está vacío, y por tanto estamos ante una libre
DoCmd.RunSQL "UPDATE GestionTarifasNoRecibidas SET " & NCabecera & " = '- ' + '" & Replace(rst1![Cabecera], "'", "''") & "' WHERE IdPersonas = " & rst1![IdPersonas] & " " ' Asignamos la Cabecera a la Persona
Exit For 'Salimos del bucle una vez añadida la cabecera
End If
Next i
If i = ((rst2.Fields.Count) - 4) Then 'Si i es igual que ((rst1.Fields.Count) - 5 + 1 ) significa que ha recorrido el for anterior entero
rst2.Close 'Cierro el Recordset para evitar problemas de exclusividad
NCabecera = "Cabecera" & i
DoCmd.RunSQL "ALTER TABLE GestionTarifasNoRecibidas ADD " & NCabecera & " Text "
DoCmd.RunSQL "UPDATE GestionTarifasNoRecibidas SET " & NCabecera & " = '- ' + '" & Replace(rst1![Cabecera], "'", "''") & "' WHERE IdPersonas = " & rst1![IdPersonas] & " " ' Asignamos la Cabecera a la Persona
End If
Else 'False significa que la persona no existe en la tabla, por lo que la damos de alta con los datos actuales del rst1
DoCmd.RunSQL "INSERT INTO GestionTarifasNoRecibidas (IdPersonas, Nombre, Apellidos, Email, Cargo) " _
& " VALUES (" & rst1![IdPersonas] & ", '" & rst1![Nombre] & "', '" & rst1![Apellidos] & "', '" & rst1![Email] & "', '" & rst1![Cargo] & "') "
rst1.MovePrevious 'Movemos uno atrás para volver a comprobar con los nuevos datos
End If
rst1.MoveNext
Loop
End If
Set db = Nothing
Set rst1 = Nothing
Set rst2 = Nothing
Exit_ActualizarGestionTarifasNoRecibidas:
Exit Function
Err_ActualizarGestionTarifasNoRecibidas:
MsgBox Err.Description
Resume Exit_ActualizarGestionTarifasNoRecibidas
DoCmd.SetWarnings True 'Activar Warnings
End Function
¡AVISO! Introducir los valores debería hacerse con los propios Rerdsets ya que están activados...
Un saludo a todos.
Psdt: Ya puede algún moderador cerrar el tema y darlo por solucionado