Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Assigning the Procedure ID in a VBA Collection Class 1

Status
Not open for further replies.

PaulMcCulloh

Programmer
Feb 11, 2003
8
US
Hello,
How do you Hide a method and assign a ProcedureID in VBA?

Since VBA does not provide the Procedure Attributes dialog, what code is used to HIDE the NewEnum method and assign it the ProcedureID of -4 that For Each...Next requires to work?

I am trying to enable For Each...Next in a Collection Class. The VB6 Programmer's Guide says that "for your collection classes to work with For Each...Next, you must provide a hidden NewEnum method with the correct ProcedureID."

I've got the NewEnum method part, which returns the Collection object's enumerator.

A guess for the HIDE code is to export the module to a text editor, place the following line as the second line of the method, and then reimport it:

Attribute VB_Exposed = False

however, this is just a guess and I don't know if this is correct.

As far as code to set the ProcedureID to be -4, I have no idea how to do that!

Can you help? Thanks much!!!

 
Hiya,

somewhere in my collection of stuff_i_got_from_SOMEwhere_but_don't_ask_me_where (I think it's an MS's example from one of their courses for a default class) I found this:
Code:
Option Explicit
Private m_Col As Collection

Public Property Get Count() As Long
  Count = m_Col.Count
End Property

Public Sub Add(ByVal NewItem As Variant, ByVal key As Variant)
On Error GoTo ERR_HAND
  m_Col.Add NewItem, key
ERR_HAND:
Exit Sub
  Err.Raise Err.Number, "MyCollection Class", Err.Description
End Sub

Public Sub Remove(ByVal key As Variant)
On Error GoTo ERR_HAND
  m_Col.Remove key
ERR_HAND:
Exit Sub
  Err.Raise Err.Number, "MyCollection Class", Err.Description
End Sub

Public Property Let Item(ByVal key As Variant, ByVal NewItem As Variant)
On Error Resume Next
  m_Col.Remove key
On Error GoTo ERR_HAND
  m_Col.Add NewItem, key
ERR_HAND:
Exit Property
  Err.Raise Err.Number, "MyCollection Class", Err.Description
End Property

Public Property Get Item(ByVal key As Variant) As Variant
On Error GoTo ERR_HAND
  Set Item = m_Col(key)
Exit Property
ERR_HAND:
  Err.Raise Err.Number, "MyCollection Class", Err.Description
End Property

Public Function NewEnum() As IUnknown
  Set NewEnum = m_Col.[_NewEnum]
End Function

Private Sub Class_Initialize()
  Set m_Col = New Collection
End Sub

This is generic code to create a class with the NewEval function added

i *think* you need to make it the default for it to work - not sure.
BUT i have no idea whether the attibute'd work. Only advice = give it a go & see if it works ;-)

Cheers
Nikki

 
Paul,

From a VB ref:

Step 1: write the NewEnum function procedure (as Nikki has shown in her code - it must have the square brackets and leading underscore as shown)

Step 2: With the insertion point in the Function NewEnum statement, open the Procedure Attributes dialog box from the Tools menu, choose Advanced, and set the Procedure ID to -4 (as you've wanted to do above) and check the box for Hide this member.

Once you have completed these 2 steps to expose the enumerator, you can step through the collection using FOR EACH.

Again, the above is an extract from a ref I have for VB6 - not VBA. I'm not sure if this is possible in VBA as I've only used it in VB. I hope this helps you to step through the members of your class. :) MM
 
Thank you so much for your replies!

Could I ask one of you a huge favor? I don't have a copy of VB6. If I could just see the code that VB adds when Hide this member and a Procedure ID of -4 are assigned to a method in the Tools, Procedure Attributes dialog, I'm pretty sure I'd have the answer.

It was Nikita6003 who turned me on to the fact that when attributes are assigned, VB adds code to the module telling itself the assignments: For example, setting the Name attribute causes VB to add the code
Code:
Attribute VB_Name = "MyNewModule".

If one of you has a copy of VB6, could you take a just a few minutes and help me with this?

First, create a new generic class module and add a function -- no code needed -- as follows:

Code:
Public Function NewEnum() As IUnknown
  '
End Function

Then, in Tools, Procedure Attributes, in the Name box select the NewEnum method you just created. Then click Advanced and check Hide this member. In the Procedure ID box, type -4 (minus four); Click OK.

Finally, File, Export File the module you created and open the resulting .cls file in Notepad or Wordpad or whatever and tell me what code VB has inserted that you didn't? I'd expect one or two "
Code:
Attribute_VB_____
" lines and probably one other line...

thank you!
Paul [noevil]
 
got it at home - lemme just finish here, drive the 4 hrs back ;-) (holdays have started so traffic's jammed solid here) & I'll take a look

meanwhile - if anyone out there can help - be my guest!

Cheers
Nikki
 
Hi Paul

coupls links for you - I forgot I have .NET installed on my new PC & my old one is currently unavailable
I've asked a colleague to check out the bit of code you need, but meanwhile, take a look here for some hints on Class module code:


Cheers 4 now
Nikki
 
Hi Nikki! What can I say? You have been so helpful! The links you forwarded were excellent - I was able to set up the NewEnum function with the correct procedure ID based on code in the vb2themax article:
Code:
Attribute NewEnum.VB_UserMemId = -4

That set up the For Each...Next capability. Beautiful.

[Smarty]

Thank you so much - you have no idea how many hours I spent running Internet searches to try to get more information on these "Attributes" (should've spent the time bidding on a copy of VB6 on e-Bay...).

Thank you, also, for checking on your copy of VB and talking to your colleague. At this point, only the Attribute for setting a method Hidden is up in the air. If your colleague has the time, it would seem that creating a function and designating it Hidden would be enough to return the Attribute code.

In any case, it appears to be working perfectly. Thank you, thank you, thank you!

talk to you again soon,
Paul [Thumbsup2]
 
Paul,

Following your instructions, the resulting .cls file gives:

Public Function NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Attribute NewEnum.VB_MemberFlags = "40"
'
End Function

If I repeat w/o checking 'Hide this member', the bolded statement above does not appear.

HTH
Mike
 
Mike, thanks so much for running that code! I really appreciate your taking the time to do that.

I guess there must be some further trick involved, because adding that attribute didn't hide the Method. I ran across the same code in a website provided by Nikita6003 (but didn't know what it did), so I'm sure it's correct, but obviously I'm missing something.

If you hear/find anything more about this, I'd love to figure this one out.

In the meantime, I'm going to go practice my VB.NET...

thanks,
Paul [thumbsup2]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top