Conversión de fecha IBM CYYMMDD – ¡Por favor, dígame que hay una manera mejor!

Un usuario Pregunto ✅

mesmollar

¡Hola a todos!

Mi oficina usa un IBM AS400 y me estoy conectando a mis datos a través de una conexión ODBC.

Estoy construyendo un modelo de datos usando varios archivos, cada uno con varios campos de fecha, y los datos que provienen de IBM siempre están en formato CYYMMDD y se reconocen como un número (no como texto) y los valores nulos aparecen como ceros.

Así que tengo la siguiente manipulación manual, pero me pregunto si hay una forma más rápida. ¡Esto es doloroso! Esto es lo que se me ocurrió. ¡Tengo que hacer este proceso manual con cada campo apestoso!

  1. Cambiar el tipo de datos a texto
  2. Reemplazar todos los valores 0 con nulos
  3. Cree una nueva columna personalizada con fórmula:
    1. = Text.Range ([*Your Date Field*], 3,2) y «https://community.powerbi.com/» y Text.Range ([*Your Date Field*], 5,2) & «https://community.powerbi.com/» & Text.Range ([*Your Date Field*], 1,2)
  4. Cambiar el tipo de datos en la nueva columna personalizada al tipo de fecha

@mesmollar

Como su próxima fecha es siempre el formato CYYMMDD, no creo que haya una mejor manera que truncar la «C» de la cadena de datos a través de Power Query o DAX. Puede considerar almacenar los datos de IBM en una base de datos relacional, luego puede personalizar una función y usar un procedimiento almacenado para ejecutar la conversión.

Saludos,

emarc1

Desde que encontré esto a través de Google, pensé en dar mis pensamientos, aunque llego 4 años demasiado tarde … Quizás alguien más lo encuentre útil.

También utilizamos un IBM AS400 / iSeries. Probé algunos métodos anteriormente, pero me decidí por lo siguiente por un tiempo:

#"Added Custom - Date" = Table.AddColumn(Source, "Date", each if [DateCol] = 0 then null else
Date.FromText(Text.From([DateCol] + 19000000)), type date)

Esto me ha servido bien, pero estaba tratando de ordenar un poco el código porque lo uso en todos los informes que hago. Primero quería algo que transformara la columna en lugar de crear una nueva … Pero al final encontré un método para hacer esto que podría transformar una lista completa de columnas con solo dos líneas de código:

DateFunction = each if _ = 0 then null else Date.FromText(Text.From(_ + 19000000)),
DateConversion = Table.TransformColumns(Source,{{"DateCol_1", DateFunction, type date},{"DateCol_2", DateFunction, type date},{"DateCol_3", DateFunction, type date}})

Dudo que esto sea realmente muy diferente desde el punto de vista del rendimiento, pero lo hace mucho más ordenado desde la perspectiva del código, lo cual es útil cuando tienes muchas columnas de fecha. Potencialmente, podría haber algunos problemas alrededor de 1900-01-02 a 1900-02-29, según otra publicación que vi, pero eso no debería ser un problema en los datos AS400. Se podría agregar más código para manejar las fechas 9999999, pero ese debería ser un cambio bastante simple que podría realizarse en la sección DateFunction:

DateFunction = each if _ = 0 then null else if _ = 9999999 then Date.From("9999/12/31") else Date.FromText(Text.From(_ + 19000000))

¡Ojalá ayude a otros pobres que tienen que trabajar con datos AS400!

mgonza1

En respuesta a emarc1

¡Hola! ¿Dónde puedo ejecutar las dos líneas de código que dices?
¿Tengo que invocar una función personalizada?

¡Saludos!

emarc1

En respuesta a mgonza1

Lo acababa de usar en Power Query. Puede hacer clic con el botón derecho en una consulta existente en Power Query y abrirla con el editor avanzado. El código que di debe ir en el dejar cuadra. Lo puse inmediatamente después de la función de transformación ‘Fuente’, pero podría ir a otra parte si se ajusta. Deberá ajustar la matriz (el bit {{x}, {y}, {z}}) en la función ‘DateConversion’ para su conjunto de datos y también ajustar cualquier otra función después, esa referencia ‘Fuente’ para extraer ‘DateConversion’ en su lugar. p.ej:

let
    Source = Odbc.Query("dsn=dsn_name", "select x from y when z"),
    DateFunction = each if _ = 0 then null else Date.FromText(Text.From(_ + 19000000)),
    DateConversion = Table.TransformColumns(Source,{{"DateCol_1", DateFunction, type date},{"DateCol_2", DateFunction, type date},{"DateCol_3", DateFunction, type date}}),
    #"Renamed Columns" = Table.RenameColumns(DateConversion,{{"DateCol_1", "Date 1 Column Name"}, {"DateCol_2", "Date 2 Column Name"}, {"DateCol_3", "Date 3 Column Name"}})

in
    #"Renamed Columns"

@mesmollar

Como su próxima fecha es siempre el formato CYYMMDD, no creo que haya una mejor manera que truncar la «C» de la cadena de datos a través de Power Query o DAX. Puede considerar almacenar los datos de IBM en una base de datos relacional, luego puede personalizar una función y usar un procedimiento almacenado para ejecutar la conversión.

Saludos,

Deja un comentario

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