miércoles, 31 de julio de 2019

Power Query: Eliminar espacios en blanco sobrantes

Hoy lucharemos, con Power Query, con una situación siempre incomoda como son los espacios en blanco sobrantes.

Power Query: Eliminar espacios en blanco sobrantes



Sin duda en la hoja de cálculo la solución es simple, usar la función ESPACIOS(texto), la cual elimina por el principio, por el final y por medio los espacios en blanco sobrantes...
Solo una limitación, elimina solo el caracter espacio en blanco.


En el entorno de Power Query (Obtener y transformar) disponemos de las siguientes funciones de Texto:
Text.TrimStart(texto inicial, opcional caracter a eliminar):
Elimina el caracter indicado, o el espacio en blanco si se omite, pero solo por el inicio del texto (por la izquierda)
Text.TrimEnd(texto inicial, opcional caracter a eliminar):
Elimina el caracter indicado, o el espacio en blanco si se omite, pero solo por el final del texto (por la derecha)
y
Text.Trim(texto inicial, opcional caracter a eliminar):
Elimina el caracter indicado, o el espacio en blanco si se omite, pero por el inicio y final del texto (NO en medio!!!)


Podemos ver el efecto en la imagen anterior, donde se observa el efecto de aplicar Text.Trim al campo inicial

Power Query: Eliminar espacios en blanco sobrantes


Comprobamos con el conteo de caracteres añadido, como se han eliminado los espacios sobrantes a izquierda y derecha, pero se mantienen los espacios duplicados en medio de los textos!!.

Un pequeño contratiempo para Power Query, que a cambio ofrece la opción de 'limpiar' de cualquier caracter (y no solo del espacio en blanco como la función ESPACIOS) las cadenas de texto.


La solución la encontré leyendo a Ken Puls donde mostraba como crear una función personalizada en el editor de Power Query que replicara el efecto deseado.
Puedes recordar aquí como crear una función en Power Query.

La función tendría esta forma:
(texto_inicial as text, optional caracter_a_eliminar as text) =>
//Función creada por Ken Puls de excelguru.ca
let
    //Identificamos el caracter a eliminar... si no indicamos nada cogerá un 'espacio en blanco'
    caracter = if caracter_a_eliminar = null then " " else caracter_a_eliminar,
    //Separamos la cadena de texto por el caracter, en diferentes palabras o partes
    split = Text.Split(texto_inicial, caracter),
    //solo nos quedamoso con las partes que contengan algo..
    //esto es, dejamos fuera las partes de los espacios en blanco
    EliminaEspacios = List.Select(split, each _ <> ""),
    //y finalmente, de las partes no vacías anteriores, recomponemos el texto inicial
    //ya limpio de esos caracteres indicados...
    Resultado_limpio=Text.Combine(EliminaEspacios, caracter)
in
    Resultado_limpio

Power Query: Eliminar espacios en blanco sobrantes



Con la función creada, la ponemos a prueba con la consulta siguiente:
let
    Origen = Excel.CurrentWorkbook(){[Name="Tabla1"]}[Content],
    #"Tipo cambiado" = Table.TransformColumnTypes(Origen,{{"textos", type text}, {"Num caracteres", Int64.Type}}),
    #"Personalizada agregada" = Table.AddColumn(#"Tipo cambiado", "Text.Trim", each Text.Trim([textos])),
    #"Personalizada agregada1" = Table.AddColumn(#"Personalizada agregada", "Contar1", each Text.Length([Text.Trim])),
    #"Personalizada agregada2" = Table.AddColumn(#"Personalizada agregada1", "Elimina Espacios", each EliminaEspacios([textos])),
    #"Personalizada agregada3" = Table.AddColumn(#"Personalizada agregada2", "Contar2", each Text.Length([Elimina Espacios]))
in
    #"Personalizada agregada3"


Power Query: Eliminar espacios en blanco sobrantes



Comprobamos como ahora si, en el campo 'Elimina Espacio', el uso de nuestra función, limpia de los caracteres no deseados el texto de partida.

Power Query: Eliminar espacios en blanco sobrantes

miércoles, 17 de julio de 2019

Power Query: Recuperar datos de otras filas

Hoy veremos como Power Query nos permite recuperar información de otras filas dentro de la misma tabla...
En este ejemplo emplearemos una Columna personalizada.

Power Query: Recuperar datos de otras filas



Como siempre cargaremos nuestra tabla en la hoja de cálculo (llamada 'Tabla1') desde la ficha Datos > grupo Obtener y transformar > botón Desde tabla o rango.
Esto nos abrirá el Editor de Power Query donde realizaremos algunas acciones...
1- agregaremos una columna índice desde el menú de Agregar columnas - grupo General - botón Columna de índice - Desde 1

Power Query: Recuperar datos de otras filas


2- agregamos una Columna personalizada desde el menú de Agregar columnas - grupo General - botón Columna personalizada

Power Query: Recuperar datos de otras filas


Este condicional es clave ya que es la acción que recupera datos de otra fila.
La clave es el uso de los corchetes:
#"Índice agregado"{[Índice]} [#"Cód artículo"]
aquí empleamos el valor de cada fila del campo 'Índice' (que definimos de 1 a 20) para recuperar el valor del campo 'Cód artículo'... jugamos con la numeración real de los registros que internamente empieza en cero!!, así al indicar fila 1 estamos refiriéndonos a la segunda fila real...


3- eliminamos las filas con error. Desde el menú Inicio - grupo Reducir filas - botón Quitar filas - Quitar errores

Power Query: Recuperar datos de otras filas



4- Filtramos los NO 'null' por el campo 'Descripción'.

Power Query: Recuperar datos de otras filas



El código completo generado con las acciones realizadas:
let
    Origen = Excel.CurrentWorkbook(){[Name="Tabla1"]}[Content],
    #"Tipo cambiado" = Table.TransformColumnTypes(Origen,{{"Fecha compra", type date}, 
                                                          {"Cód artículo", type text}, 
                                                          {"Unidades", Int64.Type}}),
    #"Índice agregado" = Table.AddIndexColumn(#"Tipo cambiado", "Índice", 1, 1),
    #"Personalizada agregada" = Table.AddColumn(#"Índice agregado", "Descripción", 
            each if #"Índice agregado"{[Índice]} [Fecha compra] = null then 
                #"Índice agregado"{[Índice]} [#"Cód artículo"] 
            else 
                if #"Índice agregado"{[Índice]} [Índice] <= Table.RowCount(#"Índice agregado")-1 then null else null
                                                                                                                     ),
    #"Errores quitados" = Table.RemoveRowsWithErrors(#"Personalizada agregada", {"Descripción"}),
    #"Filas filtradas" = Table.SelectRows(#"Errores quitados", each ([Descripción] <> null))
in
    #"Filas filtradas"


Finalmente Cerraremos y cargaremos la consulta y llevaremos el resultado a la hoja deseada...

miércoles, 10 de julio de 2019

VBA: Menú Contextual personalizado

Hoy profundizaremos en un tema que ya tocamos tiempo atrás: los menús personalizados
Puedes revisar esta lectura.

La idea es crear nuestro propio menú contextual personalizado.

VBA: Menú Contextual personalizado



Para ello, insertamos en la ventana de código de un módulo estándar el siguiente código:

'En primer lugar ejecutar la macro 'Crear_Men_Contextual'
'a continuación podremos lanzar la macro siguiente:
Sub Mostrar__MenuContextualPersonalizado()
'Mostrar el menú creado
Application.CommandBars("MiMenu").ShowPopup
End Sub

Sub Eliminar_MenuContextualPersonalizado()
'eliminar el menú creado
Application.CommandBars("MiMenu").Delete
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Sub Crear_Menu_Contextual()
Dim miMenu As CommandBar
Dim submenu As CommandBarPopup
Dim opcion1 As CommandBarButton, opcion2 As CommandBarButton
Dim opcion3_1 As CommandBarButton, opcion3_2 As CommandBarButton, opcion3_3 As CommandBarButton

'creamos el menú
Set miMenu = Application.CommandBars.Add(Name:="MiMenu", Position:=msoBarPopup, MenuBar:=False, Temporary:=True)
'añadimos elementos al menú contextual...
With miMenu
    'un primer elemento
    Set opcion1 = .Controls.Add(Type:=msoControlButton) 'tipo botón
    With opcion1
        .Caption = "Primer elemento"    'el texto que aparece visible
        .FaceId = 71            ' el icono asociado
        .OnAction = "Macro1"    'la acción o macro a realizar
    End With
    'un segundo elemento
    Set opcion2 = .Controls.Add(Type:=msoControlButton) 'tipo botón
    With opcion2
        .Caption = "Segundo elemento"   'el texto que aparece visible
        .FaceId = 72            ' el icono asociado
        .OnAction = "Macro2"    'la acción o macro a realizar
    End With
    'un submenú dependiente con desplegable de opciones
    Set submenu = .Controls.Add(Type:=msoControlPopup)
    With submenu
        .Caption = "Submenú"    'el texto que aparece visible...
        'un elemento dentro del submenú
        Set opcion3_1 = .Controls.Add(Type:=msoControlButton)   'tipo botón
        With opcion3_1
            .Caption = "Punto tres-uno"    'el texto que aparece visible
            .FaceId = 73            ' el icono asociado
            .OnAction = "Macro31"    'la acción o macro a realizar
        End With
        'otro elemento dentro del submenú
        Set opcion3_2 = .Controls.Add(Type:=msoControlButton)   'tipo botón
        With opcion3_2
            .Caption = "Punto tres-dos"      'el texto que aparece visible
            .FaceId = 74            ' el icono asociado
            .OnAction = "Macro32"    'la acción o macro a realizar
        End With
        'tercer elemento dentro del submenú
        Set opcion3_3 = .Controls.Add(Type:=msoControlButton)   'tipo botón
        With opcion3_3
            .Caption = "Punto tres-tres"      'el texto que aparece visible
            .FaceId = 75            ' el icono asociado
            .OnAction = "Macro33"    'la acción o macro a realizar
        End With
    End With
End With
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub Macro1()
MsgBox "Aprendiendo Excel...." & vbCrLf & "Primera acción principal"
End Sub
Sub Macro2()
MsgBox "Aprendiendo Excel...." & vbCrLf & "Segunda acción principal"
End Sub
Sub Macro31()
MsgBox "Aprendiendo Excel...." & vbCrLf & "Primera acción del submenú"
End Sub
Sub Macro32()
MsgBox "Aprendiendo Excel...." & vbCrLf & "Segunda acción del submenú"
End Sub
Sub Macro33()
MsgBox "Aprendiendo Excel...." & vbCrLf & "Tercera acción del submenú"
End Sub



Para personalizar los iconos mostrados lee la entrada siguiente.


Con el código generado el primer paso será ejecutar la macro: Crear_Menu_Contextual
Después podremos asociar un método abreviado a la macro Mostrar__MenuContextualPersonalizado (ver aquí).
El menú se hará visible donde tengamos el cursor activo.


El resultado es el esperado... al presionar nuestra combinación de teclas de acceso rápido abriremos nuestro menú contextual con las opciones definidas...

miércoles, 3 de julio de 2019

Gráfico de línea degradada a tres colores

Hace bastante tiempo generamos un gráfico de línea a tres colores (ver aquí), según ciertos valores...

Hoy veremos una alternativa algo más simple pero igualmente vistosa.
Partiremos de los datos del post anterior que muestran, para un intervalo de valores de -5 a 5, el resultado de la ecuación x3.

Gráfico de línea degradada a tres colores


El gráfico es un gráfico de línea 2D.

En el paso siguiente configuraremos los colores de la línea.
Para ello accederemos al Formato de series de datos > Opciones de series > Líneas > Línea degradada

Gráfico de línea degradada a tres colores


Y nos centraremos en modificar las opciones de:
Puntos de degradado
Color
Posición


En primer lugar añadiremos hasta un total de seis puntos de degradado presionando el icono de 'añadir'.

Gráfico de línea degradada a tres colores



A continuación, desde la barra de puntos, y tras ir seleccionándolos, vamos asignando los colores deseados.
Por ejemplo como se muestra en la imagen

Gráfico de línea degradada a tres colores


Notemos que para conseguir el aspecto de color homogéneo damos el mismo color a los puntos seguidos 1-2, 3-4 y 5-6.

Finalmente, con la opción de Posición o desde la misma barra los colocaremos en las posiciones de corte.
El primer punto al 0%
El segundo punto al 30%
(estos dos punto definen el primer intervalo de valores)

El tercer punto al 31%
El cuarto punto al 60%
(estos dos punto definen el segundo intervalo de valores, el de en medio)

El quinto punto al 61%
El sexto punto al 100%
(estos dos punto definen el último intervalo de valores)


El resultado es el esperado...

Gráfico de línea degradada a tres colores

lunes, 1 de julio de 2019

Excelforo: X aniversario y VI Premio Microsoft MVP Excel 2019-2020

DIEZ años juntos... no ha sido fácil ;-)
y por sexto año consecutivo (desde el 2014) he sido premiado por Microsoft con el título MVP (Most Vauable Professional) en Excel... (ver perfil)

Comenzar por agradeceos a todos vosotros por el apoyo mostrado durante todo este tiempo, sé que sin vosotros nada sería posible.
Agradecer, también, a Microsoft por este nuevo premio... tomo el reconocimiento como acicate para continuar difundiendo todo el conocimiento posible de nuestra hoja de cálculo favorita: Excel.

Excelforo: X aniversario y VI Premio Microsoft MVP Excel 2019-2020



Por otra parte, son diez años!! ya prestando la mejor formación presencial y elearning(online).
Sin olvidar todos aquellos clientes a los que las horas de consultoría han ahorrado tiempo y dinero.
Visita mi web:
www.excelforo.com


Como en años pasados, en este nuevo aniversario, mostraré algunos datos estadísticos acumulados hasta la fecha; respecto al blog diré que son ya más de 9.875.000 páginas vistas, y un 4.900.000 usuarios únicos de todo el mundo (España, México, Colombia, Perú, Chile, Argentina, Ecuador, Estados Unidos.. y un largo etcétera)...
Son ya más de 1.050 entradas publicadas, de casos prácticos propuestos por vosotros, solucionados y explicados; y más de 12.000 comentarios, y desde luego muchísimas horas dedicadas.

No quiero olvidar aventuras ya consolidadas, como el grupo de Facebook de Excel: Microsoft Excel en Español...
https://www.facebook.com/groups/ExcelEspanol/
donde lo especial es que trato de controlar al máximo los comentarios que no aporten nada (como publicidad de cursos, web, grupos, etc...), reduciendo el grupo a contenido de valor añadido.
Contento de alcanzar ya casi 8.000 seguidores!!
ÚNETE.. no lo dudes!

Pero sin duda la mayor satisfacción es y ha sido poder contestar personalmente todas las consultas presentadas, bien a través del correo bien a través de los comentarios del blog...

Mi eterno agradecimiento a todos vosotros.