5

I think I have a fairly good idea what the difference is between ByVal and ByRef in VB, but my issue is when I try using it in conjunction with a member that is declared with WithEvents.

I have the following method:

Private Sub SafeCloseAndDeRefConnection(ByRef cnx As ADODB.Connection)
On Error GoTo ErrH
    If Not cnx Is Nothing Then
        If (cnx.State And adStateConnecting) = adStateConnecting Then
            cnx.Cancel
        End If

        If (cnx.State And adStateOpen) = adStateOpen Then
            cnx.Close
        End If

        Set cnx = Nothing
    End If
Exit Sub
ErrH:
 Set cnx = Nothing
End Sub

If I have a class member declared as such:

Private WithEvents Connection As ADODB.Connection

I then want to close the connection and then call it as such:

SafeCloseAndDeRefConnection Connection

But after the call to SafeCloseAndDeRefConnection the Connection variable is not set to Nothing and still has its original reference.

If I remove the WithEvents keyword the call to SafeCloseAndDeRefConnection works as expected (but obviously events can then not be handled)

Can anyone explain to me why this is happening?

P.S. I have found a similar question elsewhere, but the workaround does not work in my scenario.

Francois Nel
  • 1,662
  • 2
  • 19
  • 29
  • 4
    A `WithEvents` object cannot be passed `ByRef` and if you attempt it a "copy" is passed just as if you'd declared it `ByVal`. It sort of has to be this way to manage connecting and disconnecting the actual object's outgoing event interface and the client's sink object. – Bob77 Jul 04 '13 at 15:10
  • 1
    Try implementing a "fluent" function which you can then use like this `Set Connection = SafeCloseAndDeRefConnection(Connection)` – wqw Jul 04 '13 at 21:24
  • @Bob77 Thank you for your reply. It makes a bit sense (as much as VB can make sense). Do you maybe have a reference where this is explained in more detail? VB6 is a "pre-Web 2.0" language, so help with this is somewhat scattered and not so easily found on the web. – Francois Nel Jul 05 '13 at 06:37
  • 1
    The details of the mechanism is a Windows topic, and not a VB6 topic. VB6 makes an effort to eliminate the need to understand such implementation details. You might try "Events in COM and Connectable Objects" though at http://msdn.microsoft.com/en-us/library/windows/desktop/ms694379(v=vs.85).aspx – Bob77 Jul 05 '13 at 08:15

1 Answers1

0

Perhaps call:

Set Connection = Nothing

After SafeCloseAndDeRefConnection(Connection)

This will force the destruction of the object and not rely on VB6 to do it for you!

Mike Weir
  • 3,094
  • 1
  • 30
  • 46