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

VBA Function en Excel — Valores de retorno y funciones personalizadas (UDF)

|

VBA Function en Excel — Valores de retorno y funciones personalizadas (UDF)

Probado en: Excel 365 v2509 · Excel 2021 · Excel 2019 · última verificación el 07/06/2026

En resumen — Una Function es un procedimiento que devuelve un valor. Ese valor se devuelve asignándolo al propio nombre de la función — en VBA no existe la palabra clave Return. Y como una Function devuelve un valor, puedes escribirla directamente en una celda como tu propia fórmula (una UDF):

Function AgregarIVA(precio As Double, tasa As Double) As Double
    AgregarIVA = precio * (1 + tasa)   ' se asigna al NOMBRE — ese es el valor de retorno
End Function
En una celda:   =AgregarIVA(A2; 0,21)   ' tu propia fórmula, junto a SUMA y BUSCARX

Esa única capacidad — vivir dentro de una celda — es toda la razón de ser de las Functions junto a los Subs. Todo lo demás parte de ahí.

El modelo mental: una Function es un Sub que da el parte

Un Sub es un operario que hace una tarea y se marcha. Una Function es un operario que hace una tarea y luego te dice el resultado. La misma mecánica — un bloque de código con nombre, argumentos de entrada — con un añadido: sale un valor.

Esa salida hace que una Function sirva donde un Sub nunca podrá: dentro de una celda de la hoja. La cuadrícula de Excel está hecha para mostrar el resultado de una expresión, así que todo lo que devuelve un valor — SUMA, BUSCARX o tu AgregarIVA — puede ir en una celda. Un Sub no devuelve nada, así que Excel no tiene qué poner en la celda; escribe =SaludarUsuario() y obtienes #¿NOMBRE?. Quédate con esa imagen y la decisión Sub/Function se resuelve sola.

La única regla: devolver asignando al nombre (sin Return)

Este es el fallo que atrapa a todos los que vienen de Python, JavaScript o C#:

Function Descuento(precio As Double) As Double
    Descuento = precio * 0.9    ' ✅ en VBA se devuelve asignando al nombre de la función
End Function

Function Rota(precio As Double) As Double
    Return precio * 0.9         ' ❌ VBA no funciona así — devuelve 0 en silencio
End Function

Return existe en VBA, pero solo como pareja del antiquísimo GoSubno devuelve ningún valor. Si escribes Return (o si olvidas asignar el nombre), la función compila sin quejarse y devuelve en silencio el valor predeterminado de su tipo — 0, "" o Empty. Sin error, solo resultados equivocados. Si una UDF devuelve siempre 0, casi seguro olvidaste asignar su nombre.

Puedes asignar el nombre tantas veces como quieras (dentro es una variable normal); el valor que tenga al terminar la función es el que vuelve:

Function Nota(puntos As Long) As String
    Nota = "Suspenso"           ' predeterminado
    If puntos >= 50 Then Nota = "Aprobado"
    If puntos >= 80 Then Nota = "Sobresaliente"
End Function

Sub vs Function — la decisión en una línea

Olvida las largas tablas comparativas. Toda la elección es una pregunta:

¿Quien llama necesita una respuesta? Sí → Function. No → Sub.

Sub Function
Devuelve un valor No (asignar al nombre)
Usable en una celda No (es una UDF)
Aparece en el cuadro Macros (Alt+F8) Sí, si es Public y sin argumentos No
Tarea típica Hacer algo (dar formato, exportar, eliminar) Calcular algo (una tasa, una etiqueta, un texto limpio)

Una pista útil: si haces que un Sub meta su resultado en una variable global para que otro procedimiento lo lea, lo que querías era una Function. Devuelve el valor como es debido en vez de colarlo por una global.

Conviértela en función de hoja (UDF) — la función estrella

Pon la Function en un módulo estándar (Insertar → Módulo, no un módulo de hoja ni ThisWorkbook), y queda disponible al instante en la cuadrícula y en el autocompletado de fórmulas:

Function Iniciales(nombreCompleto As String) As String
    Dim partes() As String
    partes = Split(Trim(nombreCompleto), " ")
    Iniciales = Left(partes(0), 1) & Left(partes(UBound(partes)), 1)
End Function
=Iniciales("Ada Lovelace")  →  "AL"

Aquí es donde VBA compensa para los no programadores a tu alrededor: escribes la lógica una vez y tus compañeros la usan como cualquier función nativa, sin ver una línea de código.

La regla que rompe cada UDF nueva: una función de hoja solo devuelve a su propia celda

Esta es la limitación que genera mil hilos de foro. Cuando una Function se llama desde una celda, Excel la ejecuta en un modo protegido en el que no puede cambiar nada — no puede escribir en otras celdas, ni poner un color, ni renombrar una hoja, ni mostrar un MsgBox. Solo puede calcular y devolver el valor de la celda que la llamó.

Function Coloreame(c As Range) As String
    c.Interior.Color = vbYellow   ' ❌ NO hace nada al llamarse desde una celda
    Coloreame = "hecho"
End Function

Lo escribes, ves aparecer el texto pero ningún color, y concluyes que VBA está roto. No lo está — las UDF son puras por diseño. Si necesitas cambiar la hoja, ese es el trabajo de un Sub (activado por un botón o un evento), no de una UDF. Conocer esta línea ahorra horas: fórmula de celda → solo calcular y devolver; cambiar el libro → un Sub.

Argumentos opcionales y con tipo hacen que la UDF se sienta nativa

Dos detalles hacen agradable una función personalizada:

Function Neto(bruto As Double, Optional tasa As Double = 0.21) As Double
    Neto = bruto / (1 + tasa)      ' tasa vale 0,21 si quien llama la omite
End Function

Optional con un valor predeterminado permite que =Neto(A2) y =Neto(A2; 0,1) funcionen las dos. Declarar el tipo de retorno (As Double, As String, As Boolean) en vez de Variant hace la función más rápida y la intención clara.

La opinión: no reinventes una función nativa

Las Functions de VBA son para la lógica que Excel aún no tiene. Si WorksheetFunction.SumIf, UNIRCADENAS o BUSCARX ya hace el trabajo, llámala — una función nativa es más rápida, recalcula bien y no exige un libro con macros. Reserva tus Functions para reglas de verdad propias: un tramo fiscal de la empresa, un analizador de texto sucio, un cálculo de negocio sin equivalente. Una UDF que envuelve SUMA es un lastre; una UDF que codifica tu regla de negocio es un activo.

Errores frecuentes de Function (y la solución)

Síntoma Causa Solución
La función devuelve siempre 0 / vacío Usaste Return, o nunca asignaste el nombre Asignar el resultado al nombre: MiFuncion = resultado
#¿NOMBRE? en la celda La función está en un módulo de hoja, o el nombre está mal escrito Moverla a un Módulo estándar; revisar la ortografía
La UDF no colorea/cambia celdas Una UDF llamada desde celda no puede alterar el libro Un Sub en un botón/evento para los cambios
#¡VALOR! en la celda Un error no controlado dentro de la función Validar las entradas; devolver un valor de respaldo en vez de un error
El resultado de la UDF no se actualiza La función no ve la entrada cambiada Pasar las celdas cambiadas como argumentos, o Application.Volatile (con moderación)
«se esperaba: fin de la instrucción» al llamar Confusión paréntesis/Call (como en los Subs) Usar el valor de retorno: x = MiFuncion(a)

Cuando la lógica de la fórmula es el verdadero trabajo — olvida el VBA

Una Function personalizada es la herramienta correcta para un cálculo reutilizable. Pero cuando la tarea es «concilia estos dos exportes, marca las filas sin coincidencia y suma las diferencias por mes», no quieres escribirlo y mantenerlo a mano. ExcelMaster Agent toma esa frase en español sencillo y produce el resultado — sin UDF que depurar, sin archivo con macros que distribuir. Prueba gratis →

Guías relacionadas

Preguntas frecuentes

¿Qué es una Function en VBA? Una Function es un procedimiento con nombre que hace un trabajo y devuelve un valor al código que la llama. Se define con Function Nombre(args) As Tipo … End Function y se devuelve el resultado asignándolo al propio nombre de la función.

¿Cómo devuelvo un valor desde una función VBA? Asigna el valor al nombre de la función: dentro de Function Total() As Double, escribe Total = 42. VBA no tiene una instrucción Return para esto — Return pertenece al antiguo GoSub y no devuelve ningún valor. El último valor asignado al nombre antes del final es el que se devuelve.

¿Por qué mi función VBA devuelve 0 o vacío? Porque nunca asignaste un valor al nombre de la función (o usaste Return, que no funciona en VBA). La función devuelve entonces el valor predeterminado de su tipo — 0, "" o Empty. Añade NombreFuncion = resultado antes de End Function.

¿Cómo creo una función personalizada (UDF) en Excel? Pon una Function en un módulo estándar (Insertar → Módulo), dale un tipo de retorno y asigna el resultado a su nombre. Luego escribe =TuFuncion(...) en una celda. Aparece en el autocompletado de fórmulas como una función nativa.

¿Por qué mi UDF no puede cambiar otras celdas o colores? Cuando Excel llama a una Function desde una celda, se ejecuta en un modo restringido que solo puede devolver un valor — no puede modificar el libro (ni escribir en celdas, ni dar formato, ni MsgBox). Para cambiar la hoja, usa un Sub activado por un botón o un evento en lugar de una UDF.

¿Cuándo debo usar una Function en vez de un Sub? Usa una Function cuando quien llama necesita un valor de vuelta — un cálculo, una búsqueda, un texto limpio — o cuando quieras llamarla desde una celda. Usa un Sub cuando el procedimiento solo hace algo (da formato, exporta, elimina) y no devuelve nada.