viernes, marzo 18, 2016

Integrar datos de archivos cerrados con Power Query

Consolidar datos de distintos archivos es una tarea frecuente para todo analista que use Excel. Tal es así que este blog ha tratado el tema desde distintos ángulos: usando MS Query, Access, SQL, Vba (macros) y últimamente con Power Query.

La técnica que mostré en el post anterior puede parecer complicada e incluso intimidante para quien recién se inicia en el uso del Power Query (nueva interfaz, nuevo idioma). Para nuestra fortuna, Miguel Escobar publicó en el pasado una técnica sencilla, que pueden ver en esta nota (y continuada luego en esta otra nota), y que reproduzco aquí en una versión simplificada (parece ser que Miguel eliminó la versión en castellano del post).

Power Query nos permite consolidar datos de distintos archivos sin necesidad de abrirlos, sin tener que programar Vba, sin SQL, en pocos pasos y con facilidad.

En nuestro ejemplo deben cumplirse dos condiciones:

1 - los archivos deben tener la misma estructura (número y tipo de columnas);
2 - los archivos se encuentran en la misma carpeta.

Supongamos tres archivos con las ventas de una empesa imaginaria


Nuestra misión en consolidar los datos de los tres años en una única tabla que luego podremos analizar con tablas dinámicas, mejor aún, con PowerPivot.

Empezamos toda la carpeta a la ventana del Power Query


obteniendo este resultado en la ventana del editor del Power Query


Además de los tres de ventas, la carpeta contiene otros archivos así que filtramos la tabla dejando visibles sólo los archivos con la extensión ".xlsx"


Eliminamos todos los campos en la tabla excepto "Content" (Binary ) y "Name". Una de las tantas cosas buenas del Power Query es que podemos seleccionar las columnas que queremos dejar y elegir la opción Remove Other Columns (eliminar las otras columnas)

muy práctico cuando queremos eliminar la mayor parte de las columnas en el ventana.

Ahora viene el paso crítico en el proceso: vamos a crear una nueva columna, "Datos", definida con la fórmula =Excel.Workbook([Content],true)


¿Qué es esta expresión "=Excel.Workbook([Content],true)"? Power Query tiene su propio lenguaje de funciones (conocido como "M"). La función Excel.Workbook pertenece a la categoría de funciones que permiten acceder a distitnas plataformas de datos y extraerlos en forma de tabla. El valor "true" delsegundo argumento de la función hace que la primer fila de la tabla de datos de la hoja sea usada como encabezamiento de las columnas.

Al escribir la fórmula debemos tomar en cuenta que, a diferencia de las de Excel, en las funciones del lenguaje del Power Query las mayúsculas y minúsculas tienen importancia. Si escribimos =excel.workbook, resultará un error. Siguiendo con nuestro ejemplo, introducimos la fórmula y apretamos OK para crear la nueva columna. Este es el resultado




Ahora expandimos la columna Datos apretando la doble flecha en el lado derecho del encabezado de la columna


Power Query nos ofrece abrir todas las columnas de "Table" pero dejamos sólo la marca en "Data" y apretamos OK


Ahora expandimos la columna "Data"



En este caso vamos a dejar todas las columnas



Los próximos dos pasos son:

# - eliminar las columnas "Content" y  "Name" que, en nuestro caso, no cumplen ya ninguna función;
# - cambiar el tipo de dato de la columna Fecha de "any" (general) a "Date" (fecha)



El última paso es pasar (load) la tabla que hemos creado a una hoja de Excel o crear sólo una conexión


Si elegimos la primer opción (Close and Load), Excel exporta la tabla a una hoja del cuaderno



lunes, marzo 14, 2016

Excel y el problema de los separadores (definiciones regionales)

En más de una oportunidad a lo largo de la historia de este blog me he topado con el problema de los separadores y las definiciones regionales. En ciertos países se usa la coma para separar los miles  y el punto para los decimales mientras que en otros el uso se invierte.
Lo mismo sucede con los separadores de filas y columnas que usamos en las constantes matriciales. Si nos atenemos a la ayuda de Excel usaremos la coma para crear una constante matricial orientada horizontalmente


y el punto y coma para una orientada verticalmente


Sin embargo, en ciertas definiciones regionales, Excel usa el caracter "\" como separador.

Para saber qué caracteres usa Excel para los distintos separadores podemos usar una macro para exponer los valores de la propiedad Application.International. Esta tabla muestra los índices de los distitntos valores


El código para mostrar los valores en un MessageBox es el siguiente

 Sub mostrar_separadores()  
 Dim strSep As String  
 With Application  
   strSep = "Separador de elementos de matriz alternativo =" & .International(xlAlternateArraySeparator) & vbCrLf  
   strSep = strSep & "Separador de Columna =" & .International(xlColumnSeparator) & vbCrLf  
   strSep = strSep & "Separador Decimal =" & .International(xlDecimalSeparator) & vbCrLf  
   strSep = strSep & "Separador de Lista =" & .International(xlListSeparator) & vbCrLf  
   strSep = strSep & "Separador de Fila =" & .International(xlRowSeparator) & vbCrLf  
   strSep = strSep & "Separador de Miles =" & .International(xlThousandsSeparator) & vbCrLf  
   MsgBox (strSep)  
 End With  
 End Sub  

Al correr el código veremos este mensaje



jueves, marzo 10, 2016

Las funciones FILA() y COLUMNA()

Las funciones FILA() y COLUMNA() de Excel son de ese tipo de funciones que a primera vista parecen superfluas. FILA() da como resultado el número de fila de una referencia: COLUMNA() hace lo mismo en relación al número de columna de la referencia


Es decir, si ponemos en un celda =FILA(A4) el resultado será 4; si ponemos =FILA(), sin referencia, el resultado sera el número de fila de la celda que ocupa la fórmula.

El verdadero valor de esta funciones aparece cuando queremos crear series (vectores) de númenos enteros sucesivos lo que hacemos con una constante matricial.

En la nota sobre cálculo de vencimientos en día hábil usamos un constante matricial en esta fórmula

=MAX((C5+C4-{7;6;5;4;3;2;1;0})*(ESERROR(COINCIDIR(C5+C4-{7;6;5;4;3;2;1;0},Feriados,0)))*(DIASEM(C5+C4-{7;6;5;4;3;2;1;0},2)<6 span="">

(nótese el uso de "{" y "}" para crear la constante matricial y el ";" para indicar el sentido del vector). Esta notación tiene el problema de las definiciones regionales; en cierta definiciones se usa el "\" en lugar del punto y coma.
La función FILA supera este problema, ya que es independiente de las definiciones regionales:

=MAX((C5+C4+1-FILA(1:7))*(ESERROR(COINCIDIR(C5+C4+1-FILA(1:7);Feriados;0)))*(DIASEM(C5+C4+1-FILA(1:7);2)<6 span="">

Pero también esta notación tiene sus problemas ya que si copiamos la fórmula, la referencia cambia. Si ponemos en la celda A2 la fórmula =FILA(1:7), al copiarla a A3 veremos =FILA(2:8).

La solución es usar la función INDIRECTO de esta manera =FILA(INDIRECTO("1:7"))

Nótese que usamos comillas en la expresión "1:7", ya que INDIRECTO funciona con texto, no con valores numéricos.