Transformar los datos del servidor de Exchange con citas periódicas en Power BI / Power Query

Un usuario Pregunto ✅

raksha_v

Tengo un par de preguntas sobre cómo extraer datos del servidor Exchange con citas periódicas en Power BI

  1. ¿Hay alguna forma de obtener citas periódicas como citas independientes para cada aparición en Power BI> Power Query? En este momento, las citas periódicas se devuelven como una única cita en la primera aparición.
  1. Además, ¿cómo puedo usar los datos en la sección de atributos para generar nuevas filas para ocurrencias individuales y agregarlas a los datos principales?

@raksha_v

Al conectar datos de Exchange, solo tiene un registro para una cita, sin importar si es Single o RecurringMaster. Puede expandir las columnas de atributos en la tabla MeetingRequest o Calendar.

let
    Source = Exchange.Contents("xxxxxx@microsoft.com"),
    Calendar1 = Source{[Name="Calendar"]}[Data],
    #"Expanded Attributes" = Table.ExpandRecordColumn(Calendar1, "Attributes", {"AppointmentType", "Recurrence"}, {"Attributes.AppointmentType", "Attributes.Recurrence"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Attributes", each ([Attributes.AppointmentType] = "RecurringMaster")),
    #"Expanded Attributes.Recurrence" = Table.ExpandRecordColumn(#"Filtered Rows", "Attributes.Recurrence", {"StartDate", "EndDate", "Pattern", "Interval"}, {"Attributes.Recurrence.StartDate", "Attributes.Recurrence.EndDate", "Attributes.Recurrence.Pattern", "Attributes.Recurrence.Interval"})
in
    #"Expanded Attributes.Recurrence"

77.PNG

No es una buena práctica que esas citas recurrentes aparezcan en la tabla del calendario, porque necesita generar una lista de fechas entre la fecha de inicio y la fecha de finalización para cada cita recurrente. Será una tabla enorme. Luego, calcule el intervalo de fechadiff y mod para obtener esos días recurrentes para cada cita. Y no puede funcionar para citas sin FECHA DE FINALIZACIÓN. Consulte mi ejemplo a continuación, comencé con la tabla de registros de citas periódicas filtrada anteriormente:

let
    Source = Exchange.Contents("xxxxx@microsoft.com"),
    Calendar1 = Source{[Name="Calendar"]}[Data],
    #"Expanded Attributes" = Table.ExpandRecordColumn(Calendar1, "Attributes", {"AppointmentType", "Recurrence"}, {"Attributes.AppointmentType", "Attributes.Recurrence"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Attributes", each ([Attributes.AppointmentType] = "RecurringMaster")),
    #"Expanded Attributes.Recurrence" = Table.ExpandRecordColumn(#"Filtered Rows", "Attributes.Recurrence", {"StartDate", "EndDate", "Pattern", "Interval"}, {"Attributes.Recurrence.StartDate", "Attributes.Recurrence.EndDate", "Attributes.Recurrence.Pattern", "Attributes.Recurrence.Interval"}),
    #"Added Custom" = Table.AddColumn(#"Expanded Attributes.Recurrence", "RecurrenceStartDate", each [Attributes.Recurrence.StartDate]),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "RecurrenceEndDate", each [Attributes.Recurrence.EndDate]),
    #"Filtered Rows1" = Table.SelectRows(#"Added Custom1", each ([RecurrenceEndDate] <> null)),
    #"Changed Type" = Table.TransformColumnTypes(#"Filtered Rows1",{{"RecurrenceStartDate", type date}, {"RecurrenceEndDate", type date}}),
    #"Added Custom2" = Table.AddColumn(#"Changed Type", "DatesInPeriod", each List.Dates([RecurrenceStartDate],Duration.Days(Duration.From([RecurrenceEndDate]-[RecurrenceStartDate])),#duration(1,0,0,0))),
    #"Expanded DatesInPeriod" = Table.ExpandListColumn(#"Added Custom2", "DatesInPeriod"),
    #"Added Custom3" = Table.AddColumn(#"Expanded DatesInPeriod", "DateDiffModInterval", each Number.Mod(Duration.Days(Duration.From([DatesInPeriod]-[RecurrenceStartDate])),7*[Attributes.Recurrence.Interval])),
    #"Filtered Rows2" = Table.SelectRows(#"Added Custom3", each ([DateDiffModInterval] = 0))
in
    #"Filtered Rows2"

777.PNG

Saludos,

pedanticpad

Esto funciona perfectamente cuando solo se selecciona un día a la semana cuando se realiza la cita en Outlook. Sin embargo, si alguien establece una recurrente para algo más de un día a la semana, solo el primer día se informa utilizando los métodos anteriores.

Por ejemplo, si se crea una cita periódica para el lunes y el jueves de cada semana, el patrón de recurrencia = WeeklyPattern, el intervalo de recurrencia = 1 y solo se informa el lunes, no se capturan el segundo y los días posteriores de la semana incluidos en la recurrencia. por motivo de multiplicar el intervalo * 7. ¿Hay alguna forma de hacer esto para que se informen todos los días de la recurrencia?

Lamysroe

En respuesta a pedanticpad

@pedanticpad Usé una tabla separada que luego agregué a la tabla principal. Para la recurrencia diaria, cambié el patrón de recurrencia a diario y el intervalo según sea necesario.

pedanticpad

En respuesta a Lamysroe

@lamysroe Gracias por la respuesta. No estoy seguro si es lo mismo en otras versiones, pero en Office365 cuando configuro cualquier combinación de días en una semana, almacena esto como una recurrencia semanal. Lunes y jueves = semanalmente, lunes y jueves y viernes = semanalmente. ¿Cómo puedo dar cuenta de esto? ¿Me falta expandir un atributo?

image.png

@raksha_v

Al conectar datos de Exchange, solo tiene un registro para una cita, sin importar si es Single o RecurringMaster. Puede expandir las columnas de atributos en la tabla MeetingRequest o Calendar.

let
    Source = Exchange.Contents("xxxxxx@microsoft.com"),
    Calendar1 = Source{[Name="Calendar"]}[Data],
    #"Expanded Attributes" = Table.ExpandRecordColumn(Calendar1, "Attributes", {"AppointmentType", "Recurrence"}, {"Attributes.AppointmentType", "Attributes.Recurrence"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Attributes", each ([Attributes.AppointmentType] = "RecurringMaster")),
    #"Expanded Attributes.Recurrence" = Table.ExpandRecordColumn(#"Filtered Rows", "Attributes.Recurrence", {"StartDate", "EndDate", "Pattern", "Interval"}, {"Attributes.Recurrence.StartDate", "Attributes.Recurrence.EndDate", "Attributes.Recurrence.Pattern", "Attributes.Recurrence.Interval"})
in
    #"Expanded Attributes.Recurrence"

77.PNG

No es una buena práctica que esas citas recurrentes aparezcan en la tabla del calendario, porque necesita generar una lista de fechas entre la fecha de inicio y la fecha de finalización para cada cita recurrente. Será una tabla enorme. Luego, calcule el intervalo de fechadiff y mod para obtener esos días recurrentes para cada cita. Y no puede funcionar para citas sin FECHA DE FINALIZACIÓN. Consulte mi ejemplo a continuación, comencé con la tabla de registros de citas periódicas filtrada anteriormente:

let
    Source = Exchange.Contents("xxxxx@microsoft.com"),
    Calendar1 = Source{[Name="Calendar"]}[Data],
    #"Expanded Attributes" = Table.ExpandRecordColumn(Calendar1, "Attributes", {"AppointmentType", "Recurrence"}, {"Attributes.AppointmentType", "Attributes.Recurrence"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Attributes", each ([Attributes.AppointmentType] = "RecurringMaster")),
    #"Expanded Attributes.Recurrence" = Table.ExpandRecordColumn(#"Filtered Rows", "Attributes.Recurrence", {"StartDate", "EndDate", "Pattern", "Interval"}, {"Attributes.Recurrence.StartDate", "Attributes.Recurrence.EndDate", "Attributes.Recurrence.Pattern", "Attributes.Recurrence.Interval"}),
    #"Added Custom" = Table.AddColumn(#"Expanded Attributes.Recurrence", "RecurrenceStartDate", each [Attributes.Recurrence.StartDate]),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "RecurrenceEndDate", each [Attributes.Recurrence.EndDate]),
    #"Filtered Rows1" = Table.SelectRows(#"Added Custom1", each ([RecurrenceEndDate] <> null)),
    #"Changed Type" = Table.TransformColumnTypes(#"Filtered Rows1",{{"RecurrenceStartDate", type date}, {"RecurrenceEndDate", type date}}),
    #"Added Custom2" = Table.AddColumn(#"Changed Type", "DatesInPeriod", each List.Dates([RecurrenceStartDate],Duration.Days(Duration.From([RecurrenceEndDate]-[RecurrenceStartDate])),#duration(1,0,0,0))),
    #"Expanded DatesInPeriod" = Table.ExpandListColumn(#"Added Custom2", "DatesInPeriod"),
    #"Added Custom3" = Table.AddColumn(#"Expanded DatesInPeriod", "DateDiffModInterval", each Number.Mod(Duration.Days(Duration.From([DatesInPeriod]-[RecurrenceStartDate])),7*[Attributes.Recurrence.Interval])),
    #"Filtered Rows2" = Table.SelectRows(#"Added Custom3", each ([DateDiffModInterval] = 0))
in
    #"Filtered Rows2"

777.PNG

Saludos,

Lamysroe

En respuesta a v-sihou-msft

¿Hay alguna forma de hacer esto teniendo en cuenta diferentes intervalos de recurrencia 1, 2, 3, etc. así como diferentes patrones (diarios, semanales, mensuales)?

csnider

En respuesta a Lamysroe

@lamysroe, ¿alguna vez te diste cuenta de esto? Estoy trabajando en el mismo problema. Gracias.

Lamysroe

En respuesta a csnider

@csnider Tenga paciencia conmigo si esto se alarga …

  1. Cargué el calendario dos veces
    1. El primer calendario que cargué, expandí los atributos y filtré para reuniones individuales
    2. El segundo calendario que cargué, expandí los atributos y filtré para reuniones recurrentes
      1. Expandí el fin de la última ocurrencia (esta es la última fecha verdadera de la reunión periódica a pesar de las ocurrencias especificadas o la fecha de finalización)
        1. Usé esta fecha para ampliar las fechas de la reunión.
      2. Expanda Recurrence Plus estos … día del mes, día de la semana, días de la semana
        recurrencia.fecha de inicio
        recurrence.enddate (fecha de finalización especificada)
        recurrence.numberofoccurences (se usa si no se especifica una fecha de finalización)
        recurrence.pattern (diario, semanal, mensual)
        recurrence.interval (relativo al patrón, número de veces en una semana o mes para la recurrencia)
      3. Agregar Fechas en la columna Período (como lista)
      4. Agregar nueva columna de intervalo de recurrencia (el patrón mensual es * 4 para tener en cuenta las semanas de un mes. Todos los demás se hacen a diario)
      5. Expandir la lista DatesinPeriod
      6. Agregar columna ModdInterval
      7. Filter Row filter a 0 de mod diff (el filtrado a 0 proporciona los días reales de reuniones, todos los demás números son los días entre reuniones)
    3. Agregué todos los calendarios individuales en 1
    4. Agregué todos los calendarios recurrentes en 1

Calendario único: hay pasos adicionales aquí porque agregué columnas para aclarar la sala de reuniones utilizada y la ubicación de la oficina

let
    Source = Exchange.Contents("XXXXXX"),
    Calendar1 = Source{[Name="Calendar"]}[Data],
   #"Removed Other Columns" = Table.SelectColumns(Calendar1,{"Subject", "Location", "Start", "End", "Attributes", "Body", "Id"}),
    #"Expanded Body" = Table.ExpandRecordColumn(#"Removed Other Columns", "Body", {"TextBody"}, {"TextBody"}),
        #"Expanded Attributes" = Table.ExpandRecordColumn(#"Expanded Body", "Attributes", {"AppointmentType", "Duration", "ExtendedProperties", "Organizer", "Recurrence"}, {"Attributes.AppointmentType", "Attributes.Duration", "Attributes.ExtendedProperties", "Attributes.Organizer", "Attributes.Recurrence"}),
    #"Expanded Attributes.Organizer" = Table.ExpandRecordColumn(#"Expanded Attributes", "Attributes.Organizer", {"Name"}, {"Attributes.Organizer.Name"}),
    #"Replaced Value" = Table.ReplaceValue(#"Expanded Attributes.Organizer",null,"",Replacer.ReplaceValue,{"TextBody"}),
    #"ReplacedValue - Location ""meeting"" if empty" = Table.ReplaceValue(#"Replaced Value",null,"meeting",Replacer.ReplaceValue,{"Location"}),
   #"AddedColumn - Office" = Table.AddColumn( #"ReplacedValue - Location ""meeting"", "Office", each if Text.Contains([Location], "meeting") then "XXXXXCity" else "XXXXcity"),
      #"AddedColumn - Room" = Table.AddColumn(#"AddedColumn - Office", "Room", each if Text.Contains([Location], "meeting") then "XXXXXmeeting room name" else "XXXXXmeeting room name"),
    #"Filtered - ""Single""" = Table.SelectRows(#"AddedColumn - Room", each ([Attributes.AppointmentType] = "Single")),
    #"Removed Columns" = Table.RemoveColumns(#"Filtered - ""Single""",{"Attributes.ExtendedProperties", "Attributes.Recurrence"}),
    #"Renamed Column - Attributes organizer" = Table.RenameColumns(#"Removed Columns",{{"Attributes.Organizer.Name", "Name"}})
in
    #"Renamed Column - Attributes organizer"



​

Calendario de reuniones periódicas: lo mismo con los pasos adicionales anteriores. El intervalo recurrente es la frecuencia con la que ocurre la reunión. El intervalo recurrente se multiplica por 7 para los días de una semana. El mes no siempre termina en la fecha exacta, pero cuenta el número correcto de ocurrencias (esta era la única forma en que podía ponerme a trabajar). Tomé un calendario de sala de reuniones de Outlook y los datos en Power BI y confirmé esos datos durante todo un año para asegurarme de que lo estaba haciendo bien.

let
    Source = Exchange.Contents("XXXXXX"),
    Calendar1 = Source{[Name="Calendar"]}[Data],
 #"Removed Other Columns" = Table.SelectColumns(Calendar1,{"Subject", "Location", "Start", "End", "Attributes", "Body", "Id"}),
        #"Expanded Attributes" = Table.ExpandRecordColumn(#"Removed Other Columns", "Attributes", {"AppointmentType", "Duration", "ExtendedProperties", "LastOccurrence", "Organizer", "Recurrence"}, {"AppointmentType", "Duration", "ExtendedProperties", "LastOccurrence", "Organizer", "Recurrence"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Attributes", each ([AppointmentType] = "RecurringMaster")),
    #"Replaced Value" = Table.ReplaceValue(#"Filtered Rows",null,"meeting",Replacer.ReplaceValue,{"Location"}),
    #"Added Conditional Column1" = Table.AddColumn(#"Replaced Value", "Office", each if Text.Contains([Location], "meeting") then "XXXXcity" else "XXXXcity"),
      #"Added Conditional Column2" = Table.AddColumn(#"Added Conditional Column1", "Room", each if Text.Contains([Location], "meeting") then "XXXXXmeeting room name" else "XXXXXmeeting room name"),
    #"Expanded Recurrence" = Table.ExpandRecordColumn(#"Added Conditional Column2", "Recurrence", {"StartDate", "EndDate", "NumberOfOccurrences", "Pattern", "Interval", "DayOfMonth", "DayOfTheWeek", "DaysOfTheWeek"}, {"Recurrence.StartDate", "Recurrence.EndDate", "Recurrence.NumberOfOccurrences", "Recurrence.Pattern", "Recurrence.Interval", "Recurrence.DayOfMonth", "Recurrence.DayOfTheWeek", "Recurrence.DaysOfTheWeek"}),
    #"Expanded ExtendedProperties" = Table.ExpandRecordColumn(#"Expanded Recurrence", "ExtendedProperties", {"RecurrencePattern"}, {"ExtendedProperties.RecurrencePattern"}),
    #"Expanded LastOccurrence" = Table.ExpandRecordColumn(#"Expanded ExtendedProperties", "LastOccurrence", {"End"}, {"LastOccurrence.End"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Expanded LastOccurrence",{{"LastOccurrence.End", type date}, {"Recurrence.StartDate", type date}, {"Recurrence.EndDate", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "DatesInPeriod", each List.Dates([Recurrence.StartDate],Duration.Days(Duration.From([LastOccurrence.End]-[Recurrence.StartDate])),#duration(1,0,0,0))),
    #"Added Custom2" = Table.AddColumn(#"Added Custom", "Newrecurrenceinterval", each if [Recurrence.Pattern] = "RelativeMonthlyPattern" then [Recurrence.Interval]*4 else [Recurrence.Interval]),
    #"Expanded DatesInPeriod" = Table.ExpandListColumn(#"Added Custom2", "DatesInPeriod"),
    #"Filtered Rows3" = Table.SelectRows(#"Expanded DatesInPeriod", each true),
    #"Added Custom1" = Table.AddColumn(#"Filtered Rows3", "DateDiffModInterval", each Number.Mod(Duration.Days(Duration.From([DatesInPeriod]-[Recurrence.StartDate])),7*[Newrecurrenceinterval])),
    #"Changed Type1" = Table.TransformColumnTypes(#"Added Custom1",{{"DatesInPeriod", type date}}),
    #"Duplicated Column" = Table.DuplicateColumn(#"Changed Type1", "DatesInPeriod", "DatesInPeriod - Copy"),
    #"Extracted Day Name" = Table.TransformColumns(#"Duplicated Column", {{"DatesInPeriod - Copy", each Date.DayOfWeekName(_), type text}}),
    #"Renamed Columns" = Table.RenameColumns(#"Extracted Day Name",{{"DatesInPeriod - Copy", "DayName"}}),
    #"Replaced Value1" = Table.ReplaceValue(#"Renamed Columns",null,0,Replacer.ReplaceValue,{"Newrecurrenceinterval"}),
    #"Replaced Value2" = Table.ReplaceValue(#"Replaced Value1",null,0,Replacer.ReplaceValue,{"DateDiffModInterval"}),
    #"Filtered Rows4" = Table.SelectRows(#"Replaced Value2", each [DateDiffModInterval] = 0),
    #"Filtered Rows5" = Table.SelectRows(#"Filtered Rows4", each true),
    #"Expanded Organizer" = Table.ExpandRecordColumn(#"Filtered Rows5", "Organizer", {"Name"}, {"Name"}),
    #"Expanded Body" = Table.ExpandRecordColumn(#"Expanded Organizer", "Body", {"TextBody"}, {"TextBody"})
in
    #"Expanded Body"

Tablas de reuniones individuales adjuntas: se agregaron días de semanas y horas de trabajo para evaluar las horas disponibles frente a las usadas (hice esto específicamente para esta tabla porque necesitaba algo separado)

let
    Source = Table.Combine (XXXALL SINGLE TABLES),
    #"Extracted Start Time" = Table.AddColumn(Source, "Time", each DateTime.Time([Start]), type time),
    #"Renamed Start Time" = Table.RenameColumns(#"Extracted Start Time",{{"Time", "Start Time"}}),
    #"Extracted End Time" = Table.AddColumn(#"Renamed Start Time", "Time", each DateTime.Time([End]), type time),
    #"Renamed End Time" = Table.RenameColumns(#"Extracted End Time",{{"Time", "End Time"}}),
    #"Inserted Year" = Table.AddColumn(#"Renamed End Time", "Year", each Date.Year([End]), Int64.Type),
    #"Inserted Month Name" = Table.AddColumn(#"Inserted Year", "Month Name", each Date.MonthName([End]), type text),
    #"Inserted Day Name" = Table.AddColumn(#"Inserted Month Name", "Day Name.1", each Date.DayOfWeekName([Start]), type text),
    #"Inserted Month Number" = Table.AddColumn(#"Inserted Day Name", "Month", each Date.Month([End]), Int64.Type),
    #"Inserted Day of Week Number" = Table.AddColumn(#"Inserted Month Number", "Day of Week", each Date.DayOfWeek([Start])+1, Int64.Type),
    #"ChangedType - Dates" = Table.TransformColumnTypes(#"Inserted Day of Week Number",{{"Start", type datetime}, {"End", type datetime}}),
    #"Added Available Work Hours" = Table.AddColumn(#"ChangedType - Dates", "Available Work Hours", each if [Day of Week] = 1 then 0 else if [Day of Week] = 7 then 0 else 10),
    #"Inserted Week of Year" = Table.AddColumn(#"Added Available Work Hours", "Week of Year", each Date.WeekOfYear([Start]), Int64.Type),
    #"Inserted Day of Year" = Table.AddColumn(#"Inserted Week of Year", "Day of Year", each Date.DayOfYear([Start]), Int64.Type),
    #"Removed Errors" = Table.RemoveRowsWithErrors(#"Inserted Day of Year", {"Room"}),
    #"Changed Duration to Hours" = Table.TransformColumns(#"Removed Errors",{{"Attributes.Duration", Duration.TotalHours, type number}}),
    #"Renamed Duration" = Table.RenameColumns(#"Changed Duration to Hours",{{"Attributes.Duration", "Duration"}}),
    #"ChangedType - Dates2" = Table.TransformColumnTypes(#"Renamed Duration",{{"Start", type date}, {"End", type date}})
in
    #"ChangedType - Dates2"

Mesas de reuniones periódicas adjuntas

let
    Source = Table.Combine(XXXXALL RECURRING TABLES),
    #"Removed RecurrenceDayofMonth(null)" = Table.RemoveColumns(Source,{"Recurrence.DayOfMonth"}),
    #"ChangedType - Start Date to Time" = Table.TransformColumnTypes(#"Removed RecurrenceDayofMonth(null)",{{"Start", type time}}),
    #"Renamed ""Start"" to ""StartTimeRec""" = Table.RenameColumns(#"ChangedType - Start Date to Time",{{"Start", "StartTimeRec"}}),
    #"ChangedType - End Date to Time" = Table.TransformColumnTypes(#"Renamed ""Start"" to ""StartTimeRec""",{{"End", type time}}),
    #"Renamed DateInPeriod(StartDate) & End(EndTimeRec)" = Table.RenameColumns(#"ChangedType - End Date to Time",{{"End", "EndTimeRec"}, {"DatesInPeriod", "StartDate"}}),
    #"ChangedType - Duration to nearest 15 minutes" = Table.TransformColumns(#"Renamed DateInPeriod(StartDate) & End(EndTimeRec)",{{"Duration", Duration.TotalHours, type number}}),
    #"Filtered Rows" = Table.SelectRows(#"ChangedType - Duration to nearest 15 minutes", each true),
    #"Removed RecurrenceEndDate" = Table.RemoveColumns(#"Filtered Rows",{"Recurrence.EndDate"}),
    #"Renamed Columns" = Table.RenameColumns(#"Removed RecurrenceEndDate",{{"StartTimeRec", "Start Time"}, {"EndTimeRec", "End Time"}, {"StartDate", "Start"}})
in
    #"Renamed Columns"

Tabla final única adjunta y tabla final recurrente:

let
    Source = Table.Combine({#"Conference Room Recurring", #"Conference Rooms Single"}),
    #"Removed Column" = Table.RemoveColumns(Source,{"End"}),
    #"Removed Columns1" = Table.RemoveColumns(#"Removed Column",{"Year", "Month Name", "Day Name.1", "Month", "Day of Week", "Available Work Hours", "Week of Year", "Day of Year"}),
    #"Removed Columns2" = Table.RemoveColumns(#"Removed Columns1",{"Attributes.AppointmentType", "Recurrence.DayOfTheWeek", "Recurrence.DaysOfTheWeek", "ExtendedProperties.RecurrencePattern", "DayName"}),
    #"Inserted Year" = Table.AddColumn(#"Removed Columns2", "Year", each Date.Year([Start]), Int64.Type),
    #"Inserted Month Name" = Table.AddColumn(#"Inserted Year", "Month Name", each Date.MonthName([Start]), type text),
    #"Inserted Month" = Table.AddColumn(#"Inserted Month Name", "Month", each Date.Month([Start]), Int64.Type),
    #"Inserted Day Name" = Table.AddColumn(#"Inserted Month", "Day Name", each Date.DayOfWeekName([Start]), type text),
    #"Inserted Day of Week" = Table.AddColumn(#"Inserted Day Name", "Day of Week", each Date.DayOfWeek([Start])+1),
    #"Inserted Day of Year" = Table.AddColumn(#"Inserted Day of Week", "Day of Year", each Date.DayOfYear([Start]), Int64.Type),
    #"Inserted Week of Year" = Table.AddColumn(#"Inserted Day of Year", "Week of Year", each Date.WeekOfYear([Start]), Int64.Type),
    #"Added Available Work Hours" = Table.AddColumn(#"Inserted Week of Year", "Available Work Hours", each if [Day of Week] = 1 then 0 else if [Day of Week] = 7 then 0 else 10),
    #"ReplacedValue - Appt Type ""null"" to Single" = Table.ReplaceValue(#"Added Available Work Hours",null,"Single",Replacer.ReplaceValue,{"AppointmentType"}),
    #"Added Column - Room Setup" = Table.AddColumn(#XXXXXADDED CONDITIONAL COLUMN TO ADD ROOM USES TO EACH CONFERENCE ROOM NAME),
    #"Filtered Rows" = Table.SelectRows(#"Added Column - Room Setup", each true),
    #"AddedColumn - Round Start Time" = Table.AddColumn(#"Filtered Rows", "Time Test", each if Time.Minute([Start Time])/15>3 then [Start Time]+#duration(0,0,60-Time.Minute([Start Time]),-Time.Second([Start Time])) else if Time.Minute([Start Time])/15<1 then [Start Time]+#duration(0,0,-Time.Minute([Start Time]),-Time.Second([Start Time])) else [Start Time]+#duration(0,0,30-Time.Minute([Start Time]),-Time.Second([Start Time]))),
    #"Renamed - StartTimeRounded" = Table.RenameColumns(#"AddedColumn - Round Start Time",{{"Time Test", "StartTimeRounded"}}),
    #"Changed Type StartTimeRounded to Time" = Table.TransformColumnTypes(#"Renamed - StartTimeRounded",{{"StartTimeRounded", type time}}),
    #"Replaced Value" = Table.ReplaceValue(#"Changed Type StartTimeRounded to Time",null,"",Replacer.ReplaceValue,{"TextBody"}),
    #"Added Video Conference" = Table.AddColumn(#"Replaced Value", "Video Conference", each if Text.Contains([Subject], "bluejeans") then "Yes" else if Text.Contains([Subject], "zoom") then "Yes" else if Text.Contains([Location], "bluejeans") then "Yes" else if Text.Contains([Location], "zoom") then "Yes" else if Text.Contains([TextBody], "bluejeans") then "Yes" else if Text.Contains([TextBody], "zoom") then "Yes" else "No")
in
    #"Added Video Conference"

También tengo una tabla de días festivos en la que utilizo un calendario para ver los días hábiles correctos.

cz1romanini

En respuesta a Lamysroe

¡Esto es realmente interesante, maravilloso! Al mismo tiempo, diría que es un poco complejo, especialmente para alguien como yo que no está acostumbrado a trabajar tan bien con Power Bi.

Hice todo como se describe y, en mi caso, me enfrento al siguiente mensaje de error:
«Expression.Error: No podemos convertir el valor nulo al tipo Número.
Detalles:
Valor =
Tipo =[Type]»

He tratado de arreglar eso pero no tengo ni idea de lo que está pasando. ¿Podrías ayudarme de nuevo, por favor?
¡Muchas gracias!

Cesar Romanini

Lamysroe

En respuesta a cz1romanini

@ cz1romanini Vaya a la columna que da el error y reemplace el valor «nulo» con un espacio en blanco.

SimonNicholson

En respuesta a Lamysroe

también recibo ese error, parece estar en una línea completa

Lamysroe

En respuesta a SimonNicholson

@SimonNicholson puede ver qué columna y tipo de columna está arrojando el error?

SimonNicholson

En respuesta a Lamysroe

Hola

Eso es lo extraño, no es una columna, es una fila completa

Lamysroe

En respuesta a SimonNicholson

¿Puedes enviar una captura de pantalla? ¿Cuál es el error que se está lanzando?

SimonNicholson

En respuesta a Lamysroe

SimonNicholson_0-1595364280546.png

Lamysroe

En respuesta a SimonNicholson

@SimonNicholson Este error es de una de las columnas con un tipo de número que tiene «nulo» en la columna en lugar de un espacio en blanco. Ir a cada columna que tiene Tipo de número y reemplace «Nulo» con un espacio en blanco (ya que no es nada). Esto debería borrar el error.

SimonNicholson

En respuesta a Lamysroe

Hola, ya hice eso en todas las columnas.

Lamysroe

En respuesta a SimonNicholson

¿Alguna posibilidad de que pueda compartir el archivo conmigo? Si no es así, ¿hay alguna posibilidad de que elimine esa fila solo para ver si funciona?

SimonNicholson

En respuesta a Lamysroe

hola – creo que lo he descubierto

si la recurrencia no tiene una fecha de finalización, entonces se produce un error. así que agregué el 31/12/2025 y se ejecuta

gracias por las sugerencias

Lamysroe

En respuesta a SimonNicholson

¿Qué paso lateral ocurre el error? ¿Puede retroceder al paso y reducir el cambio que generó el problema?

csnider

En respuesta a Lamysroe

@lamysroe Holy smokes: ¡gracias por la respuesta detallada!

Necesitaré tomarme un tiempo para revisarlo con más detalle. (No soy un experto en Power BI y trabajo en esto cuando tengo tiempo). Especialmente la parte sobre las horas disponibles frente a las usadas. (Para eso, actualmente estoy usando pestañas separadas para cada mes del año y asignando una cantidad de horas disponibles a la pestaña y filtrando todas las imágenes en la pestaña para ese mes en particular).

Adopté un enfoque similar para las consultas, es decir, dividí los datos originales en diferentes transformaciones y luego los volví a ensamblar en una al final.

Con respecto a las recurrencias diarias usando una cantidad de recurrencias versus una fecha de finalización, creé una columna duplicada para la fecha de inicio, la convertí en un número entero y luego agregué el número de recurrencias de los atributos expandidos ‘recurrence.numberofoccurrences’. Dupliqué esa columna y luego la convertí de nuevo a un tipo de fecha. Esto me da la fecha de finalización de la recurrencia y luego puedo usar DatesInPeriod, expandir y ModDiff como lo hizo.

Deja un comentario

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