Solved Possible to pass the ParamArray arguments through 'By ref' ? (1 Viewer)

prabha_friend

Prabhakaran Karuppaih
Local time
Tomorrow, 02:17
Joined
Mar 22, 2009
Messages
784
Code:
Sub CAT_Report_RD()
Dim CYLedger As Workbook
Dim PYDLedger As Workbook
Dim IO_PO As Workbook
Dim AiREAS As Workbook
Dim LossEstimations As Workbook
Dim Inputfiles As Variant
Inputfiles = Array(CYLedger, PYDLedger, IO_PO, AiREAS, LossEstimations)
For Each element In Inputfiles
    Set element = Workbooks.Open(Application.GetOpenFilename(), ReadOnly:=True)
Next element
MsgBox CYLedger.Name
End Sub
 
Solution
No, I was saying that if the objects are added to the array ByRef then after
Code:
  For Each wb In arrWB
    Set wb = fGetWorkbook(CStr(arrWBNames(i)))
    i = i + 1
  Next wb
then wb1 and wb2 should not be Nothing because arrWB(0) and arrWB(1) should be pointers to those objects, and the wb in the For loop should act on those elements.
Okay, thanks for the explanation. I may have to digest that a bit. Cheers!

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
Make sure you add it tot the top of every code module (above or below Option Compare Database.

Then, go to Debug menu in VBA editor and click 'Compile'. It might highlight code errors and undeclared variables.

You never declared element in your For loop, so it might not like its datatype.
 

prabha_friend

Prabhakaran Karuppaih
Local time
Tomorrow, 02:17
Joined
Mar 22, 2009
Messages
784
Error_Message.png
 

Attachments

  • Macro.zip
    10.6 KB · Views: 67

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
Interesting.

It doesn't work with the For ... Each construct.

I tested by declaring the variable both as Variant and as Object.

Try using the index method (For i = LBound(InputFiles) To ...)
 

prabha_friend

Prabhakaran Karuppaih
Local time
Tomorrow, 02:17
Joined
Mar 22, 2009
Messages
784
Code:
Sub CAT_Report_RD()
Dim CYLedger As Workbook
Dim PYDLedger As Workbook
Dim IO_PO As Workbook
Dim AiREAS As Workbook
Dim LossEstimations As Workbook
Dim Inputfiles As Variant
Inputfiles = Array(CYLedger, PYDLedger, IO_PO, AiREAS, LossEstimations)
For i = 0 To UBound(Inputfiles) 'iTerationBook In Inputfiles
    Set Inputfiles(i) = Workbooks.Open(Application.GetOpenFilename())
Next i
MsgBox CYLedger.Name 'Giving Error
MsgBox Inputfiles(0).Name 'Showing the Sheet Name
End Sub
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 16:47
Joined
May 21, 2018
Messages
8,527
Lots of misstatements here.
1. You most certainly can load an array with objects, unless they are user types
2. You can do a For Each on an array

From Microsoft
The For...Each...Next statement syntax has these parts:

SYNTAX
PartDescription
elementRequired. Variable used to iterate through the elements of the collection or array. For collections, element can only be a Variant variable, a generic object variable, or any specific object variable. For arrays, element can only be a Variant variable.
groupRequired. Name of an object collection or array (except an array of user-defined types).


Declare the array as variant

Code:
Public Sub ForEachInArrayOfObjects()
  Dim myArray() As Variant
  Dim ctrl As Access.Control
  Dim i As Integer
  Dim itm As Variant
 
  ReDim myArray(Me.Controls.Count - 1)
  'load array with objects
  For Each ctrl In Me.Controls
    Set myArray(i) = ctrl
    i = i + 1
  Next ctrl
  'For each an array
 
  For Each itm In myArray
    Debug.Print itm.Name
  Next itm
 
End Sub

Results
Code:
Combo0
ReviewerID_Label
Command2
Label3
List4
Label5
 

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
2. You can do a For Each on an array
No one disputes this!

The curious point is:
Code:
' ...
  For i = LBound(arrWB) To UBound(arrWB)
    Set arrWB(i) = fGetWorkbook(CStr(arrWBNames(i)))
  Next i
  For i = LBound(arrWB) To UBound(arrWB)
    Debug.Print arrWB(i).Name
  Next i
' ...
works fine.

... but:
Code:
  Dim wb1 As Object, wb2 As Object, arrWB As Variant, i As Integer, arrWBNames As Variant, wb As Variant

  arrWB = Array(wb1, wb2)
  arrWBNames = Array("E:\Dropbox\Pepys Road\PepysRoadBookings.xlsm", _
                     "C:\Users\dm\Desktop\qryYourTableWithCounts2.xls")
  i = 0
  For Each wb In arrWB
    Set wb = fGetWorkbook(CStr(arrWBNames(i)))
    i = i + 1
  Next wb
  For Each wb In arrWB
    Debug.Print wb.Name
  Next wb
' ...
throws Error 91 (Object variable not set) At Debug.Print wb.Name
 

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
Interesting - my equivalent errors on Debug.Print wb.Name

(I'm using Acc2K7)

Will you try something else as well - add a couple of lines to your sub at the end:
Code:
  Debug.Print wb1.Name
  Debug.Print wb2.Name
 

theDBguy

I’m here to help
Staff member
Local time
Today, 13:47
Joined
Oct 29, 2018
Messages
21,473
Interesting - my equivalent errors on Debug.Print wb.Name

(I'm using Acc2K7)

Will you try something else as well - add a couple of lines to your sub at the end:
Code:
  Debug.Print wb1.Name
  Debug.Print wb2.Name
Hi David,

Simply adding those lines errors just like the original code. Did you notice the changes I added? So, doing this also works.

1631553940104.png
 
Last edited:

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
Did you notice the changes I added?
No - sorry - skimmed through without paying enough attention! :oops:

OK, I see.

But that suggests that the object in the For Each (wb) is ByVal rather than ByRef as otherwise you wouldn't need the intermediate Set back to the array element object. ????
 

theDBguy

I’m here to help
Staff member
Local time
Today, 13:47
Joined
Oct 29, 2018
Messages
21,473
But that suggests that the object in the For Each (wb) is ByVal rather than ByRef as otherwise you wouldn't need the intermediate Set back to the array element object. ????
Maybe that's the part of the discussion I missed. However, in my mind, an object has to be set. So, after declaring wb1 As Object, there has to be a Set wb1 = line somewhere. I didn't think using arrWB = Array(wb1, wb2) would be enough to do it. At that point in the procedure, both wb1 and wb2 are still set to Nothing.
 

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
Maybe that's the part of the discussion I missed. However, in my mind, an object has to be set. So, after declaring wb1 As Object, there has to be a Set wb1 = line somewhere. I didn't think using arrWB = Array(wb1, wb2) would be enough to do it. At that point in the procedure, both wb1 and wb2 are still set to Nothing.
In which case there's no point in using the array, if you have to set each individual object variable.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 15:47
Joined
Feb 28, 2001
Messages
27,183
You asked for the difference between "For Each x" vs. "For counter = start To ..."



The "For Each x in x-group" construct steps through the elements in the group, which must have some uniformity of data type. The X that follows the word "Each" can be a variant or it can be the data type that is common to the members of the group, including the possibility of it being an object. Case in point for a group of objects would be "For Each TableDef-object In AllTables..." or "For Each FieldDef-object in MyTable.Fields" for two examples. You would of course supply variables of the appropriate type for the Each object. Groups have indexes (or for arrays, subscripts). The "For Each" construct determines the highest and lowest indexes in the group and steps automatically from lowest to highest with no gaps

The "FOR counter = start TO stop STEP stepsize" construct just counts out numbers in the sequence specified. You can use the "counter" variable as an index or a subscript as appropriate to whatever you are examining, but in fact it would be possible to use it both ways in the same loop if you had both an array AND a collection ... or you might use it in neither of those ways, if all you wanted was to generate a sequence of numbers.

Therefore, the biggest difference in the "For Each" syntax is that it is bound to a collection, whereas the "For counter=start TO stop..." syntax is not necessarily bound to anything at all - except the counter variable.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 13:47
Joined
Oct 29, 2018
Messages
21,473
In which case there's no point in using the array, if you have to set each individual object variable.
Sorry, I'm still a bit confused. Are you saying the following lines of code should produce/create the objects wb1 and wb2?
Code:
Dim wb1 As Object, wb2 As Object

arrWB = Array(wb1, wb2)
When I step through that, both wb1 and wb2 were empty (set to Nothing), so doing Debug.Print wb1.Name produced the "Object Not Set" error.
 

cheekybuddha

AWF VIP
Local time
Today, 21:47
Joined
Jul 21, 2014
Messages
2,278
Sorry, I'm still a bit confused. Are you saying the following lines of code should produce/create the objects wb1 and wb2?
No, I was saying that if the objects are added to the array ByRef then after
Code:
  For Each wb In arrWB
    Set wb = fGetWorkbook(CStr(arrWBNames(i)))
    i = i + 1
  Next wb
then wb1 and wb2 should not be Nothing because arrWB(0) and arrWB(1) should be pointers to those objects, and the wb in the For loop should act on those elements.
 

Users who are viewing this thread

Top Bottom