Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Power BI is turning 10! Let’s celebrate together with dataviz contests, interactive sessions, and giveaways. Register now.

Reply
Syndicate_Admin
Administrator
Administrator

Cambiar las fechas en función de los valores y requisitos comunes

Hola comunidad de Power BI,

Espero que esto te encuentre bien.

Tengo un informe que contiene hitos o comprobaciones que debo completar por curso. Estas comprobaciones se programan actualmente en función de fechas específicas que se calculan mediante SQL en función de una comprobación de la primera clase de ese curso específico. Cada curso tiene 7 verificaciones en este orden: Syllabus Received, Course Built, Assessment Checks, Programme Checks, EdTech Checks, Library Checks, Course Published y First Lecture.

A partir del 05 de agosto de 2025, las verificaciones se modifican para incluir 2 semanas entre el plan de estudios recibido y el curso construido. Esto es un aumento de 1 semana antes de esa fecha. Todos los cambios que necesito hacer antes deben realizarse solo para los hitos posteriores al 05 de agosto de 2025. Los hitos anteriores deben permanecer exactamente como están.

He buscado en línea, he realizado algunas pruebas y he utilizado la IA para hacer lo siguiente:

1. Cree una tabla de fechas que se utilizará para la inteligencia de tiempo. esta tabla contiene fechas procedentes de la API de días festivos del Reino Unido para incorporar la lógica de días festivos para todas las fechas disponibles en la tabla. Se basa en 2 columnas: IsHoliday - TRUE/FALSE y Holiday Name - Text.

2. Se fusionó la tabla de verificaciones, que incluye todos los hitos de cada curso, con la tabla de fechas. A continuación, expandí la tabla de comprobaciones para incluir las columnas IsHoliday, Holiday Name e IsWeekend de la tabla de fechas.

3. Usando las columnas extendidas en la tabla de verificaciones, creé una columna calculada en Power Query llamada IsFutureDate - TRUE/FALSE. esta columna marca todas las fechas desde el 05 de agosto de 2025 en adelante, como VERDADERO.

4. También creé una columna calculada en DAX para ajustar las fechas de vencimiento a las nuevas. esta columna se denomina AdjustedDueDate (consulte el código que se proporciona a continuación como referencia). Sin embargo, este código actualmente es un poco defectuoso, ya que después de realizar un ajuste, resta un día adicional, que no es el resultado deseado. Por ejemplo, cambia de sábado a viernes y, a continuación, resta 1 día adicional a jueves.

5. También creé otra columna calculada en DAX para marcar todos los días libres como VERDADERO y todo lo demás como FALSO (consulte el código proporcionado a continuación como referencia).

Necesito ayuda para implementar alguna lógica de cambio de fecha en mi conjunto de datos para cambiar las fechas de AdjustedDueDate a nuevas fechas en función de algunas restricciones. El siguiente es el resultado deseado:

1. Me gustaría cambiar todos los hitos que caigan en fines de semana y días festivos (Inglaterra y Gales) al primer día laborable. Por ejemplo, si un hito cae en el domingo 14 de marzo de 2025, cámbielo a viernes 12 de marzo de 2025. Y para los hitos que caen en días como el Lunes de Pascua, muévelos al jueves de la semana anterior, antes del Viernes Santo. esta lógica se implementa mediante la columna calculada AdjustedDueDate, pero el código resta un día adicional después de haber realizado los cambios adecuados. quiero que NO reste un día adicional y me asegure de que el cambio se ajuste solo al nivel del primer día hábil, y eso es todo.

2. Hay un "período de descanso" específico durante el cual me gustaría que los hitos que caigan durante ese tiempo se actualicen en consecuencia. Este período de descanso es desde el lunes de la segunda semana de diciembre hasta el 01 de enero de cada año. He incluido esta lógica con la columna calculada IsOffPeriod, que marca todo lo que hay después del último día laborable del primer día de la semana de diciembre al 1 de enero (inclusive).

Los cambios que necesito hacer durante este tiempo son:

i. mover la fecha de vencimiento del hito al último día hábil de la primera semana de diciembre

ii. si el hito es Curso publicado, actualice otros hitos del mismo curso de la siguiente manera

- mover las comprobaciones de evaluación, las comprobaciones de tecnología educativa, las comprobaciones de programa y las comprobaciones de biblioteca a 7 días antes del nuevo hito de publicación del curso del mismo curso.

- mover el curso creado a 7 días antes del nuevo hito de verificaciones de evaluación del mismo curso.

- mover el plan de estudios recibido a 14 días antes del nuevo hito de curso creado del mismo curso.

iii. si el hito es Curso Construido, mueva el hito de Syllabus Received del mismo curso a 14 días antes.

Espero que todo eso haya tenido sentido. Además, he proporcionado los fragmentos de código de las 2 columnas calculadas en la tabla de comprobaciones , un archivo .pbix con un informe de muestra para mostrar cómo se vinculan los datos y una hoja de c.... He resaltado en verde todos los hitos que han cambiado, para que puedas ver qué ha cambiado. Notarás que hay varios cursos con 7 hitos cada uno, y solo cuando una fecha de vencimiento cae en fin de semana, banco o día festivo, o un período libre, se aplican los cambios.

A modo de referencia:

I. Cada curso tiene 7 hitos

ii. los hitos están en un orden específico desde el plan de estudios recibido, el curso construido, las verificaciones de evaluación, las verificaciones de programa, las verificaciones de biblioteca, las verificaciones de tecnología educativa, el curso publicado y la primera conferencia.

iii. el número de días de diferencia entre los hitos es El programa de estudios recibido es 14 días antes de la creación del curso, que es 7 días antes de las verificaciones de evaluación, tecnología educativa, biblioteca y programa (todo el mismo día), que son 7 días antes de la publicación del curso, y eso es 21 días antes de la primera conferencia.

iv. observará en el archivo de resultados deseado que un curso como CD51 J SPR26 tiene una fecha de recepción del programa de estudios que no cae en fin de semana, día festivo o festivo, ni período libre. sin embargo, se ha actualizado antes de que se actualizaran todos los hitos anteriores del curso publicado.

FRAGMENTOS DE CÓDIGO:

El siguiente código es para la columna calculada en la tabla de cheques para ajustar las fechas de vencimiento de fines de semana y días festivos al primer día hábil.

AdjustedDueDate =
VAR Fecha original = Hitos[Fecha de vencimiento]
VAR IsFuture = Hitos[IsFutureDate]
VAR IsWeekend =
DÍA LABORABLE(Fecha original, 2) EN {6, 7}
VAR WeekendAdjustedDate =
INTERRUPTOR(
VERDADERO(),
DÍA LABORABLE(Fecha original, 2) = 6, Fecha original - 1, -- Sábado → Viernes
DÍA LABORABLE(Fecha original, 2) = 7, Fecha original - 2, -- Domingo → Viernes
Fecha original
)
VAR IsHoliday = Hitos[IsHoliday]
VAR FinalAdjustedDate =
SI(
IsHoliday && WeekendAdjustedDate = Fecha original,
Fecha original - 1,
WeekendAdjustedDate
)
DEVOLUCIÓN
SI(IsFuture, FinalAdjustedDate, Fecha original)
########################
El código siguiente es para una columna calculada en la tabla de comprobaciones para identificar todos los días durante el período de inactividad
IsOffPeriod =
VAR AdjDueDate = 'Hitos'[Fecha de vencimiento ajustada]
VAR CutoffDate (Fecha de corte) = FECHA(2025, 8, 5)

-- Si la fecha es anterior al límite, devuelva FALSE (o mantenga la lógica existente si es necesario)
DEVOLUCIÓN
SI(
AdjDueDate < CutoffDate (Fecha de corte),
FALSO,
VAR Vencimiento = AÑO(AdjDueDate)
VAR DueMonth = MES(AdjDueDate)

-- Determinar el año de anclaje para el período de inactividad
VAR Año de anclaje = SI(DueMonth = 1, Vencimiento - 1, Vencimiento)

-- Último día hábil de la primera semana de diciembre (5 de diciembre)
VAR Dic 5 = FECHA(Año de anclaje, 12, 5)
VAR StartOfOffPeriod =
INTERRUPTOR(
DÍA LABORABLE(Dic 5, 2),
6, Dic 5 - 1, Sábado → Viernes
7, Dic 5 - 2, Domingo → Viernes
Dic 5 Día laborable
)

-- Fin del período de descanso: 1 de enero del año siguiente
VAR EndOfOffPeriod = FECHA(Año de anclaje + 1, 1, 1)

DEVOLUCIÓN
SI(
AdjDueDate >= StartOfOffPeriod && AdjDueDate <= EndOfOffPeriod,
VERDADERO,
FALSO
)
)
########################
Por favor, hágamelo saber en caso de que haya alguna otra información que pueda proporcionar que pueda ayudar con la resolución de esta consulta

Saludos

Mrisho.

1 ACCEPTED SOLUTION

@v-sdhruv,

Gracias por proporcionar esta solución.

Cuando lo implementé, funcionó hasta cierto punto, sin embargo, hubo algunas fechas que se mantuvieron sin cambios. Siguiendo los consejos que me diste y la sugerencia original de @GrowthNatives, personalicé aún más tus aportaciones y las mías utilizando Deepseek AI y finalmente logré hacer los ajustes finales que necesitaba.

Para beneficio de los demás, a continuación se muestra el código más reciente que se actualiza en la columna calculada "CascadeAdjustedDueDate ". Esto es lo que incorpora todas las sugerencias y aportaciones para finalizar la lógica que necesitaba.

Correct Due Date = 
VAR ThisMilestone = Milestones[Milestone]
VAR CurrentCourse = Milestones[CourseKey]
VAR FinalPubDate = RELATED(CoursePublishedDates[CoursePublishedDate])
VAR FinalCourseBuiltDate = RELATED(CourseBuiltDates[CourseBuiltAdjusted])
VAR IsCurrentMilestoneOffPeriod = Milestones[IsOffPeriod]
VAR OriginalDueDate = Milestones[FinalDueDate]
VAR OriginalDueYear = YEAR(OriginalDueDate)
VAR OriginalDueMonth = MONTH(OriginalDueDate)

// Determine if date is in December or January off-period
VAR IsDecOffPeriod = OriginalDueMonth = 12
VAR IsJanOffPeriod = OriginalDueMonth = 1

// Calculate correct adjustment date
VAR AdjustedDecDate = 
    IF(
        IsJanOffPeriod,
        DATE(OriginalDueYear - 1, 12, 5), // Jan 2026 → Dec 2025
        DATE(OriginalDueYear, 12, 5)      // Dec 2025 stays in 2025
    )

VAR SecondWeekDecMonday = DATE(YEAR(AdjustedDecDate), 12, 8)
VAR OffPeriodEnd = DATE(YEAR(AdjustedDecDate) + IF(IsJanOffPeriod, 0, 1), 1, 1)
VAR IsPubDateOffPeriod = LOOKUPVALUE(Milestones[IsOffPeriod], Milestones[Milestone], "Course Published", Milestones[CourseKey], CurrentCourse)
VAR SyllabusLogicStartDate = DATE(2025, 8, 5)

// Adjusted publication date
VAR AdjustedPubDate = 
    IF(
        IsPubDateOffPeriod,
        AdjustedDecDate,
        FinalPubDate
    )

// Check if any check milestones are in off period
VAR HasCheckMilestonesInOffPeriod =
    COUNTROWS(
        FILTER(
            FILTER(
                Milestones,
                Milestones[CourseKey] = CurrentCourse &&
                (Milestones[Milestone] = "Assessment Checks" ||
                 Milestones[Milestone] = "EdTech Checks" ||
                 Milestones[Milestone] = "Library Checks" ||
                 Milestones[Milestone] = "Programme Checks") &&
                Milestones[IsOffPeriod] = TRUE
            ),
            TRUE()
        )
    ) > 0

// Calculate adjusted dates
VAR AdjustedCourseBuiltDate = 
    IF(
        ThisMilestone="Course Built",
        IF(
            IsPubDateOffPeriod,
            AdjustedPubDate - 14,
            IF(
                IsCurrentMilestoneOffPeriod,
                IF(
                    HasCheckMilestonesInOffPeriod,
                    AdjustedDecDate - 7,
                    AdjustedDecDate
                ),
                FinalCourseBuiltDate
            )
        ),
        FinalCourseBuiltDate
    )

VAR AdjustedSyllabusReceivedDate = 
    IF(
        ThisMilestone="Syllabus Received",
        IF(
            FinalPubDate >= SyllabusLogicStartDate,
            IF(
                IsPubDateOffPeriod,
                AdjustedPubDate - 28,
                AdjustedCourseBuiltDate - 14
            ),
            OriginalDueDate
        ),
        BLANK()
    )

// Base calculation
VAR BaseDate =
    SWITCH(
        TRUE(),
        ThisMilestone="Assessment Checks", AdjustedPubDate - 7,
        ThisMilestone="Programme Checks", AdjustedPubDate - 7,
        ThisMilestone="Library Checks", AdjustedPubDate - 7,
        ThisMilestone="EdTech Checks", AdjustedPubDate - 7,
        ThisMilestone="Course Built", AdjustedCourseBuiltDate,
        ThisMilestone="Syllabus Received", AdjustedSyllabusReceivedDate,
        OriginalDueDate
    )

// Final adjustment
VAR AdjustedDate =
    IF(
        IsCurrentMilestoneOffPeriod,
        SWITCH(
            TRUE(),
            NOT(IsPubDateOffPeriod) && HasCheckMilestonesInOffPeriod && 
            (ThisMilestone="Assessment Checks" || 
             ThisMilestone="EdTech Checks" || 
             ThisMilestone="Library Checks" || 
             ThisMilestone="Programme Checks"),
            AdjustedDecDate,
            BaseDate
        ),
        BaseDate
    )

// Final validation
VAR ProposedDate = 
    IF(
        ThisMilestone="First Lecture",
        OriginalDueDate,
        AdjustedDate
    )

VAR IsProposedDateInOffPeriod = 
    ProposedDate >= SecondWeekDecMonday && 
    ProposedDate <= OffPeriodEnd

RETURN
    IF(
        IsProposedDateInOffPeriod,
        OriginalDueDate,
        ProposedDate
    )

View solution in original post

5 REPLIES 5
Syndicate_Admin
Administrator
Administrator

Hola @iammrishoabeid ,
¿Solo quería verificar si tuvo la oportunidad de revisar las sugerencias proporcionadas?
Si la respuesta ha abordado su consulta, acéptela como una solución y dé un 'Felicitaciones' para que otros miembros puedan encontrarla fácilmente.
Gracias

Syndicate_Admin
Administrator
Administrator

Hola @iammrishoabeid ,

El problema al que se enfrenta es que los hitos CourseBuilt y Syllabus Received no se cascan en cascada correctamente porque dependen de valores ya ajustados dentro de la misma tabla y DAX no permite dependencias recursivas en columnas calculadas.
1.Agregue la tabla de fechas de CourseBuilt:
CourseBuiltDates =
ADDCOLUMNS(
RESUMIR(Hitos, Hitos[CourseKey]),
"CourseBuiltAdjusted",
CALCULAR(
MAX(Hitos[CascadeAdjustedDueDate]),
Hitos[Hito] = "Curso construido"
)
)

2. Crear una relación:

Milestones[CourseKey] --> CourseBuiltDates[CourseKey]

3.A continuación, actualice la lógica de CascadeAdjustedDueDate-

CascadeAdjustedDueDate =
VAR ThisMilestone = Hitos[Hito]
VAR FinalPubDate = RELATED(CoursePublishedDates[CoursePublishedDate])
VAR FinalCourseBuiltDate = RELATED(CourseBuiltDates[CourseBuiltAdjusted])

VAR NewDate =
INTERRUPTOR(
VERDADERO(),
ThisMilestone IN {"Comprobaciones de evaluación", "Comprobaciones de programa", "Comprobaciones de biblioteca", "Comprobaciones de tecnología educativa"}, FinalPubDate - 7,
ThisMilestone="Curso construido", FinalPubDate - 14,
ThisMilestone="Syllabus Received", FinalCourseBuiltDate - 14,
Hitos[FinalDueDate]
)
DEVOLUCIÓN
SI(
Hitos[IsOffPeriod],
NewDate,
Hitos[FinalDueDate]
)

¡Espero que esto ayude!
Si la respuesta ha abordado su consulta, acéptela como una solución y dé un 'Felicitaciones' para que otros miembros puedan encontrarla fácilmente.
¡Gracias!

@v-sdhruv,

Gracias por proporcionar esta solución.

Cuando lo implementé, funcionó hasta cierto punto, sin embargo, hubo algunas fechas que se mantuvieron sin cambios. Siguiendo los consejos que me diste y la sugerencia original de @GrowthNatives, personalicé aún más tus aportaciones y las mías utilizando Deepseek AI y finalmente logré hacer los ajustes finales que necesitaba.

Para beneficio de los demás, a continuación se muestra el código más reciente que se actualiza en la columna calculada "CascadeAdjustedDueDate ". Esto es lo que incorpora todas las sugerencias y aportaciones para finalizar la lógica que necesitaba.

Correct Due Date = 
VAR ThisMilestone = Milestones[Milestone]
VAR CurrentCourse = Milestones[CourseKey]
VAR FinalPubDate = RELATED(CoursePublishedDates[CoursePublishedDate])
VAR FinalCourseBuiltDate = RELATED(CourseBuiltDates[CourseBuiltAdjusted])
VAR IsCurrentMilestoneOffPeriod = Milestones[IsOffPeriod]
VAR OriginalDueDate = Milestones[FinalDueDate]
VAR OriginalDueYear = YEAR(OriginalDueDate)
VAR OriginalDueMonth = MONTH(OriginalDueDate)

// Determine if date is in December or January off-period
VAR IsDecOffPeriod = OriginalDueMonth = 12
VAR IsJanOffPeriod = OriginalDueMonth = 1

// Calculate correct adjustment date
VAR AdjustedDecDate = 
    IF(
        IsJanOffPeriod,
        DATE(OriginalDueYear - 1, 12, 5), // Jan 2026 → Dec 2025
        DATE(OriginalDueYear, 12, 5)      // Dec 2025 stays in 2025
    )

VAR SecondWeekDecMonday = DATE(YEAR(AdjustedDecDate), 12, 8)
VAR OffPeriodEnd = DATE(YEAR(AdjustedDecDate) + IF(IsJanOffPeriod, 0, 1), 1, 1)
VAR IsPubDateOffPeriod = LOOKUPVALUE(Milestones[IsOffPeriod], Milestones[Milestone], "Course Published", Milestones[CourseKey], CurrentCourse)
VAR SyllabusLogicStartDate = DATE(2025, 8, 5)

// Adjusted publication date
VAR AdjustedPubDate = 
    IF(
        IsPubDateOffPeriod,
        AdjustedDecDate,
        FinalPubDate
    )

// Check if any check milestones are in off period
VAR HasCheckMilestonesInOffPeriod =
    COUNTROWS(
        FILTER(
            FILTER(
                Milestones,
                Milestones[CourseKey] = CurrentCourse &&
                (Milestones[Milestone] = "Assessment Checks" ||
                 Milestones[Milestone] = "EdTech Checks" ||
                 Milestones[Milestone] = "Library Checks" ||
                 Milestones[Milestone] = "Programme Checks") &&
                Milestones[IsOffPeriod] = TRUE
            ),
            TRUE()
        )
    ) > 0

// Calculate adjusted dates
VAR AdjustedCourseBuiltDate = 
    IF(
        ThisMilestone="Course Built",
        IF(
            IsPubDateOffPeriod,
            AdjustedPubDate - 14,
            IF(
                IsCurrentMilestoneOffPeriod,
                IF(
                    HasCheckMilestonesInOffPeriod,
                    AdjustedDecDate - 7,
                    AdjustedDecDate
                ),
                FinalCourseBuiltDate
            )
        ),
        FinalCourseBuiltDate
    )

VAR AdjustedSyllabusReceivedDate = 
    IF(
        ThisMilestone="Syllabus Received",
        IF(
            FinalPubDate >= SyllabusLogicStartDate,
            IF(
                IsPubDateOffPeriod,
                AdjustedPubDate - 28,
                AdjustedCourseBuiltDate - 14
            ),
            OriginalDueDate
        ),
        BLANK()
    )

// Base calculation
VAR BaseDate =
    SWITCH(
        TRUE(),
        ThisMilestone="Assessment Checks", AdjustedPubDate - 7,
        ThisMilestone="Programme Checks", AdjustedPubDate - 7,
        ThisMilestone="Library Checks", AdjustedPubDate - 7,
        ThisMilestone="EdTech Checks", AdjustedPubDate - 7,
        ThisMilestone="Course Built", AdjustedCourseBuiltDate,
        ThisMilestone="Syllabus Received", AdjustedSyllabusReceivedDate,
        OriginalDueDate
    )

// Final adjustment
VAR AdjustedDate =
    IF(
        IsCurrentMilestoneOffPeriod,
        SWITCH(
            TRUE(),
            NOT(IsPubDateOffPeriod) && HasCheckMilestonesInOffPeriod && 
            (ThisMilestone="Assessment Checks" || 
             ThisMilestone="EdTech Checks" || 
             ThisMilestone="Library Checks" || 
             ThisMilestone="Programme Checks"),
            AdjustedDecDate,
            BaseDate
        ),
        BaseDate
    )

// Final validation
VAR ProposedDate = 
    IF(
        ThisMilestone="First Lecture",
        OriginalDueDate,
        AdjustedDate
    )

VAR IsProposedDateInOffPeriod = 
    ProposedDate >= SecondWeekDecMonday && 
    ProposedDate <= OffPeriodEnd

RETURN
    IF(
        IsProposedDateInOffPeriod,
        OriginalDueDate,
        ProposedDate
    )

Syndicate_Admin
Administrator
Administrator

Hola @iammrishoabeid ,
Veamos, está administrando la lógica de programación de hitos para los cursos, donde cada curso tiene 7 hitos clave y la lógica de fechas debe ajustarse dinámicamente en función de:

  1. Fines

  2. Días festivos (Reino Unido – Inglaterra y Gales)

  3. Lógica fuera de período (2ª semana de diciembre al 1 de enero)

  4. Nuevos plazos de entrega después del 05 de agosto de 2025

🔍 Objetivo

Desea asegurarse de que solo se ajusten los hitos posteriores al 05 de agosto de 2025 :

  • Sáltate los fines de semana y los días festivos.

  • Mueva las fechas en el período libre a un día hábil fijo.

  • Ajustes en cascada en función de los hitos del curso publicado o del curso creado.

Pasos que tomaría

Paso 1: Tabla de Fechas – Días Festivos y Fines de Semana

Ya lo has hecho bien. Solo tienes que verificar:

  • IsHoliday = TRUE/FALSE de la API de días festivos del Reino Unido.

  • IsWeekend = TRUE si WEEKDAY([Date], 2) es 6 (sábado) o 7 (domingo).

  • Combine esto en su tabla de hitos a través de la fecha de vencimiento.

Paso 2: Marcar hitos futuros (Post 05 de agosto de 2025)

En Power Query (buena elección):

IsFutureDate = [Due Date] >= #date(2025, 8, 5)

Úselo para filtrar dónde se necesitan actualizaciones.

Paso 3: Ajuste para fines de semana y días festivos

La columna AdjustedDueDate es en su mayoría correcta, pero resta 1 día adicional al mover días festivos. Solucionaremos esto de la siguiente manera:

  • Solo se ajusta una vez.

  • Pasar al día laborable anterior (ni uno más).

🔁 Reemplace su DAX por lo siguiente:

AdjustedDueDate =
VAR OriginalDate = Milestones[Due Date]
VAR IsFuture = Milestones[IsFutureDate]
VAR WeekdayNum = WEEKDAY(OriginalDate, 2)
VAR IsWeekend = WeekdayNum IN {6, 7}
VAR HolidayTable = FILTER(ALL(Dates), Dates[IsHoliday] = TRUE)
VAR IsHoliday = Milestones[IsHoliday]
VAR WorkingDate =
    IF(
        IsFuture,
        // Loop back to the nearest working day
        CALCULATE(
            MAX(Dates[Date]),
            FILTER(
                ALL(Dates),
                Dates[Date] <= OriginalDate &&
                Dates[IsHoliday] = FALSE &&
                Dates[IsWeekend] = FALSE
            )
        ),
        OriginalDate
    )
RETURN
    WorkingDate

💡 Explicación: Esto evita la doble resta (sábado→viernes y luego -1 de nuevo). Tira de la última fecha que no sea un fin de semana o un día festivo.

Paso 4: Crear la columna IsOffPeriod

Estás cerca aquí. Solo una pequeña mejora para que la lógica sea un poco más legible.

Sustituya su DAX por:

IsOffPeriod =
VAR AdjDate = Milestones[AdjustedDueDate]
VAR YearToCheck = YEAR(AdjDate)
VAR DecStart = DATE(YearToCheck, 12, 8 )  // 2nd Monday of December
VAR DecWeekStart =
    DecStart - WEEKDAY(DecStart, 2) + 1  // Get Monday of that week
VAR EndDate = DATE(YearToCheck + 1, 1, 1)  // Jan 1

RETURN
    IF(
        Milestones[IsFutureDate] &&
        AdjDate >= DecWeekStart &&
        AdjDate <= EndDate,
        TRUE,
        FALSE
    )


Paso 5: Mover las fechas que caen en el período de desconexión

Para cualquier hito en el que IsOffPeriod = TRUE, haremos lo siguiente:

  • Pasar al último día laborable de la primera semana de diciembre.

Calculemos esto como una nueva columna:

FinalDueDate =
VAR BaseDate = Milestones[AdjustedDueDate]
VAR IsOff = Milestones[IsOffPeriod]
VAR Year = YEAR(BaseDate)
VAR DecFirst = DATE(Year, 12, 1)
VAR FirstFriday =
    CALCULATE(
        MAX(Dates[Date]),
        FILTER(
            ALL(Dates),
            Dates[Date] >= DecFirst &&
            Dates[Date] <= DecFirst + 6 &&
            Dates[IsWeekend] = FALSE &&
            Dates[IsHoliday] = FALSE
        )
    )
RETURN
    IF(IsOff, FirstFriday, BaseDate)


Paso 6: Cambios en cascada si se actualiza "Curso publicado" o "Curso creado"

Vamos a dividir esto en una lógica basada en medidas o en una columna calculada.

Es necesario:

  • Localizar curso publicado

  • Calcule hacia atrás los hitos relacionados para el mismo curso.

A continuación, se explica cómo implementar esto:

  1. Crear una columna para obtener la fecha final del curso publicado

CoursePublishedDate =
CALCULATE(
    MAX('Milestones'[FinalDueDate]),
    FILTER(
        'Milestones',
        'Milestones'[Course ID] = EARLIER('Milestones'[Course ID]) &&
        'Milestones'[Milestone] = "Course Published"
    )
)
  1. Ahora ajuste todos los hitos relacionados en función de esto:

CascadeAdjustedDueDate =
VAR ThisMilestone = Milestones[Milestone]
VAR FinalPubDate = Milestones[CoursePublishedDate]
VAR NewDate =
    SWITCH(
        TRUE(),
        ThisMilestone="Assessment Checks", FinalPubDate - 7,
        ThisMilestone="Programme Checks", FinalPubDate - 7,
        ThisMilestone="Library Checks", FinalPubDate - 7,
        ThisMilestone="EdTech Checks", FinalPubDate - 7,
        ThisMilestone="Course Built", FinalPubDate - 14,
        ThisMilestone="Syllabus Received", FinalPubDate - 28,
        Milestones[FinalDueDate]
    )
RETURN
    IF(
        Milestones[IsOffPeriod] &&
        Milestones[Milestone] <> "First Lecture",
        NewDate,
        Milestones[FinalDueDate]
    )
  1. Si desea ajustar por separado el programa recibido en función del curso creado únicamente (si el curso publicado no está ajustado):

Cree una lógica similar utilizando Course Built como referencia.


🧪 Paso 7: Probar la salida

Ahora que has hecho todo lo anterior:

  • Agregue una matriz o una tabla en Power BI.

  • Columnas de visualización:

    • ID del curso

    • Hito

    • Fecha de vencimiento original

    • AdjustedDueDate

    • FinalDueDate

    • CascadeAdjustedDueDate

    • IsOffPeriod

Compáralo con tu ejemplo de Excel. ¡Deberías ver filas verdes coincidentes!

📘 Resumen de lo que construimos

Notas de la herramienta Logic

Ajuste para fines de semana/días festivosDAXBusca el último día laborable
Marcar hitos después del 05 de agostoPower QuerySe utiliza para aislar ajustes
Detección de período de inactividadDAXManeja la 2ª semana de diciembre - 1 de enero
Ajuste en cascadaDAXUtiliza SWITCH para la lógica por tipo de hito
Verificación visualObjeto visual de la matrizCompara lo esperado con lo real



¡Espero que esta solución le ayude a sacar el máximo partido a Power BI! Si es así, haga clic en "Marcar como solución" para ayudar a otros a encontrar las respuestas correctas.
💡¿Te ha resultado útil? ¡Muestra un poco de amor con felicitaciones 👍 , ya que tu apoyo mantiene a nuestra comunidad próspera!
🚀¡Sigamos creando juntos soluciones más inteligentes y basadas en datos! 🚀 [Explorar más]

Hola @GrowthNatives,

Gracias por apoyarme con esto tan rápidamente y por proporcionar una excelente guía paso a paso con instrucciones detalladas.

Al realizar los cambios que sugirió, llegué con éxito hasta el Paso 6, punto 1. En ese momento, recibí un error de dependencia circular. Resolví esto creando CoursePublishedDates como una tabla calculada usando el siguiente código:

CoursePublishedDates = 
ADDCOLUMNS(
    SUMMARIZE(Milestones, Milestones[CourseKey]),
    "CoursePublishedDate",
    CALCULATE(
        MAX(Milestones[FinalDueDate]),
        Milestones[Milestone] = "Course Published"
    )
)

y, a continuación, asocié esa tabla con la columna CascadeAdjustedDate mediante RELATED(...) para vincular la columna y la tabla calculada. Ese código es:

CascadeAdjustedDueDate = 
VAR ThisMilestone = Milestones[Milestone]
VAR FinalPubDate = RELATED(CoursePublishedDates[CoursePublishedDate])
VAR NewDate =
    SWITCH(
        TRUE(),
        ThisMilestone="Assessment Checks", FinalPubDate - 7,
        ThisMilestone="Programme Checks", FinalPubDate - 7,
        ThisMilestone="Library Checks", FinalPubDate - 7,
        ThisMilestone="EdTech Checks", FinalPubDate - 7,
        ThisMilestone="Course Built", FinalPubDate - 14,
        ThisMilestone="Syllabus Received", FinalPubDate - 28,
        Milestones[FinalDueDate]
    )
RETURN
    IF(
        Milestones[IsOffPeriod],
        NewDate,
        Milestones[FinalDueDate]
    )

Al realizar estos cambios, realizó correctamente los cambios de fecha para todas las fechas, excepto los hitos Curso creado y Programa recibido, que aún hacen referencia a las fechas originales de la columna FinalDueDate.

La tabla siguiente cambia para un curso cuyos hitos caen en el tiempo IsOffPeriod. Observará la última columna, donde he indicado las fechas corregidas que deben actualizarse para los hitos de curso creado y programa recibido.

Código del cursoHitoFecha de vencimientoCascadeAdjustedDateFechas correctas
AM11 SPR26Plan de estudios recibido18 de noviembre de 202518 de noviembre de 202507 de noviembre de 2025
Curso Construido02 Dic 202502 Dic 202521 de noviembre de 2025
Comprobaciones de evaluación09 Dic 202528 de noviembre de 2025Correcto
Comprobaciones de tecnología educativa09 Dic 202528 de noviembre de 2025Correcto
Comprobaciones de la biblioteca09 Dic 202528 de noviembre de 2025Correcto
Comprobaciones del programa09 Dic 202528 de noviembre de 2025Correcto
Curso Publicado16 dic 202505 de noviembre de 2025Correcto
Primera Lección06 de enero de 202606 de enero de 2026Correcto
CD52 S SPR26Plan de estudios recibido18 dic 202518 dic 202521 de noviembre de 2025
Curso Construido01 de enero de 202601 de enero de 202605 Dic 2025
Comprobaciones de evaluación08 de enero de 202608 de enero de 2026Correcto
Comprobaciones de tecnología educativa08 de enero de 202608 de enero de 2026Correcto
Comprobaciones de la biblioteca08 de enero de 202608 de enero de 2026Correcto
Comprobaciones del programa08 de enero de 202608 de enero de 2026Correcto
Curso Publicado15 de enero de 202615 de enero de 2026Correcto
Primera Lección02 de febrero de 202602 de febrero de 2026Correcto

¿Le importaría aconsejarme sobre cómo puedo asegurarme de que los hitos del plan de estudios recibido y del curso creado se actualicen en consecuencia?

Helpful resources

Announcements
June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

Check out the June 2025 Power BI update to learn about new features.

May 2025 Monthly Update

Fabric Community Update - May 2025

Find out what's new and trending in the Fabric community.

Top Solution Authors