How to Pass Additional Method signature dynamically - ms-access

Ok so i have this situation where i need to dynamically open a form, see code below, and, if possible, execute a known method for that form.
Open Form Method:
Public Sub ShowForm(par As Form, nm As String)
DoCmd.OpenForm nm
While IsOpen(nm)
DoEvents
Wend
End Sub
Caveat:
Not all forms will have the same method. So if possible add an additional optional parameter to pass through the method call, probably as a string value.
Some examples:
Form1:
public sub InitItem(id as string)
....
end sub
Form2:
public sub InitCategory(id as string)
....
end sub

How about going mad?
Private Sub Form_Open(Cancel As Integer)
Cancel = Not BuildForm(Me.Name, True)
End Sub
Function BuildForm(strFormName, blnRS, Optional strParent = "None", _
Optional strSubname = "", Optional strParentS = "", _
Optional NameMod = "", _
Optional strFormReport = "Form") As Boolean
OpenArgs, some notes
If Me.OpenArgs & "" = "" Then
Cancel = True
Exit Sub
End If
astrOpenArgs = Split(Me.OpenArgs, ",")

Related

How to create a public variable in a private module

Basically It's a login form and i'm trying to save the ID which is the Me.CBOUsername.Column(0) but I get an error when i try to call it in another form.
Option Compare Database
Option Explicit
Public ID_ As String
Private Sub Command4_Click()
Dim strCBOPass As String
Dim strPassword As String
strCBOPass = Me.CBOUsername.Column(1)
strPassword = Me.txtpassword
If strCBOPass = strPassword Then
MsgBox "Login Successful!"
DoCmd.OpenForm "Form1"
DoCmd.Close acForm, Me.Name
ID_ = Me.CBOUsername.Column(0)
Else
MsgBox "login Unsuccessful!"
End If
End Sub
It may be a little easier to explain this way.
As an example of a global variable:
Public Global_Variable1 as String
Public Sub Procedure1()
Global_Variable1 = "Test"
End Sub
Public Sub Procedure2()
Call Procedure1
MsgBox (Global_Variable1) 'return Test
End Sub
Add the module by right-clicking, and using Insert > Module

Make custom Wait Popup wait Until activity is done MS Access 2010 - 2016

I have a custom Popup that I call whenever an activity takes more than a second. Example:
PopupMsg("Getting records")
It makes a nice box that just shows the user something is happening, then it quietly disappears when the activity is done.
It works great for anything that only takes about 3 seconds, but beyond that, it disappears and then the user is left with the impression that the activity is finished. I'd like to make it stay up exactly as long as whatever activity is happening, but I've never been successful in determining this. I'd like to make sure all screen calculations are done before the popup disappears.
Here's how I implement my PopupMsg routine
Public Function PopUpMsg(strMsg As String, Optional strTitle As String)
Dim frmWait As New Form_Wait
If strTitle <> "" Then
frmWait.OpenForm strMsg & "...", strTitle
Else
frmWait.OpenForm strMsg & "..."
End If
End Function
Wait (A form called 'Wait' contains the following code)
Option Compare Database
Option Explicit
Public Property Let Message(ByVal MessageText As String)
Me.MessageLabel.Caption = MessageText
Me.Repaint
End Property
Public Property Get Message() As String
Message = Me.MessageLabel.Caption
End Property
Public Property Let Title(ByVal TitleText As String)
Me.Caption = TitleText
End Property
Public Property Get Title() As String
Title = Me.Caption
End Property
Public Function OpenForm(Optional MessageText As Variant, _
Optional TitleText As Variant) As Boolean
If Not IsMissing(MessageText) Then Me.MessageLabel.Caption = MessageText
If Not IsMissing(TitleText) Then Me.Caption = TitleText
Me.Visible = True
Me.Repaint
OpenForm = True
End Function
As you're opening a form through a class instantiation, it doesn't actually persist, and gets removed as soon as Access decides to do garbage collection and sees there's no reference to the form. If you want a form that persists until code execution is done, the best way is to pass back that form:
Public Function PopUpMsg(strMsg As String, Optional strTitle As String) As Object
Set PopUpMsg = New Form_Wait
If strTitle <> "" Then
PopUpMsg.OpenForm strMsg & "...", strTitle
Else
PopUpMsg.OpenForm strMsg & "..."
End If
End Sub
The rest of your code is still valid
You can call it like this:
Dim WaitForm As Object
Set WaitForm = PopupMsg("Getting records")
That way, you're still depending on garbage collection to remove the form, but it will close as soon as the function calling it is done.
You could also just open the form through DoCmd.OpenForm "Wait", reference it through the Forms collection, and close it using DoCmd.Close acForm, "Wait" at the end of your function, but then you'll have to close it actively. Full code for that approach:
Public Function PopUpMsg(strMsg As String, Optional strTitle As String)
DoCmd.OpenForm "Wait"
Dim frmWait As Form
Set frmWait = Forms!Wait
If strTitle <> "" Then
frmWait.OpenForm strMsg & "...", strTitle
Else
frmWait.OpenForm strMsg & "..."
End If
End Sub
Call it: PopupMsg("Getting records")
Close it at the end of execution: DoCmd.Close acForm, "Wait"
If you're not calling DoEvents in your code, there's another alternative:
Open the form using DoCmd.OpenForm "Wait", set it's TimerInterval to 1, and add DoCmd.Close acForm, Me.Name to it's Form_Close event

Dlookup Function in MS Access 2007 vba

I have a textbox that has a name ISCO68Code and ISCO68Title both are texts.
When I encode in ISCO68Code, a caption must appear on ISCO68Title that corresponds in my other table, libISCO1968.
Below is my Code Builder:
Private Sub ISCO68Code_AfterUpdate()
ISCO68Title = DLookup("ISCO68Code", "libISCO1968", "[ISCO68Code]=" & ISCO68Code&)
End Sub
Sadly, I got an error message:
Compile error: Type-declaration character does not match declared data
type.
Any help will do.
You need the quotes telling that the variable is text:
Private Sub ISCO68Code_AfterUpdate()
ISCO68Title = Nz(DLookup("ISCO68Code", "libISCO1968", "[ISCO68Code]='" & ISCO68Code & "'"))
' If the control is a Label, set its Caption:
' ISCO68Title.Caption = Nz(DLookup("ISCO68Code", "libISCO1968", "[ISCO68Code]='" & ISCO68Code & "'"))
End Sub
But your function doesn't make much sense, as DLookup will return the same ISCO68Code as you look up ... except if you just will check if it exists.
Try this function :
Private Function ISCO68Code_AfterUpdate(ByVal ISCO68Code As String) As Variant
ISCO68Code_AfterUpdate = DLookup("ISCO68Code", "libISCO1968", "[ISCO68Code] = " & ISCO68Code)
End Function
Private Sub ISCO68Code_AfterUpdate_test()
Dim ISCO68Title As Variant
ISCO68Title = ISCO68Code_AfterUpdate(ISCO68Code)
'MsgBox ISCO68Title
Debug.Print ISCO68Title
End Sub

Access variable within function

Within a JSON Geocode GetResponse, the code provided by Microsoft uses a function to return results. However, I want to use results outside of the function, but I cannot access the data from within the function afterwards. Maybe the code can explain this more clearly:
Dim geocodeRequest As New Uri(String.Format("http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}", query, key))
Dim latlong_adress As BingMapsRESTService.Common.JSON.Location = Nothing
GetResponse(geocodeRequest, Function(x)
MsgBox(x.ResourceSets(0).Resources.Length & " result(s) found.")
latlong_adress = x.ResourceSets(0).Resources(0)
'Correct results:
MsgBox(latlong_adress.Confidence)
MsgBox(latlong_adress.EntityType)
MsgBox(latlong_adress.Point.Coordinates(0) & ", " & latlong_adress.Point.Coordinates(1))
Return 0
End Function)
'Empty: --> is nothing
If latlong_adress IsNot Nothing Then
MsgBox(latlong_adress.Confidence)
MsgBox(latlong_adress.EntityType)
MsgBox(latlong_adress.Point.Coordinates(0) & ", " & latlong_adress.Point.Coordinates(1))
End If
How can I access the data from the response after the response has been made?
I solved my problem, although I am not quite sure about the correctness of the answer. My problems with understanding the issue were related to the asynchronous type of the GetResponse operation.
I added an event as follows:
Public Event NewGeocode(ByVal LocationData As BingMapsRESTService.Common.JSON.Location, ByVal successful As Boolean)
Private Sub geocodeLoop(Optional LocationData As BingMapsRESTService.Common.JSON.Location = Nothing, Optional successfull As Boolean = False) Handles Me.NewGeocode
If LocationData Is Nothing Then
geocodeAddress()
Else
If successfull = True Then
'Correct results:
MsgBox(LocationData.Confidence)
MsgBox(LocationData.EntityType)
MsgBox(LocationData.Point.Coordinates(0) & ", " & LocationData.Point.Coordinates(1))
geocodeAddress()
Else
MsgBox("Unsuccessfull")
End If
End If
End Sub
Private Sub geocodeAddress()
Dim key As String = ...
Dim query As String = "1 Microsoft Way, Redmond, WA"
Dim geocodeRequest As New Uri(String.Format("http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}", query, key))
Dim latlong_adress As BingMapsRESTService.Common.JSON.Location = Nothing
GetResponse(geocodeRequest, Function(x)
If Not x.ResourceSets(0).Resources.Length = 0 Then
RaiseEvent NewGeocode(x.ResourceSets(0).Resources(0), True)
Else
RaiseEvent NewGeocode(Nothing, False)
End If
Return 0
End Function)
End Sub
Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click
geocodeLoop()
End Sub

Compile time: Syntax error

I am able to add controls to a form when it is loaded. I need these controls to be to be catagorized so the user only can see a few at a time. My first thought was to attached the controls to particular tabs. Not sure why the syntax is off in the following code. Thanks for the help!
Private Sub Enter_Records_Click()
Dim stDocName As String
Dim tabPage As String
Dim tabNum As Integer
Dim i As Integer
Dim passedTabName As String
stDocName = "CLForm"
tabPage = "tabControl.tabPage"
stTabName = stDocName & tabPage
tabNum = 8 'the number of tabs on the "CLForm"
DoCmd.OpenForm stDocName, acDesign
For i = 0 To tabNum - 1
passedTabName = stTabName & i
CreateKeywords (stDocName, passedTabName)
Next i
DoCmd.Close acForm, stDocName, acSaveYes
DoCmd.OpenForm stDocName, acNormal
End Sub
Public Sub CreateKeywords(frmName As String, tabName As String)
Another idea that might be better, simply having buttons that show one category of controls at a time. Would this be easier?
You need to use the Call keyword when calling a method with more than one parameter and using parentheses.
For example, these would work:
Call CreateKeywords(stDocName, passedTabName)
CreateKeywords stDocName, passedTabName
//Example of using parentheses with one parameter
Msgbox (stDocName)
Welcome to the wonderful world of VBA. ;)
It is best be careful with calling arguments and parentheses:
Public Sub CallingSub()
CallingArg = "ABCDEF"
CalledFunc CallingArg
Debug.Print CallingArg ''Result: 987654
CallingArg = "ABCDEF"
CalledFunc (CallingArg) ''Result: ABCDEF
Debug.Print CallingArg
CallingArg = "ABCDEF"
Call CalledFunc(CallingArg)
Debug.Print CallingArg ''Result: 987654
End Sub
Public Function CalledFunc(CalledFuncArg)
CalledFuncArg = "987654"
CalledFunc = "Return"
End Function