🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA WorksheetFunction en Excel — llama a las propias funciones de Excel desde código (y las dos formas en que fallan)

|

VBA WorksheetFunction en Excel — llama a las propias funciones de Excel desde código (y las dos formas en que fallan)

TL;DRApplication.WorksheetFunction es la puerta por la que VBA alcanza las más de 450 funciones integradas de Excel, así que nunca reescribes SUM, VLOOKUP o COUNTIF como un bucle hecho a mano. Hay dos formas de llamar a una, y la diferencia lo es todo. Application.WorksheetFunction.VLookup(...) lanza un error de ejecución en cuanto no hay coincidencia — úsalo cuando esperas que tenga éxito y un fallo deba sonar fuerte. Application.VLookup(...) (quita el .WorksheetFunction) devuelve un valor de error que compruebas con IsError — úsalo cuando fallar es lo normal. Y la variable que recoge un resultado de Application.X debe ser un Variant, o revienta con el error 13 antes de que puedas comprobarlo.

' Cuantas veces aparece "West" en la columna B? Una linea, sin bucle.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sales")
Dim n As Long
n = Application.WorksheetFunction.CountIf(ws.Columns("B"), "West")
MsgBox "West appears " & n & " times"

Recurrir a un bucle For Each para sumar una columna, o para buscar un valor, es la forma más habitual en que VBA acaba siendo lento y con errores a la vez. Excel ya trae un motor de cálculo — cientos de funciones afinadas — y WorksheetFunction es la puerta a él. La habilidad no está en escribir más código; está en reconocer cuándo Excel ya tiene la función y llamarla. Esta guía se construye alrededor del único hecho con el que todo el mundo tropieza: hay dos estilos de llamada, y fallan de formas opuestas.

Lo que aprenderás

  • El modelo mental — toma prestado el motor de Excel, no lo reimplementes en un bucle
  • La regla más importante — WorksheetFunction.X revienta al fallar, Application.X devuelve un error que puedes comprobar
  • La trampa del tipo — por qué la variable que recibe el resultado debe ser un Variant
  • Qué funciones puedes llamar, cuáles no y las que no deberías
  • Pasar un rango entero en vez de recorrer celda a celda
  • WorksheetFunction frente a escribir una cadena de fórmula en una celda

El modelo mental: toma prestado el motor, no lo reconstruyas

Cada función de hoja que conoces — SUM, AVERAGE, VLOOKUP, MATCH, COUNTIF, SUMIF, MAX, TRIM, PROPER — está disponible desde VBA a través de Application.WorksheetFunction. No estás llamando a una copia de la función en VBA; estás llamando al mismo motor que usa la hoja, así que el resultado coincide exactamente con el de la fórmula.

Eso importa porque la alternativa casi siempre es peor. Un bucle For Each que suma una columna, cuenta coincidencias o rastrea una búsqueda es más largo de escribir, más lento de ejecutar y más fácil de equivocar que la única función que Excel ya optimizó. WorksheetFunction.Sum(ws.Range("B2:B100000")) devuelve en una sola pasada; el equivalente con bucle se arrastra por 100.000 iteraciones de VBA interpretado. Quédate con esta imagen — Excel tiene la función, yo solo tengo que llamarla — y la mayoría de las preguntas de «¿cómo calculo X en VBA?» se responden solas.

La regla más importante: dos estilos de llamada, dos modos de fallo

Esto es lo único que hay que llevarse. La misma función se puede llamar de dos maneras, y se comportan de forma completamente distinta cuando la operación falla — por ejemplo, cuando una búsqueda no encuentra nada.

' Estilo 1: WorksheetFunction.X - REVIENTA si no hay coincidencia.
Dim price As Double
price = Application.WorksheetFunction.VLookup("Widget", ws.Range("A:C"), 3, False)
' Si "Widget" no esta ahi: error de ejecucion 1004, y la ejecucion se detiene.
' Estilo 2: Application.X (sin .WorksheetFunction) - DEVUELVE un error que puedes comprobar.
Dim result As Variant
result = Application.VLookup("Widget", ws.Range("A:C"), 3, False)
If IsError(result) Then
    MsgBox "Widget not found"      ' gestionado con limpieza, sin reventar
Else
    MsgBox "Price is " & result
End If

La misma función, los mismos argumentos — pero WorksheetFunction.VLookup lanza un error cuando no hay coincidencia, mientras que Application.VLookup devuelve un valor de error #N/A que IsError atrapa. Ninguno es «correcto»; son para intenciones distintas:

  • Usa WorksheetFunction.X cuando esperas que la operación tenga éxito y un fallo significa que algo va de verdad mal. El reventón es una ventaja — detiene la macro en lugar de dejar que un valor malo fluya aguas abajo.
  • Usa Application.X cuando un fallo es un resultado normal que quieres gestionar — una búsqueda que puede encontrar su clave o no, un valor que casi siempre está. Compruebas IsError y ramificas.

El error número uno de todo este tema es usar WorksheetFunction.Match para comprobar si algo existe, y llevarte una sorpresa con el error 1004 cuando no. Las comprobaciones de existencia son justo el caso para Application.Match + IsError.

La trampa del tipo: el resultado debe ser un Variant

El estilo 2 solo funciona si la variable que recibe el resultado puede contener un valor de error. En VBA, solo un Variant puede. Decláralo con cualquier tipo más estrecho y la propia asignación estalla:

Dim result As Double
result = Application.VLookup("Widget", ws.Range("A:C"), 3, False)
' Si no se encuentra: error 13 "Type mismatch" - porque un Double no puede contener #N/A

La solución es simplemente Dim result As Variant. Entonces IsError(result) se puede llamar sin peligro, y si hay éxito usas el valor con normalidad. Esta es la segunda mitad silenciosa del patrón «devuelve un error»: los resultados de Application.X van a un Variant, siempre. Olvídalo, y el desajuste de tipo enmascara justo el manejo de errores que intentabas construir.

Qué funciones puedes llamar — y las que no deberías

Casi toda la biblioteca está disponible, pero vale la pena conocer tres aristas:

  • No todo está expuesto. Un puñado de funciones más nuevas o volátiles no aparecen en WorksheetFunction. Si falta un nombre, normalmente puedes recurrir a Application.Evaluate o escribir la fórmula en una celda (ver más abajo).
  • Algunas funciones VBA ya las tiene de forma nativa — usa esas. No llames a WorksheetFunction.Left, Mid, Right, Trim, Upper ni Lower. VBA tiene sus propias Left, Mid, Right, Trim, UCase, LCase que son más rápidas y no hacen ida y vuelta a Excel. (Un matiz: el Trim de VBA solo quita los espacios iniciales y finales, mientras que WorksheetFunction.Trim además colapsa los dobles internos — así que no son idénticos, y de vez en cuando quieres la versión de hoja.)
  • Los nombres a veces difieren. El nombre del miembro en VBA suele coincidir con la función, pero unos pocos arrastran la grafía interna antigua de Excel. Ante la duda, teclea Application.WorksheetFunction. y deja que IntelliSense liste lo que hay de verdad.

La regla práctica: echa mano de WorksheetFunction para las funciones analíticas pesadas en las que Excel es bueno — búsquedas, conteos y sumas condicionales, estadística — y usa las palabras clave propias de VBA para el trabajo básico de cadenas y matemáticas.

Pasa un rango entero, no recorras celda a celda

La mayor ganancia de velocidad es también la más fácil de pasar por alto. Las funciones de WorksheetFunction toman rangos, así que entrégales el rango entero una vez en lugar de recorrer y llamar por celda:

' LENTO - llama al motor una vez por fila.
Dim i As Long, total As Double
For i = 2 To lastRow
    total = total + ws.Cells(i, "B").Value
Next i

' RAPIDO - una llamada, el motor hace el bucle internamente.
total = Application.WorksheetFunction.Sum(ws.Range("B2:B" & lastRow))

La versión rápida no solo es más corta; empuja la iteración hacia el motor compilado de Excel en lugar de ejecutarla en VBA interpretado. Lo mismo vale para CountIf, SumIf, Average, Max, Min — dales el rango y deja que hagan el conteo. Si te descubres acumulando un total en un bucle, eso casi siempre es una función de hoja esperando a que la llames.

WorksheetFunction frente a escribir una fórmula en una celda

Hay una tercera opción, y saber cuándo preferirla mantiene tu código honesto. WorksheetFunction calcula un valor una vez, en código — la hoja nunca cambia, y la respuesta no se recalcula cuando lo hacen los datos. Escribir una cadena de fórmula en una celda (ws.Range("D2").Formula = "=SUM(B2:B100)") deja una fórmula viva que se actualiza para siempre.

Usa WorksheetFunction cuando necesitas un número ahora, dentro de tu lógica — un umbral que comparar, un conteo sobre el que ramificar, un total que estampar en un informe. Escribe una fórmula en la celda cuando el usuario deba ver un resultado que siga siendo correcto a medida que edita. Echar mano de WorksheetFunction y luego pegar su respuesta estática donde correspondía una fórmula es una forma habitual de que los informes queden obsoletos en silencio.

Cómo ayuda ExcelMaster

WorksheetFunction concentra una cantidad sorprendente de decisión en una sola llamada: cuál de los dos estilos usar, si el resultado necesita un Variant, si una palabra clave nativa de VBA sería mejor, y si el valor debería calcularse una vez o dejarse como una fórmula viva. Cada una de esas elecciones tiene un modo de fallo que devuelve una respuesta incorrecta — o revienta con datos que no probaste.

ExcelMaster te deja describir el cálculo en su lugar. Di «cuenta cuántos pedidos son de la región West» o «busca el precio de cada producto y marca los que no tenemos en stock», y elige el estilo de llamada correcto — el que revienta cuando un fallo es un error real, el que se puede comprobar cuando un fallo es lo esperado — declara el resultado como Variant cuando debe, y pasa rangos enteros en vez de recorrerlos. Te quedas con el libro y con el código; te ahorras la parte en la que un error 1004 sin gestionar detiene una macro a mitad de un informe.

Preguntas frecuentes

¿Cuál es la diferencia entre WorksheetFunction y Application en VBA?

Ambos llaman a la misma función de Excel, pero fallan de forma distinta. Application.WorksheetFunction.X lanza un error de ejecución (normalmente 1004) cuando la función no puede devolver un resultado, como una búsqueda sin coincidencia. Application.X — sin .WorksheetFunction — devuelve en su lugar un valor de error de Excel como #N/A, que compruebas con IsError. Usa el primero cuando el fallo deba detener la macro, el segundo cuando un fallo sea un caso normal que gestionar.

¿Por qué WorksheetFunction.VLookup da el error 1004?

Porque WorksheetFunction.VLookup lanza un error de ejecución cuando el valor no se encuentra, en lugar de devolver #N/A. Ahí el error 1004 casi siempre significa «no hay coincidencia», no una fórmula rota. Si esperas que algunas búsquedas fallen, llama a Application.VLookup sobre un Variant y comprueba IsError(result), o envuelve la llamada a WorksheetFunction en un manejo On Error.

¿Por qué obtengo un desajuste de tipo (error 13) con Application.VLookup?

Porque Application.VLookup puede devolver un valor de error, y solo un Variant puede contenerlo. Declarar la variable que lo recibe como Double, Long o String provoca el error 13 en el instante en que el resultado es #N/A. Decláralo As Variant, y luego llama a IsError antes de usar el valor.

¿Puedo usar cualquier función de Excel en VBA a través de WorksheetFunction?

Casi todas, pero no todas. Las funciones analíticas comunes — VLOOKUP, MATCH, COUNTIF, SUMIF, SUM, AVERAGE, estadística — están todas. Unas pocas funciones más nuevas o volátiles no están expuestas; para esas, usa Application.Evaluate o escribe la fórmula en una celda. Y para texto y matemáticas básicas, prefiere las propias Left, Mid, Trim, UCase y operadores de VBA antes que las versiones de hoja.

¿Es WorksheetFunction.Sum más rápido que un bucle en VBA?

Sí, de forma notable, en rangos grandes. Pasar el rango entero a WorksheetFunction.Sum ejecuta la iteración dentro del motor compilado de Excel en una sola llamada, mientras que un bucle For Each o For la ejecuta en VBA interpretado celda a celda. Siempre que estés acumulando un total o un conteo en un bucle, una función de hoja llamada sobre el rango entero suele ser a la vez más corta y más rápida.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 10/08/2026.

Guías relacionadas: VBA VLOOKUP · VBA eliminar duplicados · VBA Filtro avanzado · VBA For Loop · VBA Range