Re-Call a String/Object from previous Sub - vb.net

Is it possible to recall a string or object that was stored in a previous sub?
The below code gives you an idea as to what I am trying to do.
Sub StoreUserData()
Dim StorName as Object
End
Sub WriteUserFile()
'Recall StorName here
End Sub

You need to make it into a field:
Dim StorName as Object
Sub StoreUserData()
'Do stuff with StoreName
End
Sub WriteUserFile()
'Recall StorName here
End Sub
If it is declared within a method, it is a local variable and not visible outside the method.
I suggest reading about Scope in Visual Basic.

Local variables are only accessible within their respective code block. To be able to access it you would have to widen its scope like this:
Class MyClass
Dim storName as Object
Sub StoreUserData()
storName = something
End Sub
Sub WriteUserFile()
' Use storName here
End Sub
End Class

Related

Access VBA tries to terminate return value of Function

I'm building an Access database using some VBA code.
I've made a very simple class and a function which creates an instance of that class. Executing this function yields an error 91: object variable or With block variable not set. After debugging I found out Access tries to terminate the newly created object, ending the terminate function results in the error.
My intention was to create a factory for MyObject in order to create an object and initialize it with given arguments. I've stripped all this away to find the problem and now I'm dumbfounded. Can someone point out what I'm doing wrong because I have no idea anymore.
The class I made, called MyObject:
Private Sub Class_Initialize()
'does literally nothing
End Sub
Private Sub Class_Terminate()
'does literally nothing
End Sub
The function I made to initialize the class, located in another module:
Public Function createMyObject(someArg As String) As MyObject
Set createMyObject = New MyObject
End Function
I obviously expected the function createMyObject to return an instance of MyObject, but it gives me an error 91. Debugging led me to the Class_Terminate Sub in MyObject where the error gets thrown at the "end sub" line.
Try with using a property:
Option Compare Database
Option Explicit
Private mTest As Variant
Private Sub Class_Initialize()
'does literally nothing
End Sub
Private Sub Class_Terminate()
'does literally nothing
End Sub
Public Property Get Test() As Variant
Test = mTest
End Property
Public Property Let Test(ByVal NewValue As Variant)
mTest = NewValue
End Property
and then:
Public Function CreateMyObject(SomeArg As String) As MyObject
Set CreateMyObject = New MyObject
CreateMyObject.Test = SomeArg
End Function
which you can call like this:
Set o = CreateMyObject("Joe")
Debug.Print o.Test

Is there a way to make a setable function in a user defined object

Is there a way to set an object method like a property?
I want to be able to just call the function like myObj.myFunc() but I want to set where myFunc will point when i instantiate myObj. As of right now i have it as a public event that i can add a handler to at init but it does seem like the best option.
As #VisualVincent said:
Module Module1
Sub Main()
Dim myObj As New myObj(Sub() Console.WriteLine("1"))
' OR
Dim myObj2 As New myObj(AddressOf myFunc)
myObj2.myFunc.Invoke
End Sub
Sub myFunc()
Console.WriteLine("2")
End Sub
End Module
Class myObj
Public Sub New(myFunc As Action)
Me.myFunc = myFunc
End Sub
Property myFunc As Action
End Class

Calling private sub from module, concatenated reference

I have a couple of forms (i.e. frmTest) with bound comboboxes (i.e. cboTest). I'm trying to solve the NotInList event by a public sub, which calls back a button click sub's in these forms (i.e. btnTest_Click).
Form frmTest:
Private Sub cboTest_NotInList(NewData As String, Response As Integer)
Response = acDataErrContinue
Item_NotInList NewData, Me, "btnTest"
End Sub
Public Sub btnTest_Click
'....
End sub
Module:
Public strNotInList_Text As String
'public variable to store entered text
Public Sub Item_NotInList (strNewData As string, frmForm As Form, strControl As String)
Dim strControl_Sub As String
strNotInList_Text = strNewData
strControl_Sub = "." & strControl & "_Click"
Application.Run frmForm.Name & strControl_Sub
End Sub
Acces returns an error "Program ... didn't found a procedure frmTest.btnTest_Click."
Why ?
Reference frmTest.btnTest_Click looks to be correct. Sub btnTest_Click is declared as public.
Thank you for yor help.
Couldn't you create an interface let say IMyInterface with this method btnTest_Click (should be named differently) and let the forms you want to call this method implement this interface. Then change the signature of Item_NotInList like this:
Public Sub Item_NotInList (strNewData As string, frmForm As IMyInterface, strControl As String)
' ...
frmForm.btnTest_Click
' ...
Because the instance of the form is available in the method Item_NotInList you simply call the target method. Does this help?
Example:
Add class module and name it e.g. IMyInterface (can be named according to your needs). Add empty body of the method (don't add any implementation).
IMyInterface
Public Sub TestClick()
' will be implemented in your forms
End Sub
Then implement this interface in your forms e.g. in Form frmTest and others which should be used with the Item_NotInList method.
Form frmTest example
Implements IMyInterface
Private Sub IMyInterface_TestClick()
' here goes your implementation
End Sub
Standard Module test code
Sub test()
Dim f1 As UserForm1
Set f1 = New UserForm1
Item_NotInList f1
Dim f2 As UserForm2
Set f2 = New UserForm2
Item_NotInList f2
End Sub
Sub Item_NotInList(testForm As IMyInterface)
testForm.TestClick
End Sub
Thats it. HTH

Error 438 when setting an object variable to a subform path

Hi all I trying to setup an object variable to pass into a module. I'm getting the Run-time error 438 in the first case below but not in the second. Can anyone say why?
Private Sub OpGenericText_AfterUpdate()
Dim obCurrentForm As Object
Set obCurrentForm = Forms.AssemblyProcesses.APSectionsSubForm.APStepsSubForm
Call UpdateStepText(obCurrentForm)
End Sub
the following works
Private Sub OpGenericText_AfterUpdate()
Dim obCurrentForm As Object
Set obCurrentForm = Forms.StepsWhereUsedWithDetail
Call UpdateStepText(obCurrentForm)
End Sub
It should probably read as it seems as you have nested subforms:
Private Sub OpGenericText_AfterUpdate()
Dim obCurrentForm As Form
Set obCurrentForm = Forms!AssemblyProcesses!NameOfFirstSubformControl.Form!NameOfSecondSubformControl.Form
Call UpdateStepText(obCurrentForm)
End Sub

Access variable in Shared Sub

is there a way to access a variable in Form_Load from an event handler?
Please dont mind the code, this is just a representation of my question.
Public Class Form
Public Sub Form_Load()
Dim x as string
x = MyClass.MethodGetValue()
End Sub
Private Shared Sub OnChanged()
MyClass2.MethodGetValue(x)
End Sub
End Class
It's about the scope of the variable. In your situation you need a class variable. This allows it to be used anywhere inside of this class.
Public Class Form1
Private x As Object 'pick the datatype that matches your needs
Public Sub Form_Load()
x = MyClass.MethodGetValue()
End Sub
Private Sub OnChanged()
MyClass2.MethodGetValue(x)
End Sub
End Class