** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - FILTROS EN SQL
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoFILTROS EN SQL

 Responder Responder
Autor
Mensaje
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Tema: FILTROS EN SQL
    Enviado: 23/Enero/2018 a las 15:50
Estimados amigos, tengo un problema de filtros en una SQL para que me filtre unos datos para imprimir un informe que es una factura, pero no consigo que lo haga, y sin embargo me acumula los datos de varios clientes en lugar de imprimir cada factura con los datos correspondientes. Por favor, espero que alguno de vosotros pueda indicarme el error o lo que me falta por implementar. La SQL, es una consulta de Sumas y Agrupar por, debe acumular 3 criterios de filtro, el nº de cliente (Z), el año (intAño) y el mes (numMesBis). Aquí dejo la parte del código hasta la SQL; si hiciera falta todo el resto, que no creo dado que si he comprobado que funciona correctamente, por favor, indicadmelo. Un saludo a todos.

 

W = DCount("[IdCliente]", "[tbClientes]")

'Cuenta el nº de clientes y como estos se numeran del 1 en adelante, no hay problema

NumMes = Month(Fecha())

If NumMes = 1 Then

   intAño = Year(Fecha()) - 1

   numMesBis = 12

Else

   numMesBis = NumMes - 1

   intAño = Year(Fecha())

End If

'Para cuando hay que imprimir las facturas de diciembre en el mes de Enero del siguiente año

    MostrarMensaje ("ENCIENDA LA IMPRESORA Y COLOQUE PAPEL TAMAÑO A4 o Folio")

   

For Z = 1 To W

 

    NUMFAC = NumeroFactura

    NumFra = "RT/" & Format(NUMFAC, "0000") & "/" & Right(Year(Date), 2)

    curSumaIVA = 0

    curSumaBImp = 0

    curSumaTPagar = 0

 

    NUM = DCount("[IdPedido]", "[tbDetallesPedido]", "[IdCliente]=" & Z & "")

    NUMBis = DCount("[IdPedido]", "[tbPedidos]", "[IdCliente]=" & Z & "")

    ' Estas dos líneas me buscan si existen pedidos para el nº de cliente en cuestión; si no los hay, entonces salta o evita todo el código y el bucle For

    ' aumenta en una unidad hasta el siguiente nº de cliente y se repite la acción. Si hay pedidos para alguno, se recorre todo el código que sigue.

  If NUM > 0 Then

         

   SQL = "SELECT tbClientes.IdCliente, tbClientes.NCliente, tbClientes.NIF, tbClientes.NComun, tbClientes.Direccion, tbClientes.Tlf," _

   & "tbClientes.CodPostal, tbClientes.Ciudad, tbClientes.Provincia, tbPedidos.UdVenta, tbPedidos.FechaPedido, tbPedidos.Año, tbDetallesPedido.IdProducto," _

   & "tbBASICORECETAS.NProducto, tbDetallesPedido.PrecioUnidad, Sum(tbDetallesPedido.Uds) AS SumaDeUds, Sum(tbDetallesPedido.BImp) AS SumaDeBImp," _

   & "tbDetallesPedido.DTO, Sum(tbDetallesPedido.ImpDTO) AS SumaDeImpDTO, Sum(tbDetallesPedido.Neto) AS SumaDeNeto, tbDetallesPedido.IVA," _

   & "Sum(tbDetallesPedido.ImpIVA) AS SumaDeImpIVA, Sum(tbDetallesPedido.Total) AS SumaDeTotal, tbPedidos.EmitidoAlb, tbPedidos.EmitidaFra," _

   & "tbPedidos.DuplicadoFra, DatePart('m',[FechaPedido]) AS Mes FROM (tbClientes INNER JOIN tbPedidos ON tbClientes.IdCliente = tbPedidos.IdCliente)" _

   & " INNER JOIN (tbBASICORECETAS INNER JOIN tbDetallesPedido ON tbBASICORECETAS.IdProducto = tbDetallesPedido.IdProducto)" _

   & " ON tbPedidos.IdPedido = tbDetallesPedido.IdPedido GROUP BY tbClientes.IdCliente, tbClientes.NCliente, tbClientes.NIF, tbClientes.NComun," _

   & "tbClientes.Direccion, tbClientes.Tlf, tbClientes.CodPostal, tbClientes.Ciudad, tbClientes.Provincia, tbPedidos.UdVenta, tbPedidos.FechaPedido," _

   & "tbPedidos.Año, tbDetallesPedido.IdProducto, tbBASICORECETAS.NProducto, tbDetallesPedido.PrecioUnidad, tbDetallesPedido.DTO, tbDetallesPedido.IVA," _

   & "tbPedidos.EmitidoAlb, tbPedidos.EmitidaFra, tbPedidos.DuplicadoFra HAVING (((tbPedidos.IdCliente)=" & Z & ") AND ((tbPedidos.Año) =" & intAño & ") AND ((tbPedidos.EmitidaFra)=False)" _

   & " AND ((DatePart(""m"",[FechaPedido]))=" & numMesBis & ")) ORDER BY tbClientes.IdCliente;"

'Este SQL debe ser una consulta de Suma filtrada por el nº de cliente, el año en curso y para el mes anterior al actual.

     cadNombreDocumento = "RptFacturaCorosaTRES"

    ' Informe Imprimir FacturaCorosaTRES, usa la consulta SQL para imprimir la

    ' Factura con todos los pedidos del mismo cliente.

    DoCmd.OpenReport cadNombreDocumento, acViewNormal, "SQL"

 'Se imprime la factura con los datos filtrados por la SQL anterior, y aquí es donde al imprimir, no surten efecto los criterios de filtro de la SQL. El informe-factura cuelga de otra consulta igual que la SQL pero sin ningún critero de filtro. Si le quito la consulta, no se imprime nada y si le pongo la SQL con los criterios de filtro como origen del registro, da error.

Muchas gracias, aunque sólo lo hayas leído.
Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 13015
Enlace directo a este mensaje Enviado: 23/Enero/2018 a las 17:40
Hola,

Centrandonos solo en la SQL (para el método de recorrer clientes y sus pedidos cada maestrillo tiene su librillo), yo haría una cosa bastante simple pero muy efectiva: quitaría casi todos los parentesis de la clausula HAVING dejando únicamente aquellos que no sean para "enmarcar" condiciones (vamos, el de la función DatePart

...HAVING (((tbPedidos.IdCliente)=" & Z & ") AND ((tbPedidos.Año) =" & intAño & ") AND ((tbPedidos.EmitidaFra)=False) AND ((DatePart(""m"",[FechaPedido]))=" & numMesBis & ")) ORDER...

quedaria como:

...HAVING tbPedidos.IdCliente=" & Z & " AND tbPedidos.Año =" & intAño & " AND tbPedidos.EmitidaFra = False AND DatePart(""m"",[FechaPedido])=" & numMesBis & " ORDER ...

Por otro lado pondria un punto de interrupción justo despues de esa sentencia para poder copiar la SQL generada y probarla en una nueva consulta para ver si obtenemos los resultados esperados.

un saludo
Xavi, un minyó de Terrassa

Mi web
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Enviado: 23/Enero/2018 a las 18:36
Gracias Xavi, he comprobado que, igual que antes de consultar, la SQL del código funciona. El problema para mi es que el informe no asume la SQL como fuente u orgien del registro. El código está en un módulo standard, y el informe cuelga de una consulta igual a la SQL pero sin criterios de filtro, entonces, el informe imprime todos los registros de todos los clientes, porque los criterios de filtro que tiene la SQL no se transmiten a la consulta de la que cuelga el informe, o dicho de otro modo, que la SQL del código no sustituye a la consulta de la que cuelga el informe. O de que forma, mediante el código, se pueden insertar los criterios de filtro en la consulta base del informe. He probado a poner en el código, tras el comando Docmd.OpenReport, el RecordSuource la SQL pero tampoco.
Muchas gracias, aunque sólo lo hayas leído.
Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 5755
Enlace directo a este mensaje Enviado: 23/Enero/2018 a las 19:14
Hola!

Creo que tienes que pasar la SQL en el OpenArgs de "Método DoCmd.OpenReport":

Tú pones:

DoCmd.OpenReport cadNombreDocumento, acViewNormal, "SQL"

debería ser

DoCmd.OpenReport cadNombreDocumento, acViewNormal,,,, "SQL"


Mira este hilo:

http://www.mvp-access.com/foro/seleccionar-consulta-a-ejecutar_topic83404.html


Editado por mounir - 23/Enero/2018 a las 19:15
Un Saludo.
Arriba
MexMan70 Ver desplegable
Colaborador
Colaborador


Unido: 17/Julio/2007
Localización: DarkSide
Estado: Sin conexión
Puntos: 9235
Enlace directo a este mensaje Enviado: 23/Enero/2018 a las 19:49
No es necesario pasar toda la SQL, solamente se pasa como criterio el filtro; mira en la ayuda de Access acerca de los argumentos de OpenReport

Saludos !
OneDrive: http://sdrv.ms/Vk6eJd
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 14:39
Hola amigos, he probado las soluciones de Xavi, Mounir y MexMan70 y no considera los criterios de filtro. De pruebas, tengo pedidos de tres clientes, y a la hora de imprimir la factura, la primera sale con todos los pedidos de todos los clientes, la segunda con los pedidos del segundo y del tercero, y la tercera con solo los pedidos del tercero. ¿Quizá el filtro debería estar en la consulta base del informe?, pero en ése caso, ¿cómo le paso a la consulta base del informe todos los criterios de filtro desde el módulo standard?. Tengo lo mismo en un form para imprimir los albaranes y funciona bien porque el dato de filtro lo toma del form donde está el código (módulo de clase, si no me equivoco), pero claro, la consulta base es una consulta filtro que toma el IdCliente del form.
Muchas gracias, aunque sólo lo hayas leído.
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 15:58
Hola nuevamente, también he probado las siguientes formas:

SQL = "SELECT Consulta1.* FROM Consulta1 WHERE (((Consulta1.IdCliente)=" & Z & ") AND ((DatePart(""m"",[FechaPedido])=" & numMesBis & ") AND ((Consulta1.Año)=" & intAño & ") AND ((Consulta1.EmitidaFra)=False));"


    cadNombreDocumento = "RptFacturaCorosaTRES"
    ' Informe Imprimir FacturaCorosaTRES, usa la consulta SQL para imprimir la
    ' Factura con todos los pedidos del mismo cliente.
    DoCmd.OpenReport cadNombreDocumento, acViewNormal, SQL
    
    DoCmd.OpenReport cadNombreDocumento, acViewNormal, , "tbPedidos.IdCliente=" & Z & " AND tbPedidos.Año =" & intAño & " AND tbPedidos.EmitidaFra=False" _
   & " AND DatePart(""m"",[FechaPedido])=" & numMesBis & ""

    DoCmd.OpenReport cadNombreDocumento, acViewNormal, , , , "tbPedidos.IdCliente=" & Z & " AND tbPedidos.Año =" & intAño & " AND tbPedidos.EmitidaFra=False" _
   & " AND DatePart(""m"",[FechaPedido])=" & numMesBis & ""

Y tampoco consigo que los criterios de filtro funcionen.
Muchas gracias, aunque sólo lo hayas leído.
Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 5755
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 16:16
Hola!

- Esta SQL funciona y filtra bien en una consulta?

- Una vez haya funcionado en vista de consulta, haz lo siguiente:-

DoCmd.OpenReport cadNombreDocumento, acViewNormal, , , ,SQL



Editado por mounir - 24/Enero/2018 a las 16:17
Un Saludo.
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 17:08
Gracias Mounir. En modo consulta funciona perfectamente, pero cuando la pongo en el módulo no filtra, aunque le he puesto los criterios concretos en lugar de las variables que los sustituyen.

SQL = "SELECT Consulta1.* FROM Consulta1 WHERE (((Consulta1.IdCliente)=2) AND ((Consulta1.Año)=2018) AND ((Consulta1.EmitidaFra)=False) AND ((Consulta1.Mes)=1));"


    cadNombreDocumento = "RptFacturaCorosaTRES"
    ' Informe Imprimir FacturaCorosaTRES, usa la consulta SQL para imprimir la
    ' Factura con todos los pedidos del mismo cliente.
    DoCmd.OpenReport cadNombreDocumento, acViewNormal, , , , SQL
    
Muchas gracias, aunque sólo lo hayas leído.
Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 5755
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 18:33
Hola!

y en el informe hay que poner en el evento al abrir:

Private Sub Report_Open(Cancel As Integer)

If Len(Me.OpenArgs) > 0 Then
    Me.RecordSource = Me.OpenArgs
End If

End Sub

Un Saludo.
Arriba
MexMan70 Ver desplegable
Colaborador
Colaborador


Unido: 17/Julio/2007
Localización: DarkSide
Estado: Sin conexión
Puntos: 9235
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 18:39
La sintaxis del Metodo OpenReport tiene una clausula llamada WhereCondicion, ahí es donde vas a aplicar tu filtro.

Los Argumentos del Método OpenReport son:
Nombre del Informe (Requerido)
View (Opcional)
FilterName (Opcional)
WhereCondition (Opcional - Expresión de cadena que es una cláusula WHERE de SQL válida sin la palabra WHERE)
WindowMode (Opcional)
OpenArgs (Opcional)

Dicho esto, puedes hacer lo siguiente:
* En tu reporte NO discriminas ningún registro, dicho de otra manera, NO usas la clausula Where para que puedes ver todos los registros.

Luego, en tu formulario donde desees lanzar el reporte preguntas por el o los filtros y los pasas en el argumento del Método OpenReport, por ejemplo:

DoCmd.OpenReport "Tu Reporte", acViewNormal,  , "IdCliente=" & Me.ElCliente & " AND [Año]=" & Me.ElAño & " AND EmitidaFra=" & Me.ControlEmitidaFra & " AND [Mes]=" & Me.ElMes

Espero que con esto se aclare tu panorama, lee nuevamente acerca de dichos argumentos en la ayuda de Access y si aún tienes dudas por aquí andamos...

Saludos !!
OneDrive: http://sdrv.ms/Vk6eJd
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Enviado: 24/Enero/2018 a las 18:54
¡¡¡Ahora sí!!!. Gracias a todos. El asunto se ha arreglado al poner en el Open del Informe lo último que me ha indicado Mounir.

If Len(Me.OpenArgs) > 0 Then
    Me.RecordSource = Me.OpenArgs
End If

End Sub

Todo lo demás lo estaba haciendo correctamente desde que me indicásteis lo del OpenArgs.

Nuevamente muchas gracias y se puede cerrar el hilo
Muchas gracias, aunque sólo lo hayas leído.
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 350
Enlace directo a este mensaje Enviado: 20/Marzo/2018 a las 17:29
Este hilo puede cerrarse
Muchas gracias, aunque sólo lo hayas leído.
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable