** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - [Resuelto] A vueltas con los días de febrero
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerrado[Resuelto] A vueltas con los días de febrero

 Responder Responder
Autor
Mensaje
zelarra Ver desplegable
Habitual
Habitual


Unido: 21/Octubre/2020
Localización: España
Estado: Sin conexión
Puntos: 122
Enlace directo a este mensaje Tema: [Resuelto] A vueltas con los días de febrero
    Enviado: 30/Octubre/2020 a las 21:46
Buenas noches.

En una consulta, para sacar el promedio, necesita sacar el número de días de cada mes y multiplicarlo por el número de años transcurridos. Me funciona todo bien, a excepción de febrero cuando el año es bisiesto:

https://www.dropbox.com/s/b4ymepch26bpcy1/ScreenShot001.jpg?dl=0

Estas son las funciones para calcular los años y los días transcurridos.

Public Function AñosTranscurridos(Fecha As Date) As Long
    AñosTranscurridos = DateDiff("yyyy", DateSerial(IIf(Month(Fecha) = 4, 2017, 2018), Month(Fecha), 1), DateSerial(Year(Date), Month(Fecha), Day(Date)), vbMonday) + IIf(Month(Date) >= Month(Fecha), 1, 0)
End Function

Public Function DiasTranscurridos(Fecha As Date) As Long
    DiasTranscurridos = DateDiff("d", DateSerial(IIf(Month(Fecha) = 4, 2017, 2018), Month(Fecha), 1), DateSerial(Year(Date), Month(Fecha), Day(Date)), vbMonday) + IIf(Month(Date) >= Month(Fecha), 1, 0)
End Function

Necesito que solo me aparezca un único registro de febrero, pero no sé cómo poder solucionarlo.

Espero que me podáis ayudar.

Gracias.


Editado por zelarra - 01/Noviembre/2020 a las 16:28
Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 14720
Enlace directo a este mensaje Enviado: 31/Octubre/2020 a las 21:59
Aparte de no entender que, si es mes de abril, tome año 2017 o 2018, creo que lo que pretendes es calcular cuantos días "promedio" hay en el periodo para cada mes.
Obviamente todos los meses tienen la misma cantidad de días excepto febrero.

Yo lo enfocaría como un bucle para recorrer los distintos meses de febrero del periodo y sumaría los días que tiene. Una división me dice el promedio de días. Algo así:

Function PromedioDiasMes(dtmFecha As Date, intNumMes As Integer)
    Dim intContador     As Integer
    Dim intNumDiasMes   As Integer
    
    Do
        If Month(dtmFecha) = intNumMes Then
            intNumDiasMes = intNumDiasMes + Day(DateSerial(Year(dtmFecha), Month(dtmFecha) + 1, 0))
            intContador = intContador + 1
        End If
        dtmFecha = DateAdd("m", 1, dtmFecha)
    Loop While dtmFecha < Date
    
    PromedioDiasMes = intNumDiasMes / intContador
End Function

Probablemente se puede optimizar pero es la primera opción que se me ha ocurrido.

Un saludo
Xavi, un minyó de Terrassa

Mi web
Arriba
zelarra Ver desplegable
Habitual
Habitual


Unido: 21/Octubre/2020
Localización: España
Estado: Sin conexión
Puntos: 122
Enlace directo a este mensaje Enviado: 31/Octubre/2020 a las 22:10
Hola, Xavi.

Lo que pretendo calcular es el promedio de días de un mes que ha sucedido un evento a lo largo de x años, no sé si me explico. Por ejemplo

Febrero'18 --> 7 veces --> 7/28 (7 veces en 28 días que tiene el mes de febrero de 2018)
Febrero'19 --> 5 veces --> 5/28 (5 veces en 28 días que tiene el mes de febrero de 2019)
Febrero'20 --> 9 veces --> 9/29 (9 veces en 28 días que tiene el mes de febrero de 2020)

Por tanto, el promedio sería (7+5+9)/(3*(28+28+29)) --> Sumo todas las veces y lo divido entre los años transcurridos (3) multiplicado por la suma de los días. Por este motivo tengo el problema, porque me desdobla el mes de febrero.

No sé si me explico.


Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 14720
Enlace directo a este mensaje Enviado: 31/Octubre/2020 a las 22:26
¿Has probado la función?
La puedes adaptar para que, en lugar de devolver el promedio de días de un mes, devuelva la cantidad de días. Simplemente no dividas por el contador y tendrás el resultado (tomando tu ejemplo) de 28+28+29 = 85

¿No te vale?

Un saludo
Xavi, un minyó de Terrassa

Mi web
Arriba
zelarra Ver desplegable
Habitual
Habitual


Unido: 21/Octubre/2020
Localización: España
Estado: Sin conexión
Puntos: 122
Enlace directo a este mensaje Enviado: 31/Octubre/2020 a las 22:40
Vale. Me ayuda, pero me da otro problema ahora:

https://www.dropbox.com/s/w7bhclh6q7ojt3o/ScreenShot002.jpg?dl=0

Tengo que dividir el número de veces (que tendría que sumarlo), entre la multiplicación de los años transcurridos (lo calculo mediante una función y está bien); y el máximo de la columna promediodiasmes.

No sé cómo hacerlo sin tener que crear otra consulta.

Tengo que hacerlo por consulta pues lo necesito para un gráfico, y no quiero andar creando consulta sobre consulta porque luego me tarda mucho en abrir el gráfico.

Muchas gracias, Xavi


Editado por zelarra - 31/Octubre/2020 a las 22:43
Arriba
zelarra Ver desplegable
Habitual
Habitual


Unido: 21/Octubre/2020
Localización: España
Estado: Sin conexión
Puntos: 122
Enlace directo a este mensaje Enviado: 31/Octubre/2020 a las 22:43
SELECT MesEnTexto([Fecha]) AS Mes, VecesDoloresDeCabeza([Fecha]) AS Veces, AñosTranscurridos([Fecha]) AS AñosTranscurridos, Month([Fecha]) AS Mes1, Max(PromedioDiasMes([Fecha],Month([Fecha]))) AS PromedioDiasMes
FROM TDoloresDeCabeza
GROUP BY MesEnTexto([Fecha]), VecesDoloresDeCabeza([Fecha]), AñosTranscurridos([Fecha]), Month([Fecha])
ORDER BY Month([Fecha]);

Este es el SQL de la consulta.
Arriba
zelarra Ver desplegable
Habitual
Habitual


Unido: 21/Octubre/2020
Localización: España
Estado: Sin conexión
Puntos: 122
Enlace directo a este mensaje Enviado: 01/Noviembre/2020 a las 00:12
A ver, estoy haciendo pruebas. Con este código:

Function PromedioDiasMes(dtmFecha As Date, intNumMes As Integer)
    Dim intNumDiasMes   As Integer
    Dim intVeces   As Integer
    
    Do
        If Month(dtmFecha) = intNumMes Then
            intNumDiasMes = intNumDiasMes + Day(DateSerial(Year(dtmFecha), Month(dtmFecha) + 1, 0))
        End If
        dtmFecha = DateAdd("m", 1, dtmFecha)
    Loop While dtmFecha < Date
    
    PromedioDiasMes = intNumDiasMes
End Function

Y esta consulta

SELECT MesEnTexto([Fecha]) AS Mes, PromedioDiasMes([Fecha],Month([Fecha])) AS PromedioDiasMes, Month([Fecha]) AS Mes1
FROM TDoloresDeCabeza
GROUP BY MesEnTexto([Fecha]), PromedioDiasMes([Fecha],Month([Fecha])), Month([Fecha])
ORDER BY Month([Fecha]);

Me muestra la siguiente consulta:

https://www.dropbox.com/s/ocmqfbd2gvbjey8/ScreenShot003.jpg?dl=0

Como ves, me salen tantos años como haya, procediendo en cada uno a la suma del anterior. Pero no sé cómo conseguir que me muestre el valor máximo. Si pongo en PromedioDiasMes máx, en abril no me muestra el 120, solo 90 (esto de abril es porque de 2017 solo tengo registros de ese mes de abril).

Luego, estoy intentando aplicar la función que me has pasado para calcular el número de veces. Para que me entiendas, en la tabla tengo una fecha y un campo Sí/No. Yo lo que hago es agregar una fecha y marcar como Sí ese día. Entonces, que saber cuántos Síes ha habido en el mes.

Gracias.
Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 6479
Enlace directo a este mensaje Enviado: 01/Noviembre/2020 a las 12:09
Hola!

Pienso que se puede solucionar con dos consultas:-

Crear primera consulta para calcular los años y días.
Segunda consulta incluye la primera consulta y la tabla en cuestión y calcular el promedio.
Un Saludo.
Arriba
zelarra Ver desplegable
Habitual
Habitual


Unido: 21/Octubre/2020
Localización: España
Estado: Sin conexión
Puntos: 122
Enlace directo a este mensaje Enviado: 01/Noviembre/2020 a las 12:11
Pues más o menos eso es lo que he hecho:

Public Function Veces(miMes As Integer) As Integer 'En uso
Dim Veces1 As String
    Veces1 = "SELECT Sum(IIf([SiNo]=-1,1,0)) AS Veces, Month([Fecha]) AS Mes1" _
            & " FROM TDoloresDeCabeza" _
            & " WHERE Month([Fecha]) = " & miMes & "" _
            & " GROUP BY Month([Fecha])" _
            & " ORDER BY Month([Fecha])"
    Set rst = CurrentDb.OpenRecordset(Veces1)
    If Not (rst.EOF And rst.BOF) Then
         Veces = rst("Veces")
    End If
    rst.Close
    Set rst = Nothing
End Function

Public Function Dias(miMes As Integer) As Integer 'En uso
Dim Dias1 As String
    Dias1 = "SELECT Month([Fecha]) AS Mes, DiasDelMes([Fecha]) AS Dias, AñosTranscurridos([Fecha]) AS Años" _
            & " FROM TDoloresDeCabeza" _
            & " WHERE Month([Fecha]) = " & miMes & "" _
            & " GROUP BY Month([Fecha]), DiasDelMes([Fecha]), AñosTranscurridos([Fecha])" _
            & " ORDER BY Month([Fecha])"
Dim Dias2 As String
    Dias2 = "SELECT Mes, Sum([Años]*[Dias]) AS SumaDias" _
                & " FROM (" & Dias1 & ") As CDias" _
                & " GROUP BY Mes"
    Set rst = CurrentDb.OpenRecordset(Dias2)
    If Not (rst.EOF And rst.BOF) Then
         Dias = rst("SumaDias")
    End If
    rst.Close
    Set rst = Nothing
End Function

Public Function PromedioPorcentaje(miMes As Integer) As Double 'En uso
    PromedioPorcentaje = Veces(miMes) / Dias(miMes)
End Function

Y con esto me da el resultado que yo quiero.

¡Muchas gracias!
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable