Can a UDF pass a ParamArray to a subroutine for processing?

JenniferMurphy

Well-known Member
Joined
Jul 23, 2011
Messages
2,691
Office Version
  1. 365
Platform
  1. Windows
I am working on a UDF with several keyword parameters that I am passing from Excel as a ParamArray. To keep the main UDF simpler, I would like to pass the entire ParamArray to a subroutine for processing. I can't get it to work.

Here's what I've tried:

Code:
' This is the main UDF as called from Excel.
Public Function Main(P1 As Range, P1 As Range, ParamArray PArgs()) As Variant

' Define and initialize the ParamArray variables
Dim PA1 As Single:  PA1 = 100
Dim PA2 As Single:  PA2 = 0
Dim PA3 As String:  PA3 = "Off"

 . . .

' Call the subroutine to process the ParamArray string (PArgs).
' Pass the variables that will be set by the ParamArray string ByRef
' so the subroutine can change them if necessary.
If PACheck(PA1, PA2, PA3, PArgs()) Then
  Main = CVErr(xlErrValue): Exit Function   'If errors, exit
End If

 . . .

End Function 


' 
Public Function PACheck(ByRef PA1, ByRef PA2, ByRef PA3, _
                                 ByRef PArgs()) As Boolean

' Run through the ParamArray parameters, check for errors, and set the values

 . . .

End Function

When I try to run this, I get a Compile Error on the call to the subroutine saying that it is "Invalid parameter use".

I've tried it with and without the parentheses.

Can this be done? How?
 
You don’t need to deal with the array of arrays if you remove the paramarray from Pasub and declare PArgs as a variant and not an array
 
Upvote 0

Excel Facts

Can a formula spear through sheets?
Use =SUM(January:December!E7) to sum E7 on all of the sheets from January through December
You don’t need to deal with the array of arrays if you remove the paramarray from Pasub and declare PArgs as a variant and not an array

I don't understand. I want to process the ParamArray parameters in the Sub exactly as I would in the Main. Are you suggesting a method that is better than what Shg provided? That method works perfectly for my needs.
 
Upvote 0
Why is that?
Because otherwise you need to keep adding a zero with each increase in depth:

Code:
Public Function PAMain(P1, ParamArray PArgs())
  MsgBox "Main: PArgs = {" & Join(PArgs, ", ") & "}"
  Call PASub1(P1, PArgs)
End Function

Public Sub PASub1(P1, ParamArray PArgs())
  MsgBox "Sub: Pargs(0) = {" & Join(PArgs(0), ", ") & "}"
  Call PASub2(P1, PArgs())
End Sub

Public Sub PASub2(P1, ParamArray PArgs())
  MsgBox "Sub: Pargs(0)(0) = {" & Join(PArgs(0)(0), ", ") & "}"
End Sub

EDIT: I'd be interested to see Kyle's suggestion as well.
 
Last edited:
Upvote 0
Because otherwise you need to keep adding a zero with each increase in depth:

Code:
Public Function PAMain(P1, ParamArray PArgs())
  MsgBox "Main: PArgs = {" & Join(PArgs, ", ") & "}"
  Call PASub1(P1, PArgs)
End Function

Public Sub PASub1(P1, ParamArray PArgs())
  MsgBox "Sub: Pargs(0) = {" & Join(PArgs(0), ", ") & "}"
  Call PASub2(P1, PArgs())
End Sub

Public Sub PASub2(P1, ParamArray PArgs())
  MsgBox "Sub: Pargs(0)(0) = {" & Join(PArgs(0)(0), ", ") & "}"
End Sub

EDIT: I'd be interested to see Kyle's suggestion as well.

I don't understand this and I don't have time now to explore it. There must be something different about a ParamArray array variable and an array variable even when the first is copied into the second.

But I now have something that works. Unless Kyle or someone comes up with something better, I'll go with your suggestion to copy it so a second array variable.

Thanks
 
Upvote 0
This also works:

Code:
Public Function PAMain(P1, ParamArray PArgs())
  MsgBox "Main: PArgs = {" & Join(PArgs, ", ") & "}"
  Call PASub1(P1, CVar(PArgs))
End Function

Public Sub PASub1(P1, PArgs)
  MsgBox "Sub: Pargs = {" & Join(PArgs, ", ") & "}"
End Sub
 
Upvote 0
This also works:

Code:
Public Function PAMain(P1, ParamArray PArgs())
  MsgBox "Main: PArgs = {" & Join(PArgs, ", ") & "}"
  Call PASub1(P1, CVar(PArgs))
End Function

Public Sub PASub1(P1, PArgs)
  MsgBox "Sub: Pargs = {" & Join(PArgs, ", ") & "}"
End Sub

Nice! :cool:

I presume that this is the equivalent of assigning it to a local array, right?

Thank you!!!
:beerchug:
 
Upvote 0
I'm back at a computer now, essentially you just need to pass byVal rather than byRef, so this is a bit cleaner:
Code:
Public Function PAMain(P1, ParamArray PArgs())
  MsgBox "Main: P9Args = {" & Join(PArgs, ", ") & "}"
  Call PASub1(P1, PArgs)
End Function

Public Sub PASub1(P1, ByVal PArgs)
  MsgBox "Sub: Pargs = {" & Join(PArgs, ", ") & "}"
End Sub
 
Last edited:
Upvote 0

Forum statistics

Threads
1,224,824
Messages
6,181,186
Members
453,020
Latest member
Mohamed Magdi Tawfiq Emam

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top