miércoles, 29 de enero de 2014

Cursos Macros online con tutor personal Excelforo.

Seguramente en más de una ocasión has deseado aprender a programar en VBA para Excel, o simplemente te lo hayan requerido para algún puesto de trabajo, si es así, necesitas aprender con los mejores: edición de Cursos de Excel y Macros online con tutor personal de febrero de 2014.

Los cursos de Excel y Macros abiertos para este mes de febrero son:

Curso Macros Iniciación

(ver más)

Curso Macros Medio

(ver más)


Curso Excel Avanzado para versiones 2007/2010

(ver más)

Curso Excel Nivel Medio

(ver más)

Curso Excel Financiero

(ver más)

Curso Tablas dinámicas en Excel

(ver más)

Curso preparación MOS Excel 2010 (Examen 77-882)

(ver más)


Esta nueva edición de Cursos de Excel y macros en modalidad elearning (online) comienzan el día 1 de febrero de 2014; y la matrícula estará abierta hasta el día 10.

Excelforo: con la confianza de siempre....estás a tiempo!!

También formación Excel a empresas. Explota los recursos a tu alcance (ver más).


Informarte sin compromiso en cursos@excelforo.com o directamente en www.excelforo.com.

martes, 28 de enero de 2014

VBA: ShellExecute o cómo abrir desde Excel otros archivos.

En un post anterior del blog expuse el empleo de una función API para reproducir un sonido (ver).
En esta ocasión comentaré una nueva función API que nos permitirá abrir cualquier tipo de archivo tan sólo informando de dónde se encuentra (cuál es su ruta), sin saber el nombre de la aplicación asociada; en respuesta a la pregunta planteada:

...una macro que logre hipervincular los nombres de varias imágenes (p.e. a.jpg, b.jpg, c.jpg, etc) que están en una columna, con las imágenes, propiamente dichas, que están en la siguiente carpeta: "D:\BancoFotos\". Para logra que con un click en el nombre de la imagen abra dicha imagen...


Antes de 'meternos en faena' me gustaría comentar, de manera muy superficial, qué es una API y cuán peligroso puede llegar a ser, si no se emplea adecuadamente... comenzar diciendo que antes de llamar a funciones de Microsoft Windows (API), debemos entender cómo las DLL de API de Windows tratan los argumentos y tipos de datos, ya que las llamadas incorrectas a funciones de Windows pueden causar errores de páginas no válidas u otro comportamiento imprevisto.
También podemos leer una introducción en Wikipedia


En nuestro ejercicio de hoy no existe peligro alguno, ya que sólo abriremos un fichero desde nuestra hoja de cálculo... para este trabajo emplearemos la función API ShellExecute.
Esta función API 'ShellExecute' dispone de seis parámetros, muchos de ellos opcionales:

1- hWnd: Identifica la ventana principal. Esta ventana recibe las cajas de mensajes que una aplicación produce (por ejemplo, para el informe de errores).
2- lpOperation: Especificamos la acción que queremos realizar al ejecutar nuestra función. Podrían ser entre otras las siguientes acciones:
  1. "Open" = nuestra función abrirá el archivo especificado por el parámetro siguiente 'lpFile'. El archivo podrá ser indistintamente un ejecutable (.exe) o cualquier otro tipo de documento (.jpg, .pdf, etc., etc.), incluso podría ser sencillamente una carpeta o directorio.
  2. "Print" = La función imprimiría el archivo indicado por 'lpFile', lógicamente el archivo deberá ser algún tipo de documento no ejecutable, ya que en caso de serlo, simplemente lo abriría... (si así estuviera indicado).
  3. "Explore" = La función 'exploraría' la carpeta/directorio indicada por 'lpFile'.
  4. "Play" = Para aquellos métodos que soportan una función Play, como archivos de sonido...
  5. "Properties" = Detallaría las propiedades del archivo.
  6. 0& = el argumento 'lpOperation' puede ser también NULL (vbNullString si declaramos la variable como String, o bien 0& si queda declarada de cualquier otra forma). En estos casos la función toma la acción por defecto, que es OPEN.
3- lpFile: Este argumento queda definido como una cadena (String) que especifica la ruta del archivo que queremos abrir, imprimir, explorar, etc. Recuerda, lo hemos visto antes, que la función puede abrir indistintamoente ejecutables o documentos de cualquier tipo, pero sólo puede imprimir archivos tipo documento.
4- lpParameters: Si hemos informado en el anterior 'lpFile' un archivo ejecutable (.exe), entonces 'lpParameters' será una cadena(String) que detalle los parámetros para que opere dicha aplicación. Si 'lpFile' fuera un archivo tipo documento, 'lpParameters' debería ser NULL (0& or vbNullString).
5- lpDirectory: Cadena que identifica la carpeta/directorio de trabajo por defecto.
6- nShowCmd : Cómo queremos ver la applicación cuando se ejecute y abra:
    Valor
  • 0 = oculta la ventana de activación y pasa a otra ventana.
  • 1 = Activa y muestra una ventana. Si la ventana está Minimizada o Maximizada , Windows la restaura a su tamaño y posición original (igual que 9 ).
  • 2 = Activa una ventana y la muestra en forma de icono .
  • 3 = Activa una ventana y lo muestra como una ventana Maximizada.
  • 4 = muestra una ventana en su tamaño más reciente y posición. La ventana que está actualmente permanece activa.
  • 5 = Activa una ventana y lo muestra en su actual tamaño y la posición.
  • 6 = Minimiza la ventana especificada y activa la ventana de nivel superior en la lista del sistema.
  • 7 = Muestra una ventana como un icono. La ventana que está actualmente activa permanece activa.
  • 8 = Muestra una ventana en su estado actual. La ventana que está actualmente activa permanece activa.
  • 9 = Activa y muestra una ventana. Si la ventana está Minimizada o Maximizada, Windows restaura a su tamaño y posición original (lo mismo que 1).


Añadiremos nuestro código en la Hoja de trabajo, asociándolo a un evento _BeforeDoubleClick:

Private Declare Function ShellExecute _
    Lib "shell32.dll" _
    Alias "ShellExecuteA" ( _
    ByVal hwnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) _
    As Long

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim strFile As String
Dim strAction As String
Dim lngErr As Long

'ruta del archivo.
strFile = "E:\excelforo\Fotos\" & Target.Value
'las acciones pueden ser OPEN, NEW u otras; todo depende de qué necesitemos
strAction = "OPEN"
'llamamos a la funicón API
lngErr = ShellExecute(0, strAction, strFile, "", "", 0)

End Sub



Estamos listos para trabajar, bastará hacer doble clic sobre una celda cualquiera de la hoja para que la función busque y abra el fichero (sea cual sea) en la ruta especificada cuyo nombre corresponda con el valor de la celda 'clicada'...

jueves, 23 de enero de 2014

VBA: Obtener el color de relleno o fuente de una celda (con o sin formato condicional).

En varias ocasiones me han preguntado por la forma de determinar el color de relleno o de la fuente de una celda, en especial, cuando dicha celda tiene configurado un Formato condicional... obviamente, para determinar tal color (de relleno o de fuente) se necesita algo de programación.
El problema es que no existe una forma directa de obtener el color de una celda cuando lo que tiene aplicado es un Formato Condicional, ya que las propiedades estándar .Color o .ColorIndex sobre la celda de estudio no devuelve valor (o mejor dicho lo devuelve como sin color) cuando lo que tiene es un formato condicional aplicado.

Me puse a investigar y encontré esta Function que desarrolló Rick Rothstein, la cual adapté un poco y a la que he incorporado las explicaciones oportunas.

Fijémonos en la imagen:

VBA: Obtener el color de relleno o fuente de una celda (con o sin formato condicional).


donde las celdas B2 y B12 sólo tiene aplicado un formato de celda 'estándar', mientras que las celdas del rango B3:B11 tienen aplicado el siguiente formato condicional:

VBA: Obtener el color de relleno o fuente de una celda (con o sin formato condicional).



La función que crearemos está construida sobre tres argumentos (dos de ellos opcionales, pero predefinidos como VERDADERO); el primero será la celda (sólo UNA!!) que queremos analizar, el segundo conforma si obtendremos el color de relleno o de la fuente (según un valor Booleano - V ó F), y el tercer argumento define si emplearemos la propiedad .Color o .ColorIndex para conseguir el código del color de Fuente o Relleno (tmabién utilizando un valor Booleano).

En un módulo del editor de VB incluimos la siguiente Function:

Function ColorCelda(celda As Range, _
        Optional ColorRellenoCelda As Boolean = True, _
        Optional ReturnColorIndex As Long = True) As Long
' ColorRellenoCelda - Opcional, tipo Boolean (valor por defecto = TRUE)
'                VERDADERO hace que nuestra función nos devuelva el color de Relleno,
'                según la propiedad de .Color o .ColorIndex
'                determinada en el valor del tercer argumento ReturnColorIndex
'                FALSO  hace que nuestra función nos devuelva el color de la Fuente,
'                según la propiedad de .Color o .ColorIndex
' ReturnColorIndex - Opcional, tipo Boolean (valor por defecto = TRUE)
'                    VERDADERO hará que nuestra función emplee la propiedad .ColorIndex
'                    FALSO hará que nuestra función emplee la propiedad .Color

Dim X As Long
Dim Test As Boolean
Dim CeldaActiva As String

Application.Volatile

CeldaActiva = ActiveCell.Address
'recorremos todos los formatos condicionales existentes en la celda de estudio
For X = 1 To celda.FormatConditions.Count
  With celda.FormatConditions(X)
    'si la condición responde al Valor de una celda
    'sabiendo que .Formula1 y .Formula2 son los valores que podemos informar al configurar nuestro formato condicional
    If .Type = xlCellValue Then
      Select Case .Operator
        'Evaluate equivaldría a la función INDIRECTO de la hoja de cálculo
        'convierte, por tanto, un nombre de Microsoft Excel en un objeto, valor o referencia.
        Case xlBetween:      Test = celda.Value >= Evaluate(.Formula1) And celda.Value <= Evaluate(.Formula2)
        Case xlNotBetween:   Test = celda.Value <= Evaluate(.Formula1) Or celda.Value >= Evaluate(.Formula2)
        Case xlEqual:        Test = Evaluate(.Formula1) = celda.Value
        Case xlNotEqual:     Test = Evaluate(.Formula1) <> celda.Value
        Case xlGreater:      Test = celda.Value > Evaluate(.Formula1)
        Case xlLess:         Test = celda.Value < Evaluate(.Formula1)
        Case xlGreaterEqual: Test = celda.Value >= Evaluate(.Formula1)
        Case xlLessEqual:    Test = celda.Value <= Evaluate(.Formula1)
      End Select
    'si por contra la condición corresponde a una expresión o fórmula
    ElseIf .Type = xlExpression Then
      Application.ScreenUpdating = False
      celda.Select
      Test = Evaluate(.Formula1)
      Range(CeldaActiva).Select
      Application.ScreenUpdating = True
    End If

    'Verificamos nuestra comparativa Test, cuando sea VERDADERA
    If Test Then
      If ColorRellenoCelda Then
        'y además nuestro segundo y tercer argumento se han informado como CIERTOS
        'controlando el tercer argumento con la función VBA IIf
        ColorCelda = IIf(ReturnColorIndex, .Interior.ColorIndex, .Interior.Color)
      Else
        'pero si nuestro segundo argumento es FALSO y el tercer argumento se ha informado como CIERTO
        'controlando el tercer argumento con la función VBA IIf
        ColorCelda = IIf(ReturnColorIndex, .Font.ColorIndex, .Font.Color)
      End If
      'salimos de la función...
      Exit Function
    End If
  End With
Next
  
'si no tuviera Formato condicional aplicado...
If ColorRellenoCelda Then
  'y si hubieramos indicado como CIERTO el segundo argumento
  ColorCelda = IIf(ReturnColorIndex, celda.Interior.ColorIndex, celda.Interior.Color)
Else
  'y si hubieramos indicado como FALSO el segundo argumento
  ColorCelda = IIf(ReturnColorIndex, celda.Font.ColorIndex, celda.Font.Color)
End If
End Function

De especial interés en esta Function es el empleo que se hace de la propiedad .Type del formato condicional (.FormatConditions(i).Type), con el que averigüamos o controlamos el tipo de Formato Condicional de la celda analizada. Especifica si el formato condicional está basado en el valor de una celda. Nombre Valor Descripción xlCellValue --- 1 --- Valor de celda xlExpression --- 2 --- Expresión xlColorScale --- 3 --- Escala de colores xlDatabar --- 4 --- Barra de datos xlTop10 --- 5 --- 10 valores más frecuentes XlIconSet --- 6 --- Conjunto de iconos xlUniqueValues --- 8 --- Valores únicos xlTextString --- 9 --- Cadena de texto xlBlanksCondition --- 10 --- Condición de celdas que están en blanco xlTimePeriod --- 11 --- Período de tiempo xlAboveAverageCondition --- 12 --- Condición por encima de la media xlNoBlanksCondition --- 13 --- Condición de celdas que no están en blanco xlErrorsCondition --- 16 --- Condición de errores xlNoErrorsCondition --- 17 --- Condición sin errores Es decir, si se trata de un Formato condional asociado al Valor de la celda:

martes, 21 de enero de 2014

Un reloj literal en español para Excel.

Navegando por Internet encontré una web de Excel con temas interesantes, y entre alguno de ellos, dí con un reloj literal en inglés (diseñado por Biegert and Funk), que decidí convertir al español.
Lo que aporta de especial este ejercicio es la buena combinación entre los Nombres definidos con fórmula, las constantes matriciales y los formatos condicionales.


Veamos en primer lugar el aspecto final del reloj:

Un reloj literal en español para Excel.


Lo especial de este reloj es el control que hacemos para mostrar los textos 'especiales' que empleamos en el momento de leer una hora, expresiones del tipo: '...menos cuarto' o '... y diez'.

Fundamental comenzar con la plantilla de letras en la hoja de cálculo, que debe ser exactamente igual a las constantes matriciales que definiremos a continuación. El orden en que aparecen hará que posteriormente resalten y lean la hora:

Un reloj literal en español para Excel.


El siguiente paso es también muy importante, ya que consiste en construir los diferentes Nombres definidos, algunos de ellos como Constantes matriciales:
Tres constantes matriciales:
arr_c ={0;"SONDLASDIEZ";"UNASEISTRES";"CUATROCINCO";"OCHOONCEDOS";"SIETETWDOCE";"YMENOSNUEVE";"DIEZEVEINTE";"AYCUARTORDC";"VEINTICINCO";"YMEDIAJUSTO"}
que coincide con las letras colocadas por fila en la hoja de cálculo

arr_h ={"UNA";"DOS";"TRES";"CUATRO";"CINCO";"SEIS";"SIETE";"OCHO";"NUEVE";"DIEZ";"ONCE";"DOCE"}
que nos dice las doce horas de un reloj

arr_m ={"";"CINCO";"DIEZ";"CUARTO";"VEINTE";"VEINTICINCO";"MEDIA"}
que nos leerá los minutos con intervalos de cinco minutos...

Resto Nombres definidos con fórmula:
My_h =AHORA()
nos dice la hora exacta del sistema

Round_h =MULTIPLO.INFERIOR(My_h;"0:05")
redondeamos la hora al minuto más cercano inferior múltiplo del intervalo de cinco minutos

My_m =MINUTO(Round_h)
obtenemos el minuto exacto de la hora del sistema

arr_r =FILA(Hoja1!$A$1:$A$11)
servirá para localizar la fila correcta dentro de la matriz de letras (diez filas de letras más la primera vacía)

t_1 =INDICE(arr_m;ABS((My_m>30)*60-My_m)/5+1)
devuelve la constante correspondiente al minuto a mostrar de entre los valores de la constante matricial de los Minutos (arr_m)

t_2 =INDICE(arr_h;RESIDUO(HORA(My_h)+(My_m>30);12)+12*(RESIDUO(HORA(My_h)+(My_m>30);12)=0))
devuelve la constante correspondiente a la hora a mostrar de entre los valores de la constante matricial de las Horas (arr_h)

n_1 =SI(My_m;MIN(SI(--SI(ESNUMERO(ENCONTRAR(t_1;arr_c));arr_r)>=7;arr_r));0)
lo utilizaremos junto con el formato condicional que resaltará las letras de la plantilla. Identifica los minutos.

n_2 =SI(t_2="";0;MIN(SI(--SI(ESNUMERO(ENCONTRAR(t_2;arr_c));arr_r)>0;arr_r)))
lo utilizaremos junto con el formato condicional que resaltará las letras de la plantilla. Identifica las horas.


Por ejemplo, digamos son las 11:26:53, del día 31/12/2013.
Entonces los diferentes valores devueltos serían:
My_h = 41639,47701 = 31-12-13 11:26:53 como hora del sistema
Round_h = 41639,47569 = 31-12-13 11:25:00 la hora redondeada
My_m = 25 el minuto de la hora redondeada
t_1 = VEINTICINCO sería el valor correspondiente de nuestra constante matricial arr_m.
t_2 = ONCE corresponde al texto de la hora dentro de la constante arr_h de las horas.
n_1 = 10 identifica que los minutos (VEINTICINCO) lo encontramos en la fila número 10 (contando la primera fila vacía), a efectos del formato condicional.
n_2 = 5 identifica que la hora (ONCE) lo encontramos en la fila número 5 (contando la primera fila vacía), a efectos del formato condicional.


Una vez configurados los nomnres definidos y por tanto los cálculos necesarios, rematamos. Hacemos visible en la hoja de cálculo, en nuestra plantilla, los valores obtenidos, es decir, configuramos los formatos condicionales.
Serán cinco formatos condicionales con fórmulas aplicados sobre nuestra plantilla de letras.
El primero remarcará de blanco la celda C9 (es decir la letra 'Y') cuando se cumpla la igualdad
=MEDIANA(My_m;1;30)=My_m
esto es, cuando el valor de My_m se encuentre en medio de los valores 1 y 30

Otro formato es el que resaltará el texto del rango I13:M13 (i.e., 'JUSTO') cuando
=My_m=0
cuando el minuto de la hora redondeada sea cero.

Un tercer formato que formateará el rango D9:H9 (texto 'MENOS') cuando
=My_m>30
es decir, cuando los minutos pasen de la media hora.

Un cuarto formato condicional aplicado al rango C9:M13 (texto de las letras que componen los minutos) con la fórmula:
=O((FILA(C9)-FILA($C$4)+2=n_1)*(COLUMNA(C9)=COLUMNA($C$3)+SI(t_1="";0;ENCONTRAR(t_1;INDICE(arr_c;n_1)))+FILA(DESREF($B$1;;;LARGO(t_1)))-2))
donde jugamos con el valor del nombre definido t_1 y n_1.

Y el último formato aplicado sobre el rango C4:M10 (texto de las letras que componen las horas) con la fórmula:
=O((FILA(C4)-FILA($C$4)+2=n_2)*(COLUMNA(C4)=COLUMNA($C$3)+SI(t_2="";0;ENCONTRAR(t_2;INDICE(arr_c;n_2)))+FILA(DESREF($B$1;;;LARGO(t_2)))-2))
donde jugamos con el valor del nombre definido t_2 y n_2.

jueves, 16 de enero de 2014

Cuando Excel muestra la fórmula y no el resultado....

Un frecuente error, y cuestión que me plantean los lectores del blog, es el que se produce (sin saber muy bien como) y para determinadas celdas (no para todas) Excel muestra la fórmula en lugar del resultado.
No podría asegurarlo al 100%, pero diría que es algo que se produce cuando cambiamos de versiones de Excel, en especial, cuando trabajamos con ficheros de versiones anteriores a 2007 (2003, etc) en las 'nuevas' 2007 +. He leído y leído al respecto, pero no hay respuesta ni consenso de cuál puede ser la causa de esta situación.
Fijémonos que estoy hablando que el fallo ocurre para determinadas celdas... es decir, hemos descartado que tenemos presionado la opción Mostrar fórmulas.


Veamos en la imagen un ejemplo de este problema:

Cuando Excel muestra la fórmula y no el resultado....


Vemos en la imagen como las primeras celdas de nuestro listado de vínculos (fórmulas) aparecen mostrando la fórmula, mientras que el resto muestra el resultado correcto del vínculo.

La solución, una vez descartado lo obvio (que no esté presionado Mostrar fórmulas), sería verificar que el formato de esas celdas no es de Texto, y lo cambiaremos a Número o General (o cualquier otro diferente de Texto); no debería fallar aunque su formato fuera Texto... pero nos preocuparemos sólo de la solución...
Ahora viene la solución para los casos en que sean pocas celdas donde ocurra el error (como en mi ejemplo). Iremos celda a celda editándolas y verificándola, es decir, celda a celda accediendo a la barra de fórmulas (o presionando la tecla de función F2) y luego validando con Enter. De esta manera la fórmula/vínculo mostrará el resultado correcto.
Por ejemplo, edito la celda B2, seleccionándola y presionando la tecla de función F2 y a continuación valido con Enter...

Cuando Excel muestra la fórmula y no el resultado....


Si las fórmulas fueran arrastables también serviría esta opción, o copiarla y pegarla (siempre que se pueda), pero teniendo presente que primero debemos haber cambiado el formato a General o Número (alguno No Texto).

Asi que, recapitulando, fundamental cambiar a algún formato NO Texto, y a continuación copiar y pegar la fórmula de nuevo, arrastrarla si es posible, o bien, en el peor de los casos, en que no podamos por el tipo de fórmula, ir editando fórmula a fórmula y validándolo de nuevo.

martes, 14 de enero de 2014

Mostrar valores como Diferencia de... en las Tablas dinámicas de Excel.

Hace algunas semanas, en una formación, una alumna me preguntaba sobre la manera de obtener en una Tabla dinámica un diferencia entre elementos de un campo, a modo de comparativa de incremento/decremento.
Hoy contaré cómo, de una manera bastante sencilla, podemos conseguir el resultado esperado aplicando las Herramientas de tabla dinámica: Mostrar valores como.

Partiremos de un origen de datos sencillo con tres campos, y del que queremos obtener para cada Concepto la Diferencia del Importe respecto del Año anterior:

Mostrar valores como Diferencia de... en las Tablas dinámicas de Excel.



Construiremos nuestra Tabla dinámica agregando el campo Concepto al área de filas, el campo Año al área de columnas y dos veces el campo Importe al área de valores, para que quede como vemos en la imagen siguiente:

Mostrar valores como Diferencia de... en las Tablas dinámicas de Excel.



En el siguiente paso (y último importante) seleccionaremos el campo Importe2 y accederemos a su Configuración de campo valor > Mostrar valores como, donde buscaremos la opción Diferencia de (hay más formas de acceder a esta herramienta...):

Mostrar valores como Diferencia de... en las Tablas dinámicas de Excel.


En nuestro ejemplo, ya que pretendemos conseguir la diferencia respecto al Año anterior, lo configuraremos tomando como base el campo 'Año' y como elemento base dentro del campo el 'Anterior':

jueves, 9 de enero de 2014

VBA: Una función personalizada de fórmula 3D.

Un par de años atrás escribí una entrada en el blog explicando algo más sobre las fórmulas tridimensionales (fórmulas 3D) en Excel (ver).
En particular, era interesante conocer las limitaciones en cuanto a operaciones a realizar sobre diferentes hojas: SUMA, PROMEDIO, PROMEDIOA, CONTARA, MAXA,MIN, MINA, PRODUCTO, DESVEST, DESVESTA, DESVESTP, DESVESTPA, VAR, VARA, VARP y VARPA.

La cuestión entonces es ¿qué ocurre si pretendo realizar una suma condicionada sobre varias hojas de un mismo libro?. La respuesta es clara, tendremos que crear nuestra UDF o función VBA personalizada.

Planteemos un ejemplo sencillo. Queremos sumar el valor de la celda A1 de diferentes hojas sólo cuando este valor sea mayor que 2014.
Tenemos un Libro con 5 hojas con datos en la celda A1 (valdría valores en un rango de celdas...):

VBA: Una función personalizada de fórmula 3D.


Y en una última hoja 'Total' queremos 'consolidar' los datos, pero sólo los mayores a 2014.
Es decir, sabemos que debemos consolidar las Hojas 1 a 5, que están seguidas/consecutivas en orden de disposición.

Añadiremos nuestro código asociándolo a un Módulo; para ello accederemos a la ventana de código del explorador del editor de VBA, donde insertaremos el siguiente código VBA:

Function Suma3Dmayor2014(celdas As Range) As Variant
Dim primerahoja As String, ultimahoja As String
'definimos cuáles son nuestras hojas límites...
    primerahoja = Hoja1.Name
    ultimahoja = Hoja5.Name

Dim HjInicio As Long, HjFin As Long
Dim HjActual As Long
Dim Addr As String
Dim rng As Range
Dim SumaAcum As Double
Dim SheetDataRange As Range

Application.Volatile

With ThisWorkbook.Worksheets
    ' Si se produce un error, construir el mensaje de error
    ' Inicializa el controlador de error.

    On Error Resume Next
    Err.Clear
    
    'controlamos el tipo posible de error
    'si no existiera la Hoja1
    HjInicio = .Item(primerahoja).Index
    If Err.Number <> 0 Then
        Suma3Dmayor2014 = CVErr(xlErrRef)
        Exit Function
    End If
    'si no existiera la Hoja5
    HjFin = .Item(ultimahoja).Index
    If Err.Number <> 0 Then
        Suma3Dmayor2014 = CVErr(xlErrRef)
        Exit Function
    End If
    'si por alguna causa la Hoja Inicial (Hoja1) no está situada a la izquierda de la Hoja final (Hoja5)
    If HjInicio > HjFin Then
        Suma3Dmayor2014 = CVErr(xlErrRef)
        Exit Function
    End If
    'si no hemos identificado qué celda/s sumar en nuestra función
    If celdas Is Nothing Then
        Suma3Dmayor2014 = CVErr(xlErrRef)
        Exit Function
    End If
    
    ' Addr es la dirección del rango indicado en nuestra función UDF para sumar.
    Addr = celdas.Address
    'recorremos las diferentes hojas desde la Hoja1 a la Hoja5
    For HjActual = HjInicio To HjFin
        'Usamos Addr para construir un rango de valores.
        Set SheetDataRange = .Item(HjActual).Range(Addr)
        'recorremos el rango de celdas por las hojas de estudio
        For Each rng In SheetDataRange.Cells
            If Len(rng.Value) > 0 Then
                    If rng.Value > 2014 Then
                        'acumulamos los valores que cumplan nuestra condición >2014
                        SumaAcum = SumaAcum + rng.Value
                    End If
            End If
        Next rng
    Next HjActual
End With

'Suma final llevada a la Hoja de cálculo.
Suma3Dmayor2014 = SumaAcum
End Function



Listos para probarla, en alguna celda de la hoja de cálculo, por ejemplo en la celda C1 de la hoja Total escribimos:
=Suma3Dmayor2014(A1)
el resultado será de 4.031 (es decir, 0+0+0+2015+2016 0 4.031), esto es, sólo ha sumado los importes de las diferentes hojas, en la celda informada en nuestra función A1, que cumplen la condición definida (valores mayores a 2014).

martes, 7 de enero de 2014

Regla matemática de Formato Condicional para Conjunto de Iconos.

Hace un par de semanas un lector me planteaba una pregunta que me resultó curiosa, ya que creía obvia hasta que intenté responderle... La preguntaba fue cuál es la regla matemática que aplica un formato condicional de conjunto de iconos para dar los saltos entre flechas/icónos??:

...En la columna B, coloqué nros entre 10 y 100, y ya en ese caso no entiendo porqué el valor 30 y 40 lo coloca con flecha hacia abajo, siendo que la regla dice que aquellos que sean menores a 25% se verán con flecha roja hacia abajo.
[...]
En concreto: cuando la regla dice se mostrarán con flecha roja los valores por debajo del 25 porcentual, que mostrará.
...



La Regla en cuestión es la estándar:

Regla matemática de Formato Condicional para Conjunto de Iconos.


Es decir aplicamos un conjunto de iconos (4 flechas) sobre un rango, forzando los cortes/saltos en los valores porcentuales 25%, 50% y 75%.

Veamos el planteamiento completo sobre nuestra hoja de cálculo:

Regla matemática de Formato Condicional para Conjunto de Iconos.



La primera idea que se nos puede pasar por la cabeza es que ya que nuestros valores (del rango de celdas) llegan de 10 hasta 100, los puntos de cambio de flechas irán como indica la ayuda de Microsoft: ... cuando desee ver todos los valores proporcionalmente, ya que al usar un porcentaje la distribución de los valores es proporcional, es decir, proporcionalmente repartidos entre 10 y 100 serían:
25%:= (100-10)x25% = 22,50
50%:= (100-10)x50% = 45,00
75%:= (100-10)x75% = 67,50
O quizá un razonamiemto algo más directo, algo del tipo, como el valor más alto es 100, los puntos críticos serían:
25%:= 100x25% = 25,00
50%:= 100x50% = 50,00
75%:= 100x75% = 75,00
Pero como vemos, todos ellos son erróneos!!. Podemos comprobar estas reglas, o verlas en la imagen anterior. Ninguna cumple.
¿Cuál es entonces la regla matemática que sigue nuestro Formato Condicional?


Desde luego sigue la idea dada por Microsoft, es decir, una distribución proporcional; pero algo más elaborada.
La regla es que a la diferencia entre el valor máximo y mínimo del rango de celdas de análisis, multiplicada por el valor porcentual le sumaremos el valor mínimo.
=(Máx-Min)*% + Mín
Lo vemos en la siguiente imágen, con los cálculos ya realizados:

Regla matemática de Formato Condicional para Conjunto de Iconos.


Observamos el cálculo realizado en las celdas G2:G4 para los tres valores porcentuales:
25%:= (100-10)x25% +10 = 32,50
50%:= (100-10)x50% +10 = 55,00
75%:= (100-10)x75% +10 = 77,50
además lo verificamos en el rango de celdas con el formato condicional B2:B11, es precisamente en esos valores donde se produce el cambio de sentido de la flecha (o icono).


Por supuesto este cálculo sirve para cualquier otro conjunto de iconos y cualquier rango de valores.
En la siguiente imagen vemos el resultado de aplicar un Semáforo a un conjunto de valores aleatorios ordenados entre 1153 y 2498:

jueves, 2 de enero de 2014

Cursos online con tutor de Excel y Macros por Excelforo.

Feliz año nuevo !!
Casi sin darnos cuenta empezamos con este 2014, y ya son unos pocos los que compartimos juntos en este maravilloso mundo de Microsoft Excel... Os deseo a todos que este nuevo año recién comenzado sea al menos igual, si no mejor, que este 2013 acabado.

Como todos los meses, dedico un poco de tiempo en mi acción formativa.
Un nuevo año sin subir precios... mantener la formación al alcance de todo el mundo es uno de mis objetivos.
Y para este nuevo año nada mejor que comenzar formándote e inviertiendo en conocimiento, y si además son formaciones estructuradas, y con un tutor detrás para apoyarte en lo que necesites, pues no hay nada mejor (al menos en formación online).
Si necesitas aprender con los mejores te interesa la edición de Cursos de Excel y Macros online con tutor personal de enero de 2014.


Los cursos de Excel y Macros abiertos para este mes de enero son:

Curso Macros Iniciación

(ver más)

Curso Macros Medio

(ver más)


Curso Excel Avanzado para versiones 2007/2010

(ver más)

Curso Excel Nivel Medio

(ver más)

Curso Excel Financiero

(ver más)

Curso Tablas dinámicas en Excel

(ver más)

Curso preparación MOS Excel 2010 (Examen 77-882)

(ver más)


Esta nueva edición de Cursos de Excel y macros en modalidad elearning (online) comienzan el día 1 de enero de 2014; y la matrícula estará abierta hasta el día 10.

Excelforo: con la confianza de siempre....estás a tiempo!!

También formación Excel a empresas. Explota los recursos a tu alcance (ver más).


Informarte sin compromiso en cursos@excelforo.com o directamente en www.excelforo.com.