Form Function Call Malfunction - vba

First some definitions:
Access Program Name: ATS
Web tool name: C360
C360 doesn't always display readystate indicators in a timely fashion, so ATS is set to time out after five seconds to ask the user what to do next (Error 100). I'm using a form as a message box to allow for better formatting. This button (code below) is what the user presses to capture the data displayed in C360, despite not being in readystate.
I have two forms, one called Basic Ticksheet and one called Advanced Ticksheet (some of my users are a bit overstimulated if presented with too much information) that run the same functions, but display the data differently. Basic and Advanced cannot be open at the same time or read-write errors occur. As such, when Error 100 occurs, and the user presses this button, it is supposed to run the advanced code first, and if an error occurs, re-route to the basic code.
I cannot figure out why Error 2450 ('Microsoft Access Cannot find the referenced form 'Advanced Ticksheet') is firing when the user is using Basic Ticksheet. The code works flawlessly when I manually step through line-by-line. When I press 'Debug' it highlights the line beginning with: Call forms ("Basic Ticksheet"). If I step through using Debug, it also works flawlessly.
What am I doing wrong? Is there a better way to accomplish this?
Thank you in advance for any help you can offer!
Private Sub BTN_CaptureCase_Click()
DoCmd.Close acForm, "Alert Error 100", acSaveYes
Advanced_Ticksheet:
On Error GoTo Basic_Ticksheet
Call Forms("Advanced Ticksheet").Controls("Primary_Review").Form.BTN_CaptureCaseWithWM_Click
Exit Sub
Basic_Ticksheet:
Call Forms("Basic Ticksheet").Controls("BasicCapture").Form.BTN_CaptureCaseWithWM_Click
End Sub
The BTN_CaptureCaseWithWM_Click code is as follows (which calls additional code that is also marked as public):
Sub BTN_CaptureCaseWithWM_Click()
CaptureC360CaseData
ExtractCaseDetails
WMTFrameClick
ExtractWMTDetails
End Sub

The answer to this was as simple as the form containing the function wasn't actually the focus. Totally beating myself up over it, too!
I added a line to ensure the correct form was the focus before calling the code in the form. Of course, I also tooled the flow to make it work better, in the process.
Sub BTN_CaptureCase_Click()
DoCmd.Close acForm, "Alert Error 100", acSaveYes
If CurrentProject.AllForms("Basic Ticksheet").IsLoaded Then
Forms("Basic Ticksheet").SetFocus
Call Forms("Basic Ticksheet").Controls("BasicCapture").Form.BTN_CaptureCaseWithWM_Click
Application.Echo True
ElseIf CurrentProject.AllForms("Advanced Ticksheet").IsLoaded Then
Forms("Advanced Ticksheet").SetFocus
Call Forms("Advanced Ticksheet").Controls("Primary_Review").Form.BTN_CaptureCaseWithWM_Click
Application.Echo True
ElseIf CurrentProject.AllForms("Super Basic Ticksheet").IsLoaded Then
Forms("Super Basic Ticksheet").SetFocus
Call Forms("Super Basic Ticksheet").Controls("SuperBasicCapture").Form.BTN_CaptureCaseWithWM_Click
Application.Echo True
Else: MsgBox "Error 100 routing failure. Please notify ATS Administrator!"
End If

Related

Finding a syntax error in a large VBA/MS Access project

I have a MS Access database that displays an error message about a SQL syntax error on launch. "Syntax Error in query. Incomplete query clause." It also shows another error a few seconds after I hit "OK" on the first one.
Here's the two errors: https://imgur.com/a/PesjIFk
But it doesn't tell me where the syntax error is. There are SQL statements in a bunch of different places all over this project. This is a really large project and it wouldn't be practical to just look through all the code hoping that I notice an error someplace. How can I find out where this error is?
EDIT: Ok, so apparently you have to have a keyboard that has a "Break" key on it in order to even find where the error is. Wow. Fortunately I happen to have one. Here's the code that Access takes me to if I press break when I see the error message. This code is for a subform of another form. It highlights the first line (Private Sub Form_Current()).
Private Sub Form_Current()
If NumEnums > 0 Then
CurrentEnum = val(Nz(bit_value_edit.value)) 'Update CurrentEnum to the currently selected enum
Call UpdateEnumsLabel(Me.Parent![enums label]) 'Update label
End If
End Sub
...and here's UpdateEnumsLabel():
Public Sub UpdateEnumsLabel(ByRef label As Control)
If NumEnums > 0 Then
label.Caption = "Enums: " & CurrentEnum & "/" & NumEnums
Else
label.Caption = "Enums: 0"
End If
End Sub
The definition for CurrentEnum:
Public CurrentEnum, CurrentPort, CurrentFile, CurrentGroup As Long
I'm thinking that this error is unrelated to the code in Form_Current(), but Access is highlighting that line because the error happens when the form is opened. But the form doesn't contain anything that uses a query, so I'm confused as to what query Access has a problem with.
When the error Message pops up, Use Control+Break. It will take you to the line causes the issue.
You should also open a module and form the debug option in the VBA editor select "Compile All Modules"
And since it appears to happening on open/load, you can check both the macros and the main modules to find anything that triggers on AutoExec.
Often ctrl-break will hit the line where you errored out. However, in the case of multiple “events”, and code without error handling, then often the error occurs in the routine that called the code, not the actual code that caused the error.
What I would do launch the application (hold down the shift key to prevent any start up code, or forms running).
Now that you launched the application, but without forms or code running, then check for an autoexecc macro (if there is one, check what code it attempts to run).
If there not an autoexec macro in use, then check under file->options->current database. In this view, you can look/see/determine what the name of the start-up form is.
Once you determined the start-up form (or start up module/code) called from autoexec macro, then you can simply add a blank code module, and place in your code the SAME command that is used to start your application.
So let’s assume no autoexec macro, and you determine that the start-up form is frmMain.
So now, we can launch the application (hold down shift key to prevent any start up code from running). Now, type into a new “test” standard code module the following code:
Sub MyGo
Stop
Docmd.OpenForm "frmMain"
End sub
So you type in above code, hit ctrl-s to save the above code. Now with your cursor anyplace inside of the above code, you simply hit F5 to run.
At this point you hit/stop on the “stop” command in the debugger. At this point, you then can hit f8 to step to the next line of code. If the form in question calls other code etc., you still be able to single step, and “eventually” you hit the line which causes the error.
While the application may be large, a simple look at the start up forms (and huts then the start-up code) means that you ONLY really need to trace and look at the start up code – not the whole application.

microsoft access 2010: Private Sub Form_Load() not running, .setFocus not acknowleged.

So I am trying to create a login form for a database application and I used this article as my guide.
http://accesshosting.com/create-login-form-ms-access
I followed the steps to the best of my knowledge. However, in creating the vba code for the on click procedure for the "Ok" button for the login form. using the code in the webpage I receive an error on the Private Sub Load_Form part of the codeblock. Other users seemed to have issues with this part as well.
The code in which the error is thrown is:
Private Sub Form_Load()
Me.txtUserName.SetFocus
End Sub
.SetFocus is highlighted in this case and error message is shown below.
method or data member not found
I tried researching this question and I saw that there might be an issue with naming of the controls. However, the names all matched up. When i typed Me.txtUsername it popped up with intellisense. However the .setFocus didn't appear as I was typing it.
Not sure what's up. The datatypes for each field are as follows.
userName: text, userLogin: text, userID:number, password: text
Short Version: the form cant load and its because .setFocus isn't accepted as a method. Why?

RunCode macro action from 'hybrid' Access web database error

I have an Access web database
In this database, I have a web form with a button on it
In its on-click event macro, it calls RunMacro Macro1 (client-macro) which fires successfully
in Macro1, if I call RunCode Function Name: DoTest() it returns the error: "The function you entered can't be used in this expression... Error Number 2426 (or 2950 if I have an "=" symbol in front of my function)
This issue is easily reproduced by doing these steps:
Create a blank web database in MS Access
Add and save a table
Create a default form from that table and put a button on it
Create a new VBA module "Module1" and put the following function in it:
Public Function DoTest()
MsgBox "Test function runs smoothly"
End Function
Create a client-macro "Macro1" with RunCode: Function Name: DoTest() (Note that IntelliSense recognizes the macro, and it runs fine from here)
Create the form's button's on-click macro event RunMacro: Macro Name: Macro1
Click the form's button from form-view to receive the error:
The function you entered can't be used in this expression.
You may have used a DoEvents, LBound, UBound, Spc, or Tab function in an
expression.
You may have used an aggregate function, such as Count, in a design grid or in a calculated control or field.
Clicking "Ok" shows error number 2426 or 2950 depending on if you have an equals sign before your function name or not in the client-side macro's RunCode command.
I've tried all of the tips from this very similar question without any luck. Access seems to find the function fine, as replacing the function name with gibberish gives a very different error.
What the heck am I doing wrong?
In my actual web database which uses Access Services published to SharePoint 2010, I use an If IsClient() Then macro statement on the form's button's on-click event to ensure that the VBA is only running in the client mode, but that is not relevant to the error I'm receiving.
After some extra digging, I came across this post in another forum.
Here, the author simply explains that what I'm trying to do doesn't work (when you would think that it should).
Because it's on another forum, I'll spell out the workaround that also worked for me (credit: jakedrew, UtterAccess post, Jun 9 2011). Basically, you need to use a client-form in addition to a client-macro as intermediate steps to get from your web form to VBA. I made this effective for my current application by doing the following:
I re-saved my function as a sub instead:
Public Sub DoTest(ByVal intArg As Integer)
MsgBox "Test sub runs smoothly with argument = " & intArg
End Sub
Create a client-form (mine is named "frmVBA_Bridge") and create the following OnOpen event:
Private Sub Form_Open(Cancel As Integer)
' run your code using this command. Note that if you don't have an argument, you won't include the part of this line following the comma
Application.Run TempVars("SubName").Value, TempVars("Arg1").Value
' reset the "parameters"
TempVars("SubName").Value = ""
TempVars("Arg1").Value = 0
DoCmd.Close acForm, Me.Name, acSaveYes
End Sub
The client-side macro "Macro1" now instead does:
OpenForm
Form Name frmVBA_Bridge
View Form
Where Condition
Data Mode
Window Mode Hidden
The web form's button's on-click embedded macro gets changed to:
If IsClient() = True Then
SetTempVar
Name SubName
Expression ="DoTest"
SetTempVar
Name Arg1
Expression = 100
RunMacro
Macro Name Macro1
End If
Quite a bit of a workaround for such a simple thing, but it seems to do the job!

Programming VBA in an Outlook form

I created my own Outlook form to use it as standard surface to enter certain orders instead of the normal message form. The creation, editing and sending works perfectly fine and in the next step I want to insert some code via VBA.
My problem is that I can´t access the objects of my form in the VBA editor. E.g. I want to show a message box when a certain checkbox is checked. According code would be:
Sub example()
If CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
When I run the code I get the error that the object could not be found. The same goes for every other object, like textboxes or labels etc.
I guess the solution is pretty simple, like putting Item. or sth. like that in front of each object. But so far I wasn't able to find the solution.
I´m using Outlook 2010.
I know this is a year too late but you'll want to do something like this example below. It's kinda a work around but you can get whatever value was selected.
Sub ComboBox1_Click()
Set objPage = Item.GetInspector.ModifiedFormPages("Message")
Set Control = objPage.Controls("ComboBox1")
MsgBox "The value in the " & Control.Name & _
"control has changed to " & Control.Value & "."
End Sub
You should be able to get the value, just get a handle on the object you want using the Inspector
The following is an excerpt from here
When you use a custom form, Outlook only supports the Click event for
controls. This is a natural choice for buttons but not optimal for
controls like the combo box. You write the code by inserting it into a
form’s VBScript editor. You need to have the Outlook form open in the
Form Designer and click the View Code button found in the Form group
of the Developer tab.
Sub CheckBox1_Click()
msgbox "Hello World"
End Sub
The code page is fairly minimal with no syntax highlighting. I just tried this now and it does work. Dont forget to Publish your form to pick up the new changes.
I know this is almost 6 years late but, in VB and VBA, simply start with the form name. (And if that doesn't work, just keep going up a parent object and you'll get there.) So, your code becomes:
Sub example()
If MYFORMNAME.CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
Of course, after typing "MYFORMNAME." you'll know if it will work because typomatic will kick in when the system recognizes "MYFORMNAME" after you hit the period.

Preventing close buttons from saving records in MS Access

In a Microsoft Access form, whenever the current record changes, any changes in bound controls are silently saved to the database tables. This is fine, but I don't want it to happen when a user closes a form, because it is the direct opposite of what many people would expect.
The best example is when you try to close an excel file with unsaved changes, it asks whether the changes should be discarded. This is exactly what I'm trying to achieve in Access, but can't find any way to trap the close button's event in VBA.
The form's Unload event is the first event that is triggered when someone clicks the close button, but by then the changes are already written to the database.
Is this at all possible, or do I have to create my own close buttons? I'm comfortable with writing large amounts of code for trivial things like this but I hate having to clutter the GUI.
You have to work with Form_BeforeUpdate event. Below is an example; however it does create a typical warning message: "You can't save this record at this time. Microsoft Access may have encountered an error while trying to save a record. ..." - depending on your database settings. You can use simple workaround below to avoid displaying of that message.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = True
'Or even better you can check certain fields here (If Then...)
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = True
End If
End Sub
Sean gave an almost correct answer but it leaves gaps.
In general, the FORM's BeforeUpdate is the most important form event. It is your LAST line of defense and ALWAYS runs prior to a record being saved regardless of what prompted the save (form close, new record, your own save button, clicking into a subform, etc.) Although I occasionally use the control's BeforeUpdate event just so the user gets the error message sooner, the bulk of the validation code I write runs in the Form_BeforeUpdate event. This is the event you MUST use if you want to ensure that certain controls are not empty. No control level event will do this reliably for all situations. Primarily because if the control never gets focus, no control level event ever fires. Form_BeforeUpdate is also the event you would use if your validation involves multiple fields. If you are using any other control or event level event, you are wasting your time. There is always away around your "trap" and your table almost certainly contains invalid data.
Regarding the OP's question. If you want to force people to use your own save button and prompt them if they don't then you need a form level variable as Sean's suggestion implied. The only difference, is that you need to set it to False, in the form's Current event NOT the Open event. You want the flag to be reset for EVERY new record, not just when the form opens. Then you set it to True in your save button click event, just before you force the record to save with DoCmd.RunCommand acCmdSaveRecord.
Then finally, in the Form_BeforeUpdate event, you check the value of the variable.
If bClose = False Then
If MsgBox("Do you want to save the changes?", vbYesNo) = vbNo Then
Cancel = True
If MsgBox("Do you want to discard the Changes?", vbYesNo) = vbYes Then
Me.Undo
End If
Exit Sub
End If
End If
this is code I have that checks to see if the form is being closed or saved.
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Not UsingSaveButton Then
If MsgBox("Abandon Data?", vbInformation + vbYesNo) = vbNo Then
Cancel = True
Else
DoCmd.RunCommand acCmdUndo
End If
End If
End Sub
I have a Boolean Flag that is set to False on loading, and then when my Save button is used, I set it to true to allow the update to run through.
If the flag is not set, then they are leaving the record (either through going to a different record, or closing the form) so I ask if they actually want to save the changes.
The Cancel = True aborts the exit of the form or the move to a different record if any changes have been made.
The DoCmd.RunCommand acCmdUndo undoes any changes so they are not saved.
Actually, you cannot trap this, Access is working directly upon the table, every change is already being saved when the field looses the focus by moving to another field, record or a button.
Actually imho this is a great advantage compared to Excel
If you really want a behaviour similar to Excel you'd need to work on a copy of the table and some code for updating.
In the Form in the 'On Unload' event add the below code.
DoCmd.RunCommand acCmdUndo
DoCmd.Quit
Records no longer being saved when users close a form in any way.
** you can use exit button with this code**
Private Sub Button_Click()
If Me.Dirty = True Then
If MsgBox(" Save Change ", vbYesNo) = vbYes Then
Me.Dirty = False
Else
Me.Undo
End If
End If
DoCmd.Close acForm, "FormName"
End Sub