Si en un procedimiento necesitas una serie de parámetros opcionales, se pueden indicar con Optional cada uno de esos parámetros, pero si son muchos y no nos importa usar la asignación con nombres, podemos usar ParamArray. De esta forma se pasarán esos parámetros en la forma de un array. Por ejemplo:
' Private Sub tOpcional1(ParamArray optParams()) Dim i As Long For i = LBound(optParams) To UBound(optParams) Print optParams(i) Next End SubEs decir, se recorre la variable que representa a los parámetros como si fuese un array y así se accede a cada uno de esos parámetros.
Pero, ¿que ocurre si desde un procedimiento que recibe parámetros opcionales queremos pasar esos parámetros a otro procedimiento que también recibe parámetros opcionales?
Por ejemplo tenemos este otro procedimiento que que llama al anterior:
' Private Sub tOpcional2(ParamArray optParams()) ' Llamar a otro procedimiento que acepta parámetros opcionales tOpcional1 optParams End SubPues bien, esto no funciona, como podrás comprobar si haces la prueba.
¿Por qué?
Por la sencilla razón de que: sólo se ha pasado un parámetro, que contiene todos los parámetros recibidos por el primer procedimiento, y al intentar hacer optParams(i) nos da error, (13-Type Mismatch), ya que no es un array.¿La solución?
Tendrás que comprobar si el primer parámetro es un array, si es así, usar ese primer parámetro, que será el que contenga todos los demás.' Private Sub tOpcional1(ParamArray optParams()) Dim i As Long Dim Params As Variant ' Comprobar si el primer parámetro es un array If IsArray(optParams(0)) Then Params = optParams(0) Else Params = optParams End If For i = LBound(Params) To UBound(Params) Print Params(i) Next End SubPara probarlo: crea un proyecto, asigna True a la propiedad Autoredraw del form, para que no se pierda lo que se imprima.
Añade este código al Form_Load:' tOpcional2 "Varios", "parámetros", "pasados", "a un procedimiento"Añade también los dos últimos procedimientos mostrados y pulsa F5.
Verás que todo funciona bien. También puedes llamar directamente al primer procedimiento, por supuesto, debe funcionar correctamente:
' tOpcional1 "Varios", "parámetros", "pasados", "a un procedimiento"Pero... (siempre hay algún pero), el problema es que se pase un array entre esos parámetros... peor aún, si el primero de esos parámetros es un array... sólo funcionará si se llama a tOpcional2, pero no si se llama directamente a tOpcional1.
Para solucionar el tema de pasar arrays en los parámetros, tendremos que hacer una comprobación extra:
' Private Sub tOpcional1(ParamArray optParams()) ' Para solucionar el problema si se pasan arrays ' entre los parámetros opcionales Dim i As Long Dim Params As Variant ' Si el número de elementos de los parámetros opcionales es mayor que uno If UBound(optParams) - LBound(optParams) > 1 Then Params = optParams Else ' === Esto es lo mismo que antes === ' Comprobar si el primer parámetro es un array If IsArray(optParams(0)) Then Params = optParams(0) Else Params = optParams End If End If ' He cambiado el Print Params(i) por TypeName(Params(i)) para que muestre ' el tipo de dato que se ha pasado en cada parámetro. ' En el caso de un array de tipo cadena, mostrará String() For i = LBound(Params) To UBound(Params) Print TypeName(Params(i)) Next End SubPara probarlo, escribe este código en el Form_Load:
' Dim tArray(1 To 3) As String tArray(1) = "Hola, " tArray(2) = "¿cómo " tArray(3) = "estás?" tOpcional2 tArray(), 12345.67, CDec(12345.67), 1234, 1234567, "Varios parámetros pasados", "a un procedimiento" ' Por supuesto, se pueden incluir varios Arrays: Dim tArray2(1 To 2) As Long tArray2(1) = 987654 tArray2(2) = 1234567 tOpcional1 tArray(), 12345.67, tArray2, "Cadena", 123, 123.3, 12345.5564Mejor ahora ¿verdad? Pues me alegro.
Bueno, espero que todo esto te ayude a comprender un poco mejor cómo usar ParamArray.