Funciones creadas por el usurio con Rango

30/08/2004 - 12:59 por Adolfo Aparicio | Informe spam
Como bien me aconsejó Hector Miguel en el post titulado:
Re: Ayuda en las funciones definidas por el usuario
de fecha: 8/26/2004 10:31:31 PM
para hacer una función definida por el usuario que use
rangos, lo único que se ha de hacer es usar como
argumentos alguna variable tipo Range.

He probado ha construir una función que sume, de igual
forma que lo hace la función =SUMA(). La función es la
siguiente:

Function sumado(R As Range) As Double
Dim s As Double
For Each c In R
s = s + c
Next
sumado = s
End Function

Pongamos los siguientes valores:
en A1 --> 1
en A2 --> 2
en A3 --> 3
en A10 --> 4

Si aplicamos la función suma, obtenemos la suma correcta
que es 10
=SUMA(A1:A3;A10)
Por el contrario si aplicamos la fórmula que hemos creado:
=sumado(A1:A3;A10)
obtenemos un error del tipo #¡VALOR!

Pero la función 'sumado' no está mal ya que si la
llamamos desde un procedimiento funciona

Sub prueba()
MsgBox sumado(Range("A1:A3,A10"))
End Sub

Y también funciona si el rango es un sólo bloque de
celdas. Por ejemplo: =sumado(A1:A3) da como resultado 6.

Después de dar vueltas al problema he visto que si en la
fórmula que escribes añades unos paréntesis se soluciona:

=sumado((A1:A3;A10)) y el resultado es 10.

¿Sabéis como conseguir que la fórmula funcione sin
necesidad de estos paréntesis, al igual que la función
=SUMA()?

Gracias.

Adolfo
 

Leer las respuestas

#1 Fernando Arroyo
30/08/2004 - 14:18 | Informe spam
Para poder pasarle más de un rango a la función desde una celda sin necesidad de los dobles paréntesis tienes que definir el rango como una matriz de parámetros, usando ParamArray, algo como:

Function sumado(ParamArray Rango()) As Double
Dim vCelda As Variant, lngElem As Long
For lngElem = LBound(Rango) To UBound(Rango)
For Each vCelda In Rango(lngElem)
sumado = sumado + vCelda
Next vCelda
Next lngElem
End Function


Respecto a las causas de este comportamiento, no estoy completamente seguro, pero pienso que es porque al poner los dobles paréntesis los más interiores se evalúan antes de llamar a la función, lo que produce un rango (si bien es verdad que se trata de un rango con dos áreas) que es lo que se le pasa a la función (y lo que ésta espera que le sea pasado), mientras que si no se ponen los dobles parénteris la función recibe dos rangos cuando sólo espera uno, y esto hace que la función ni siquiera se ejecute.

Esto explicaría también por qué la función trabaja si es invocada desde VBA (con msgbox, por ejemplo): poque al hacerlo, el argumento se evalúa antes de ejecutarla.

Un saludo.


Fernando Arroyo
MS MVP - Excel


"Adolfo Aparicio" escribió en el mensaje news:295001c48e80$62c56c00$
Como bien me aconsejó Hector Miguel en el post titulado:
Re: Ayuda en las funciones definidas por el usuario
de fecha: 8/26/2004 10:31:31 PM
para hacer una función definida por el usuario que use
rangos, lo único que se ha de hacer es usar como
argumentos alguna variable tipo Range.

He probado ha construir una función que sume, de igual
forma que lo hace la función =SUMA(). La función es la
siguiente:

Function sumado(R As Range) As Double
Dim s As Double
For Each c In R
s = s + c
Next
sumado = s
End Function

Pongamos los siguientes valores:
en A1 --> 1
en A2 --> 2
en A3 --> 3
en A10 --> 4

Si aplicamos la función suma, obtenemos la suma correcta
que es 10
=SUMA(A1:A3;A10)
Por el contrario si aplicamos la fórmula que hemos creado:
=sumado(A1:A3;A10)
obtenemos un error del tipo #¡VALOR!

Pero la función 'sumado' no está mal ya que si la
llamamos desde un procedimiento funciona

Sub prueba()
MsgBox sumado(Range("A1:A3,A10"))
End Sub

Y también funciona si el rango es un sólo bloque de
celdas. Por ejemplo: =sumado(A1:A3) da como resultado 6.

Después de dar vueltas al problema he visto que si en la
fórmula que escribes añades unos paréntesis se soluciona:

=sumado((A1:A3;A10)) y el resultado es 10.

¿Sabéis como conseguir que la fórmula funcione sin
necesidad de estos paréntesis, al igual que la función
=SUMA()?

Gracias.

Adolfo

Preguntas similares