Primero que todo lo felicito Hernán por utilizar PostgreSQL como Back End, es un gran acierto. La instrucción que explican le sobra un paréntesis en And (Year(fecha)<2020 y NO es la respuesta porque la información ya está agrupada por idgrupo y fecha, lo que solicitan es "... obtener en una columna el monto del siguiente período de acuerdo con el grupo". Asumo por esto se hace en PostgreSQL por la dificultad.
Lo primero que debe realizar es hacer la consulta en PostgreSQL y probarla, si es correcta se copia para insertarla en el código de VBA.
CONSULTA EN POSTGRESQL
Explicación de la consulta en PostgreSQL:
Para agrupar por año es necesario obtener el año del campo fecha, esto lo hago con la función extract(year from fecha). Retorna 2018, 2019 etc
LEAD proporciona acceso a una fila que sigue a la fila actual en un desplazamiento físico especificado
OVER determina exactamente cómo se dividen las filas de la consulta para que las procese la función de ventana.
PARTITION BY pertenece a la categoría Funciones de ventana. Las funciones de ventana de PostgreSQL son las que son capaces de realizar cálculos que abarcan varias filas de una columna, pero no todas las filas.
ORDER BY permite ordenar por el año, igualmente se debe convertir el campo fecha. Se había podido crear una función en PostgreSQL para pasar la fecha como parámetro y obtener el año.
RESULTADO EN POSTGRESQL
AHORA EN ACCESS
FORMULARIO
Hago clic en
Crear Query y obtengo
CÓDIGO DEL BOTÓN CREAR QUERYPrivate Sub btn_2_Click()
Dim strQuery As String
strQuery = "qryComparaPorGruposPeriodos"
If (Not (IsNull(Me.cboDesde) And IsNull(Me.cboHasta))) And Me.cboDesde < Me.cboHasta Then
Call CreaQueryComparaPorGruposPeriodos(strQuery, Val(Me.cboDesde), Val(Me.cboHasta))
DoCmd.OpenQuery strQuery
End If
End Sub
CÓDIGO DE LA FUNCIÓN
Public Function CreaQueryComparaPorGruposPeriodos(SPTQueryName As String, intDesde As Integer, intHasta As Integer)
'En este ejemplo se utiliza la función para obtener en una columna
'el monto del año siguiente en un rango de años por grupos
'Requiere referenciar a:
' Microsfot ActiveX Data Objectc 6.1 Library
' Microsfot ADO Ext. 6.0 for DLL and Security
'Fuente:
' Microsoft
'Adpatación para PostgreSQL
'Eduardo Pérez Fernández
'Fecha: 13/09/2022
'Parametros:
' SPTQueryName --> Nombre de la consulta a crear
' intDesde ---> Año inicial
' intHasta ---> Año final
On Error GoTo hay_Error
Dim cat As ADOX.Catalog
Dim cmd As ADODB.Command
Dim strSQl As String
Dim tB As DAO.TableDef
Dim MyQueryDef As QueryDef
With CurrentDb
For Each MyQueryDef In CurrentDb.QueryDefs
If MyQueryDef.Name = SPTQueryName Then
.QueryDefs.Delete (SPTQueryName)
.QueryDefs.Refresh
Exit For
End If
Next
End With
Set cat = New ADOX.Catalog
Set cmd = New ADODB.Command
cat.ActiveConnection = CurrentProject.Connection
Set cmd.ActiveConnection = cat.ActiveConnection
strSQl = "SELECT idgrupo,extract(year from fecha) as mperiodo " & vbCrLf
strSQl = strSQl & " , monto" & vbCrLf
strSQl = strSQl & " , LEAD(monto,1) OVER (PARTITION BY idgrupo " & vbCrLf
strSQl = strSQl & " ORDER BY extract(year " & vbCrLf
strSQl = strSQl & " FROM fecha) ) ventas_sgte_periodo " & vbCrLf
strSQl = strSQl & " FROM ventas " & vbCrLf
strSQl = strSQl & " WHERE extract(year " & vbCrLf
strSQl = strSQl & " FROM fecha) BETWEEN " & intDesde & " AND " & intHasta & ";"
cmd.CommandText = strSQl
cmd.Properties("Jet OLEDB:ODBC Pass-Through Statement") = True
cmd.Properties _
("Jet OLEDB:Pass Through Query Connect String") = _
"ODBC;DSN=dbconta;"
cat.Procedures.Append SPTQueryName, cmd
Set cat = Nothing
Set cmd = Nothing
hay_Error_Exit:
Exit Function
hay_Error:
MsgBox "Ocurrió el error " & Err.Number & vbCrLf & vbCrLf & Err.Description, vbCritical, "Error..."
Resume hay_Error_Exit
End Function
Y no dejará de resultar quien opine que no es eficiente utilizar PostgreSQL con Access en bases de datos "pequeñas", supuestamente por el rendimiento.
Realmente no entro en discusión porque usted solo medio conoce Access como base de datos. - Eduardo Pérez Fernández
Jamás entender porque con esa visión tan negativa, sigue utilizando Access, cuando hay más opciones en el mercado, parece el clásico 'perro del hortelano', además de sufrir 'el síndrome del principito'.En fin, ve a hacer un pis y después a la cama que ya es tarde para los niños. - Enrique Feijóo
Porque Access va muy bien con los ODBC de PostgreSQL y es un excelente Front End, Mientras no mire más allá de sus hombres se quedará con las limitaciones de Access. Cuántos quisieran llevar sus bases de datos a la nube, pero no lo puede hacer porque no hay suficiente información al respecto, acá es donde usted queda limitado y no sé cómo se atreve a atacar todo lo que público relacionado con PostgreSQL, sino lo ha utilizado. Créame si hace 10 años hubiera conocido el PostgreSQL había dejado de utilizar Access como Back End. La diferencia que tenemos es que usted solo ha utilizado bases de datos monousuario y nada multiusuario, es donde, hay que tener mucho cuidado con las consultas y más. - Eduardo Pérez Fernández
Te arrogas el derecho de saber lo que yo sé, (pobre iluso) a mi no me preocupa lo que sepas (o dices saber), vete a jugar con tus patitos y deja al resto tranquilo, has sido tu. el que desde las primeras intervenciones ha sido faltón y desconsiderado, demostrando que carece de la más elemental educación, siempre te he visto interpretando el papel de la zorra en la fábula de las uvas /// ¿Qué te gusta PostgreSQL? ... ¡¡¡ DISFRUTALO !!! pero no trates de imponerlo. //// Creo que, por necesidad de llegar a alguna parte, has creado 'algo' en consultas de paso a través y la primera FUSILANDO una transacción diseñada para SQL Server). /// fin - Enrique Feijóo
Ese es el problema de no reconocer el trabajp de otro, efectivamente y respeto a la fuente para hacer la consulta de paso a través es de Microsoft porque es el más indicado si revisa difiere de la original en algunos aspectos, claro usted no lo entinde porque sencillamente no tiene como probarlo. Para finalizar le pido el favor deje su prepotencia de sabelo todo de nada. Esta lejos de mis 29 años de experiencia en Access y 7 en PostgreSQL pero claro nunca es tarde para aprender apresúrese antes que le cierren la escuela. - Eduardo Pérez Fernández