domingo, septiembre 28, 2014

El extraño caso de los guiones distintos

En el pasado hemos visto y analizado los extraños casos del signo + en Excel (que amplié en esta nota), del espacio inamovible (ASCII160) y del cálculo manual persistente.
Hoy voy a agregar un nuevo capítulo a la serie: el extraño caso de los guiones distintos

Veamos esta situación


En la celda B2 hemos tipeado el texto "Sucursal 1 - Norte"; en la celda C2 hemos copiado copiado el mismo texto escrito previamente en Word; la comparación de ambos textos, que suponemos idénticos, en la celda D2 da "FALSO".
El primer sospechoso es la presencia de espacios lo que podemos comprobar usando la función LARGO

Sin embargo la comparación en la celda D2 nos muestra que ambos textos tienen el mismo largo. Si bien los lectores más atentos habrán advertido la diferencia entre el guión en la celda B2 y el de la celda C2, esto no es siempre evidente; en particular si la hoja contiene grandes cantidades de datos.

Para encontrar el problema vamos a "destripar" los textos en sus componentes y compararlos uno por uno. Para hacerlo usaremos la función EXTRAE

En la celda Be ponemos la fórmula =EXTRAE($B$2,FILA()-3,1) y la copiamos hacia abajo hasta obtener todos los caracteres del texto; hacemos lo mismo en la celda C4 pero refiriéndonos al texto en la celda C2.
En la columna D comparamos entre la la columna B y la C. Inmediatamente vemos que el problema está en la fila 15, los guiones son distintos.

Cuando usamos el guión Word activa la autocorrección y lo convierte en en el guión un tanto distinto


Esta cambio pasa inadvertido (el menú para deshacer el cambio sólo aparece si apuntamos con el mouse al guión).
Esto no pasaría de ser una anécdota si no fuera porqué el mismo problema suele presentarse al importar textos de páginas WEB y de otras fuentes.

El remedio para esta situación es reemplazar el guión "largo" (em dash) por el guión "corto" (el guión "corto" es en realidad el signo menos; el guión largo se lo conoce como "em dash").
El reemplazo lo podemos hacer usando Buscar y Reemplazar (Ctrl L). Pero el problema es que el "guión largo" no está asociado a ninguna tecla en el teclado. Para poder "teclear" el guión largo usaremos la técnica conocida como Códigos Alt (Alt Codes). Sin deternos en la historia, la técnica consiste en mantener apretada la tecla Alt y pulsar el código del caracter en el teclado númerico (situado a la parte derecha del teclado). En nuestro caso el código del "em dash" es 0150




miércoles, septiembre 10, 2014

La función MONEDA de Excel

¿Alguien usó alguna vez la función MONEDA de Excel? La función MONEDA y sus dos "primas hermanas" MONEDA.FRAC y MONEDA.DEC pertenecen esa colección de funciones que ni siquiera sabíamos que existen.

Según la ayuda en línea de Excel el objetivo de la función MONEDA es convertir un número en texto usando formato de moneda


Introducimos un número (o referencia a una celda que contiene un número), definimos la cantidad de decimales y el resultado es el número precedido por el símbolo de la moneda (de acuerdo a las definiciones del sistema). Lejos de ser la función más sofisticada de Excel.

Las mencionadas "primas" tienen usos que pueden ser útiles en ciertas circunstancias. EL objetivo original de la función MONEDA.FRAC, siempre de acuerdo a la ayuda en línea de Excel, es:

Convierte una cotización de un valor bursátil, expresada en forma decimal, en fraccionaria. Use MONEDA.FRAC para convertir números decimales de moneda, como precios de valores bursátiles, en fracción.
En lugar de intentar explicar el significado de la definición, voy a mostrar un uso posible.

Por lo general los sistema de control de horarios usan la notación decimal. Por ejemplo, 2.5 horas representa 2 horas y 30 minutos; 2.75 representa 2 horas y 45 minutos. La forma decimal puede conducir a confusiones y ya hemos visto cómo convertir esta forma en formato horario:

  1. dividimos 2.75 por 24
  2. cambiamos el formato de la celda a [hh]:mm
  3. el resultado será 02:45

En lugar del formato horario podemos usar MONEDA.FRAC de la siguiente manera

=MONEDA.FRAC(A2,60)


La parte decimal del número muestra ahora los minutos (2 horas, 45 minutos).







lunes, septiembre 08, 2014

Pasar datos en filas o columnas a una matriz

En un post del año 2008 mostré como pasar los datos de una matriz (tabla bi-dimensional) a una fila o columna. Inmediatamente surge la pregunta: ¿cómo hacemos para pasar los datos de una columna o fila a una matriz de tamaño determinado?

Consideremos este ejemplo:

Queremos tomar los datos en el rango B2:B16 y pasarlos a una matriz de 5 filas y tres columnas tal como vemos en el rango E6:G10.

Si bien podemos hacerlo con fórmulas, vamos a mostrar una solución con macros, solución más flexible y práctica (podemos guardar la macro en el libro Personal y usarla en cualquier cuaderno sin necesidad de recrear las fórmulas en cada oportunidad).

Este video muestra como funciona la macro



El código de la macro es el siguiente:

Sub make_matrix()
    Dim Arr_1()
    Dim lnumRows As Long, lnumCols As Long
    Dim rngDestRange As Range, rngCellDest As Range
    Dim i As Long, j As Long, x As Long
    Dim lCounter As Long
 
     
    If Selection.Count < 4 Then
        MsgBox "Debe seleccionar un rango de por lo menos cuatro celdas", vbExclamation
        Exit Sub
    End If
 
    lnumRows = Application.InputBox("Cuantas filas en la matriz?", "Filas", , , , , , 2)
    lnumCols = Application.InputBox("Cuantas columnas en la matriz?", "Columnas", , , , , , 2)
 
    ReDim Arr_1(1 To lnumCols, 1 To lnumRows)
 
    Set rngCellDest = Application.InputBox("Posicion de la primera celda de la matriz", "Copiar matriz", , , , , , 8)
    Set rngDestRange = rngCellDest.Range(Cells(1, 1), Cells(lnumRows, lnumCols))
 
    lCounter = 0
 
    For i = 1 To lnumCols
        For j = 1 To lnumRows
            Arr_1(i, j) = Selection.Item(lCounter + 1)
            lCounter = lCounter + 1
        Next j
    Next i
 
    rngDestRange.Value = WorksheetFunction.Transpose(Arr_1)
 
 
End Sub


Antes de aplicar la macro debemos seleccionar el rango de las celdas que queremos convertir en matriz. Este rango debe ser unidimensional, fila o columna.

Una vez seleccionado accionamos la macro. En primer lugar la macro comprueba que se haya elegido un rango con por lo menos cuatro celdas (el amable lector me disculpará si no explico la razón de esta condición).

El segundo paso es determinar las dimensiones de la matriz, cuántas filas y cuantas columnas. En nuestro ejemplo el rango contiene 15 celdas, por lo que hemos definido una matriz de 5 x 3. El número de elementos en la matriz equivale al múltiplo de las dimensiones. Así por ejemplo, si definimos en nuestro ejemplo una matriz de 4 x 2, sólo los primeros 8 datos serán pasados a la matriz.

El tercer paso es determinar la posición de la primer celda de la matriz.

Una vez que hemos definido todos los parámetros usamos la orden

ReDim Arr_1(1 To lnumCols, 1 To lnumRows)

para definir un array que contenga los datos que queremos que aparezcan en la hoja.

Luego usamos este loop para introducir los datos en el array

    For i = 1 To lnumCols
        For j = 1 To lnumRows
            Arr_1(i, j) = Selection.Item(lCounter + 1)
            lCounter = lCounter + 1
        Next j
    Next i

El último paso es pasar los datos a la hoja:

rngDestRange.Value = WorksheetFunction.Transpose(Arr_1)

Nótese que usamos Transpose par invertir los datos del array que pasamos a la matriz en la hoja.

El cuaderno con el ejemplo y la macro puede descargarse aquí.