-
|
First of all, I really appreciate your work, I find what you managed to do with vba really amazing ! It's helping me at my work. I will maybe contribute to this project in the future :) I would like to write something like Sub Fun_Clean(ByRef col)
Set col = Nothing
End Sub
Sub Fun()
Dim col As New Collection
Dim factory As stdSentry: Set factory = ' ...
With factory()
' Do stuff that can raise an error
End With
End SubI want the routine to always run the cleaning section, even if an error is raised. It's mostly needed for when I open a workbook or recordset and I need to close it. Also, is the "stdSentry" class ready to be used ? It's not mentioned in the roadmap so I assumed it was ready since it's not in the "WIP" folder. But then I saw that it uses stdError that is WIP so it makes me doubt it... |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Hi Gagota, I'm not at my PC, but I will try to respond to this. Thanks for the interest and I'm glad to here this is useful at your work :) First off, the stdSentry class is absolutely ready to use, no worries there at all! I need to update the readme probably... It does have a method in it which utilises stdError, but you absolutely don't have to use that method. It's there purely if you ever do also have stdError within your module, and it's built for building stack traces basically. Critically the module doesn't have Contributions are absolutely welcome too as long as they fit the style of the repo! However if it is merely a project which uses stdVBA, this can be contributed to the examples repo! Now to the substance. Typically I would avoid what you are suggesting (in the case of a collection) and opt for: With New Collection
...
End WithAs soon as the collection goes out of scope (i.e. not within the With-block) it will be set to nothing, triggering any uninitialisers or whatever. However I assume there is method to your madness in your specific situation hehe. I think you could probably do something like this: Dim col as collection
Public Sub test
Dim factory as stdSentry: set factory = setNothingOnExpire()
set col = new Collection
With factory(col)
...
End With
debug.print col is nothing
End Sub
Public Function SetNothingOnExpire() as stdSentry
Dim onInit as stdCallback: set onInit = stdCallback.CreateFromMethod("","null_method")
Dim onDestroy as stdCallback: set onDestroy = stdCallback.CreateFromMethod("", "obj_set_to_nothing")
set setNothingOnExpire = stdSentry.Create(onInit, onDestroy)
End Function
Sub null_method(ParamArray v())
End Sub
Sub obj_set_to_nothing(ByVal obj as object)
set obj = nothing
End SubThis is untested, but I think it should do what you are after... However:
Error handling in VBA is weird... I think when an error is raised the jump doesn't exit the with block... I might be wrong, but that's my recollection? However when the function itself goes out of scope, it absolutely will execute the cleanup if it's within a sentry object. So this will probably be good enough for your needs I imagine? Unless your user clicks Typically the pattern I use can be seen in the stdError-enwrapped branch of the repo for instance: Public Function CreateFromArray(ByVal arr As Variant) As stdArray
With stdError.getSentry("stdArray#CreateFromArray", "arr", arr)
On Error GoTo stdErrorWrapper_ErrorOccurred
Set CreateFromArray = New stdArray
Dim i As Long
Dim lb As Long: lb = LBound(arr)
Dim ub As Long: ub = UBound(arr)
Call CreateFromArray.protInit(ub - lb + 1, 10)
For i = lb To ub
Call CreateFromArray.Push(arr(i))
Next
'Raise AfterCreate event
RaiseEvent AfterCreate(Create)
Exit Function
stdErrorWrapper_ErrorOccurred:
Call Err_Raise(Err.Number, Err.Source, Err.Description)
End With
End Function
...
Private Sub Err_Raise(ByVal number as Long, Optional ByVal source as string = "", Optional ByVal description as string = "")
Call stdError.Raise(description)
End Sub
|
Beta Was this translation helpful? Give feedback.
Hi Gagota,
I'm not at my PC, but I will try to respond to this. Thanks for the interest and I'm glad to here this is useful at your work :)
First off, the stdSentry class is absolutely ready to use, no worries there at all! I need to update the readme probably... It does have a method in it which utilises stdError, but you absolutely don't have to use that method. It's there purely if you ever do also have stdError within your module, and it's built for building stack traces basically. Critically the module doesn't have
Option Explicitso it won't compiler error when the function is never called, however it will runtime error if you don't includestdErrorin your project.Contributions ar…