RED Días M idioma

Un usuario Pregunto ✅

Ritaf

Hola ,

tengo que crear KPI establecido sobre de sla de gestión de pedidos. Quiero calcular esos SLA en días hábiles en power Query (no Dax).

leí muchos propósitos a las soluciones, pero no lo hizo tener éxito en adoptarlo para mi archivo (porque un muy débil conocimiento del lenguaje M).

En un enlace a continuación es mi pbix archivo con 2 puntos por ejemplo, tal vez alguien me pueden explicar paso a paso como puedo I calcular en solo días laborables sin fines de semana ni festivos EndSaleTime-StartSale tiempo y/o

EndSupplyTime-StartSupply Tiempo o simplemente ponlo en mi pbix Archivo .

https://drive.google.com/drive/folders/1xQRM3C9q5uoTs47lYv7FoM5Y3vqZQy2l?usp=sharing

por favor no me envíen enlaces de preguntas y soluciones similares porque I leerlos

Muchas gracias,

Rita

jimmy801

En respuesta a Ritaf

Hola

Traté de acelerar mi versión. por lo tanto, si no tiene problemas de rendimiento con esta solución, la elegiría.

Esta solución es más lenta que la otra propuesta por @mcybulski. Pero si venimos a incluir vacaciones es más rápido

// fnNetWorkDays
(DateStart as date, DateEnd as date, optional Holidays as list) =>
let
    Switch = DateStart > DateEnd,
    StartDate = if Switch then DateEnd else DateStart,
    EndDate = if Switch then DateStart else DateEnd,
    WeekDaysInRange=
        (
            Duration.TotalDays
            (
                (   
                    EndDate-
                    (
                        StartDate
                        +Duration.From
                        (
                            Date.DayOfWeek
                            (
                                EndDate
                            )
                            -Date.DayOfWeek
                            (
                                StartDate
                            )
                        )
                    )
                )
            )
            /7*5
        )
        +Date.DayOfWeek
        (
            EndDate
        )
        -Date.DayOfWeek
        (
            StartDate
        )
        +1
        +
        (
            if Date.DayOfWeek
                (
                    StartDate
                )=0 
                then
                -1
                else
                0
        )
        +
        (
            if Date.DayOfWeek
                (
                    EndDate
                )=6
                then 
                -1 
                else
                0
        ),
    HolidaysInRange = if Holidays = null then {} else
    List.Select(Holidays, each StartDate <= _ and _ <= EndDate and Date.DayOfWeek(_, Day.Monday) <5 ),
    Result = (if Switch then -1 else 1) * ((WeekDaysInRange) - List.Count(HolidaysInRange))
in
    Result

// fnNetWorkDays2
(DateStart as date, DateEnd as date, optional Holidays as list) =>
let
    Switch = DateStart > DateEnd,
    StartDate = if Switch then DateEnd else DateStart,
    EndDate = if Switch then DateStart else DateEnd,
    HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays),
    CreateListDates =List.Buffer( List.Dates
    (
        StartDate,
        Duration.TotalDays
        (
            EndDate - StartDate
        )
        +1,
        #duration(1,0,0,0)
    )),

    ExcludeWeekend = List.Select
    (
        CreateListDates,
        each 
        Date.DayOfWeek
        (
            _,
            Day.Monday
        )
        <5
    ),

    ExcludeHoliday = 
    if Holidays = null then ExcludeWeekend else List.Difference
    (
        ExcludeWeekend,
        HolidayIntern
    ),
    Result = List.Count
    (
        ExcludeHoliday
    ),

    FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null
    
in
    FinalResult

Si esta publicación ayuda o resuelve su problema, por favor márquelo como solución.
Felicitaciones son agradables – gracias
Divertirse

Palanqueta

jimmy801

En respuesta a Ritaf

Oye

Justo ahora que publiqué ambas versiones … y esto te confundió 🙂 lo siento 🙂

// fnNetWorkDays2
(DateStart as date, DateEnd as date, optional Holidays as list) =>
let
    Switch = DateStart > DateEnd,
    StartDate = if Switch then DateEnd else DateStart,
    EndDate = if Switch then DateStart else DateEnd,
    HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays),
    CreateListDates =List.Buffer( List.Dates
    (
        StartDate,
        Duration.TotalDays
        (
            EndDate - StartDate
        )
        +1,
        #duration(1,0,0,0)
    )),

    ExcludeWeekend = List.Select
    (
        CreateListDates,
        each 
        Date.DayOfWeek
        (
            _,
            Day.Monday
        )
        <5
    ),

    ExcludeHoliday = 
    if Holidays = null then ExcludeWeekend else List.Difference
    (
        ExcludeWeekend,
        HolidayIntern
    ),
    Result = List.Count
    (
        ExcludeHoliday
    ),

    FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null
    
in
    FinalResult

invocarlo así

=intentar fn([Start],[End]) de lo contrario nulo

Si esta publicación ayuda o resuelve su problema, por favor márquelo como solución.
Felicitaciones son agradables – gracias
Divertirse

Palanqueta

jimmy801

En respuesta a Ritaf

😪😭

ohh .qué triste

jimmy801

Hola @Ritaf

Entiendo qué es exactamente lo que necesitas … ¿qué son sla? ¿Qué quieres calcular exactamente?

Si pudiera proporcionar algún ejemplo de datos con el resultado deseado con una descripción detallada del mismo o el objetivo final, ayudaría y sería apreciado.

por cierto, hay un archivo Power-BI guardado como .xlsx

Pasar un buen rato

Palanqueta

Ritaf

En respuesta a jimmy801

Hola Jimmy,

Solo quiero calcular una diferencia entre 2 fechas sin fines de semana y/o días festivos, para este estudio cse no importa cuál, solo necesito entender el código. Y gracias por prestar atención, puse un archivo pbix.

jimmy801

En respuesta a Ritaf

Oye
Diferencia en días supongo
Palanqueta

Ritaf

En respuesta a jimmy801

Hola ,

Días (horas también es bueno saberlo)

jimmy801

En respuesta a Ritaf

Hola

esta función devuelve la diferencia en horas, excluyendo los fines de semana.

Tienes que pasar starttime y endtime. Puede pasar opcionalmente una lista con días festivos para excluirlos a

(StartTime as datetime, EndTime as datetime, ListHoliday as nullable list) as number =>
let
    //StartTime = #datetime(2019,12,3,8,00,00),
    //EndTime = #datetime(2019, 12, 8, 8, 0, 0),
    //ListHoliday = {"03.12.19", "04.12.19"},
    ListHolidayCheck = if ListHoliday = null then {} else ListHoliday,
    ListHolidayInternal = List.Transform(ListHolidayCheck, each Date.From(_)),
    DurationInHours = (Number.From(EndTime)-Number.From(StartTime))*24,
    DateTimesFromStartEnd = List.DateTimes(StartTime, DurationInHours, #duration(0,1,0,0)),
    FilterHolidays = List.Transform(DateTimesFromStartEnd, each if List.Contains(ListHolidayInternal, Date.From(_))= true then null else _),
    TableWithDateTime = #table({"DateTime"}, List.Zip({FilterHolidays})),
    #"Added Custom" = Table.AddColumn(TableWithDateTime, "Hours", each 1),
    #"Inserted Day of Week" = Table.AddColumn(#"Added Custom", "Day of Week", each Date.DayOfWeek([DateTime], Day.Monday), Int64.Type),
    #"Filtered Rows" = Table.SelectRows(#"Inserted Day of Week", each ([Day of Week] < 5)),
    HoursSum = List.Sum(#"Filtered Rows"[Hours])
in
    HoursSum

Si esta publicación ayuda o resuelve su problema, por favor márquelo como solución.
Felicitaciones son agradables – gracias
Divertirse

Palanqueta

Ritaf

En respuesta a jimmy801

Hola, esta es una de las soluciones que probé y me sale un error:

Expression.Error: no podemos convertir el valor nulo al tipo DateTime.
Detalles:
Valor=
Tipo=[Type]

¿Cómo puedo solucionar eso?

jimmy801

En respuesta a Ritaf

Hola
Tal vez esté invocando la función con nulo en el primer o segundo parámetro o intente pasar nulo como tercer parámetro
Palanqueta

Ritaf

En respuesta a jimmy801

Solo estoy eligiendo mi columna startDate, End DAte y holidys. Cómo puedo cambiar esto?

Ritaf

En respuesta a Ritaf

Hola de nuevo,

jugué con esto y vi que tengo valores nulos de suma en startDate, lo reemplacé con 01/01/01 01:00:00 parece funcionar pero ahora creo que tengo algún problema con las vacaciones, veo que este cálculo toma un mucho tiempo y veo un mensaje extraño (adjunto) y estos gigabytes continúan creciendoCapturar.JPG

mcybulski

En respuesta a Ritaf

La siguiente función adopta un enfoque diferente al problema. Debe ser rápido y pequeño porque no genera fechas.

(DateStart como fecha, DateEnd como fecha, festivos opcionales como lista) =>
dejar
Cambiar = Fecha de inicio > Fecha de finalización,
StartDate = si cambia luego DateEnd else DateStart,
EndDate = si Switch entonces DateStart else DateEnd,
WeekDaysInRange=
(Duración.TotalDays((EndDate-(StartDate+Duration.From(Date.DayOfWeek(EndDate)-Date.DayOfWeek(StartDate)))))/7*5)
+Date.DayOfWeek(EndDate)-Date.DayOfWeek(StartDate)+1
+(if Date.DayOfWeek(StartDate)=0 luego -1 más 0)+(if Date.DayOfWeek(EndDate)=6 luego -1 más 0),
HolidaysInRange = si Holidays = null, entonces {} else
List.Select(Vacaciones, cada StartDate <= _ y _ <= EndDate y Date.DayOfWeek(_, Day.Monday) <5 ),
Resultado = (if Switch entonces -1 else 1) * ((WeekDaysInRange) – List.Count(HolidaysInRange))
en
Resultado

jimmy801

En respuesta a mcybulski

Hola

este es sin duda el mejor enfoque, ya que no tengo que crear ninguna lista que se ralentice con seguridad.

Le he dado una prueba y parece que algo no está del todo bien. mira esta tablagrafik.png

Que tenga un lindo día

Palanqueta

mcybulski

En respuesta a jimmy801

Hola Jimmy,

Lamento tardar tanto en responder, pero estoy de vacaciones con acceso limitado a la red.

La función está funcionando para mí. ¿Te importaría publicar el código con el que lo llamaste para que pueda ver las diferencias?

Gracias,

Miguel

Ritaf

En respuesta a jimmy801

¿Puedo editar la lista de días festivos de alguna manera? Ahora se ve asíCapturar.JPG

jimmy801

En respuesta a Ritaf

Hola

Traté de acelerar mi versión. por lo tanto, si no tiene problemas de rendimiento con esta solución, la elegiría.

Esta solución es más lenta que la otra propuesta por @mcybulski. Pero si venimos a incluir vacaciones es más rápido

// fnNetWorkDays
(DateStart as date, DateEnd as date, optional Holidays as list) =>
let
    Switch = DateStart > DateEnd,
    StartDate = if Switch then DateEnd else DateStart,
    EndDate = if Switch then DateStart else DateEnd,
    WeekDaysInRange=
        (
            Duration.TotalDays
            (
                (   
                    EndDate-
                    (
                        StartDate
                        +Duration.From
                        (
                            Date.DayOfWeek
                            (
                                EndDate
                            )
                            -Date.DayOfWeek
                            (
                                StartDate
                            )
                        )
                    )
                )
            )
            /7*5
        )
        +Date.DayOfWeek
        (
            EndDate
        )
        -Date.DayOfWeek
        (
            StartDate
        )
        +1
        +
        (
            if Date.DayOfWeek
                (
                    StartDate
                )=0 
                then
                -1
                else
                0
        )
        +
        (
            if Date.DayOfWeek
                (
                    EndDate
                )=6
                then 
                -1 
                else
                0
        ),
    HolidaysInRange = if Holidays = null then {} else
    List.Select(Holidays, each StartDate <= _ and _ <= EndDate and Date.DayOfWeek(_, Day.Monday) <5 ),
    Result = (if Switch then -1 else 1) * ((WeekDaysInRange) - List.Count(HolidaysInRange))
in
    Result

// fnNetWorkDays2
(DateStart as date, DateEnd as date, optional Holidays as list) =>
let
    Switch = DateStart > DateEnd,
    StartDate = if Switch then DateEnd else DateStart,
    EndDate = if Switch then DateStart else DateEnd,
    HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays),
    CreateListDates =List.Buffer( List.Dates
    (
        StartDate,
        Duration.TotalDays
        (
            EndDate - StartDate
        )
        +1,
        #duration(1,0,0,0)
    )),

    ExcludeWeekend = List.Select
    (
        CreateListDates,
        each 
        Date.DayOfWeek
        (
            _,
            Day.Monday
        )
        <5
    ),

    ExcludeHoliday = 
    if Holidays = null then ExcludeWeekend else List.Difference
    (
        ExcludeWeekend,
        HolidayIntern
    ),
    Result = List.Count
    (
        ExcludeHoliday
    ),

    FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null
    
in
    FinalResult

Si esta publicación ayuda o resuelve su problema, por favor márquelo como solución.
Felicitaciones son agradables – gracias
Divertirse

Palanqueta

Ritaf

En respuesta a jimmy801

¿Dónde ves otra consulta?Capturar.JPG

jimmy801

En respuesta a Ritaf

Hola @Ritaf

ahora lo cambiaste (en la otra captura de pantalla, la consulta no comienza en el).

Sin embargo, debe cambiar «/fnNetworkdays» por «//fnNetworkdays», porque esto es solo un comentario y, por lo tanto, debe colocar el doble «https://community.powerbi.com/».

Todos mejor

Palanqueta

Ritaf

En respuesta a jimmy801

Hola,

Traté de usar un código y ahora hay un error de sintaxis.Capturar.JPG😭

Ritaf

En respuesta a Ritaf

hola jimmy,

Muchas gracias por tus intentos de ayudar,

El código es realmente no funciona.

y el indicador de error solo me envía al bolígrafo rojo.

Capturar.JPG

Ritaf

En respuesta a Ritaf

ooooooooh este código es para más de las 1 opciones de solución?😳

Ritaf

En respuesta a Ritaf

Syntex ahora ve bien, pero todavía tengo un problema debido a las celdas vacías al inicio. ¿Quizás haya algún truco para pasarlas?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *