I have several buttons coded with VBA behind an Access form. I will have a number of forms which will have these buttons in their footer (new, next, prev, duplicate etc). These buttons are not standard macros, but are simple enough to have the same code work across all of my forms.
How might I go about coding these buttons (which have the same names across all forms.. kind of template-like) so I don't have to copy-paste the code in all my forms? Is there a way to write these buttons in a Module and have the form import that module's text (kind of like most other languages)?
Just curious. Makes the code a lot cleaner/easier, as the beef of the programming is my own but others will be making small edits to the form code.
The simplest thing to do would be to create a Function for each button's functionality in a standard code module. Then change the Click property of each button from [Event Procedure] to the name of the function that corresponds with that button (eg, =MyPrevFunction([Form])).
Note that in order for this to work you must specifically use Function and not Sub. There is no requirement in VBA for a function to return anything, so simply substituting the word Function for Sub is all that is required to make the change.
A picture is worth a thousand words.
As well as the idea suggested by #mwolfe02, you can have your buttons in a subform, which means that only one set of buttons need to be edited, or better yet, set up your own custom menus. These can be invoked on a per form basis or as 'standard' menus for your application. You can even have your own right-click menus.
Related
I have a form with several subforms whose content is edited in separate forms, opened by command buttons.
When the data in those forms is updated, and the extra forms closed, naturally the main form needs to be refreshed before those changes can be seen. Clicking the Refresh All quick access toolbar button achieves this perfectly.
So I made a macro for the "got focus" event on the main form to refresh it, but it does nothing. I tried repaint and requery as well, applying the latter specifically to the subforms in question, and ran them out of vba instead of an access interface built macro too, none of these seem to solve the problem.
vba coding:
Private Sub Form_GotFocus()
Screen.ActiveForm.Requery
Screen.ActiveForm.Repaint
Screen.ActiveForm.Refresh
Me.sfmContact.Requery
Me.frmCustCert.Requery
Me.frmCustReq.Requery
End Sub
Annoying thing is that if I put this (or even just the macro or Screen.ActiveForm.Refresh) in the on click event of one of the controls it works fine. Just can't seem to make it work in any automatic events that don't require thought or clicks from the end user.
This question is sort of a dupe of Refresh button on an Access form but that question is over a year old, and has no accepted answer. So I've expanded on it.
What you mentioned in your comment there is correct:
My guess is that it's not running it, but I don't know why. I got mixed up between OnActivate and OnLoad, which is why I didn't try that option. That works and solves the problem, but why wouldn't GotFocus fire? Surely the main form lost focus when another form got it for updating, and then it got it back again when the other form closed/anything in the main form was selected...
To avoid this type of error in the future, it may be prudent to specifically name the form in your code instead of using the "Me." command, as that only works for current focus. For instance:
Me.sfmContact.Requery > Forms![FormName].sfmContact.Requery
Alternatively, you could just set the focus to the form in question before that sort of coding.
Forms![FormName].SetFocus
I have an Access 2010 database set up with using the native Navigation Form interface feature.
Using this very helpful table, I've been able to use vba on multiple ocassions to reference forms throughout my database. However I seem to be having difficulty in this one instance.
On the Navigation form I have a number of main tabs. Clicking on one of the main tabs brings up a number of sub-tabs that have various forms attached to them.
On one of these sub-tabs, I have a main form (main) attached to it. There is a subform (subform1) within that main form containing a control text box (control1). Within subform1 there is another form (subform2) containing an unbound text box (control2) displaying a value that is calculated using a TempVar.
I want to use the AfterUpdate event on control1 to requery subform2 in order to update the calculation in control2, or simply requery control2.
Using Refresh and/or Requery on the AfterUpdate event for control1 does not do anything to control2.
Currently I have a button on subform2 that users can click which refreshes the form and updates the value in control2. The user can also hit F5 and refresh all the forms with the same result.
My goal is to take away the manual aspect and have the AfterUpdate event for control1 to update control2.
Any help would be much appreciated as I haven't been able to find anything online that works and I've been kicking tires at the problem for over a month now.
**** UPDATE **** I did not correctly describe the layout of my forms. subform1 and subform2 are actually both nested under main. subform2 is NOT nested under subform1 as I originally described above.
Wow. Now I feel like an idiot. Tackling my problem again with the update I provided above allowed me to solve it.
All I needed to do was requery subform2 by referencing it this way:
[Forms]![HOME]![NavigationSubform].[Form]![subform2].[Form].Requery
Where "HOME" is the name of my Navigation Form.
For anyone with the same issue that hasn't renamed their Navigation Form I believe the syntax would be:
[Forms]![Navigation Form]![NavigationSubform].[Form]![subform2].[Form].Requery
Thank you to #Erik von Asmuth and #June7 for your patience and help.
I'm trying to write some code for my database to enable a dropdown box in a parameter prompt for a query, but it's doing nothing instead of it's intended purpose. This:
Dropdown in Access 2007 parameter query
has been the source of my inspiration. Though I seem to be unable to implement even the most basic VBA code:
Private Sub cmdReset_Click()
Me.cboSelectName = Null
End Sub
(Yes this is not all my code! Just one of the subs)
On the relevant form, I have a button called "cmdReset", which has "[Event Procedure]" for the event "On-Click". I also have a dropdown box called "cboSelectName" on said form. Also I have tried closing the database, and making sure to enable macros when it starts.
So essentially this code should make the value in the dropdown box null when I click the reset button. However it does nothing, it simply deselects the dropdown box. Can anyone help me with this one? I'm keen to start implementing some VBA in my database!
As suggested by Remou, the code wasn't even running. I figured out my problem - I had saved the code in a new module, rather than in the VBA code for my form. Once I shifted the code into the form object, the reset button worked. I've also now got some nifty code working with the actual "generate report" command. VBA really has the power to take your database to a whole new level!
I have a form (FORM-A) that requires the user to select a vehicle.
The user should click on a button on FORM-A that say's select vehicle.
A selection form (FORM-B) should open where the user can select a vehicle.
The selected value should be communicated back to FORM-A.
How would you accomplish this in MS Access 2010?
FORM-B is a continuous form that contains a picture of the vehicle and some other information.
From what I understand from your question, you want formB to open a kind of pop-up. When the pop-up is closed, its result is put somehere in the calling form.
Solution proposal:
a) open FormB using syntax docmd.openform "formB", windowmode:=acDialog.
This will prevent execution of the next lines until formB is closed or hidden.
b) in the OK button of FormB, just hide the form, do not close it.
c) when code resumes in formA, you can now
check if formB is still open. If not, it's been cancelled
read the value in hidden formB (still open), then close formB
Otherwise, you could also have formB to update a control in formA before closing. But I don't like that approach because then formB is not reusable, and it creates an unnecessary dependency between formB and formA.
I am not sure why you would need a separate form for this - just have the first textbox be a listing of all the records of vehicles in the database, where you would select one, and the rest of the vehicle information is auto-populated from the vehicle table, but not copied into your parent table. Of course, I am not sure of your table structure either, so there might be a reason for this method that isn't apparent to me.
The benefits of the method above is that if you add more vehicles, your selection box is automatically updated - and you keep the forms you have to load to a minimum (always a good performance move)
You can reference the forms in this manner forms!formName!controlName.
Once you see how this works you will be able to fool with it to get it working with your existing setup. Let’s use 3 controls a text box on Form-A, an image on Form-B and a text box on Form-B. The text box on Form-A will be named txtVehicle, the image on Form-B will be named imgVehicle and the text box on Form-B will be named txtVehicleName.
You can set the name of a control within properties. When you click on imgVehicle it will put the value from txtVehicleName into txtVehicle.
You will have to do a little coding - it's easy though if you have not done it before. Under properties for the image you will see events. If you click on the "On Click" event you will get a drop down list. One of the choices will be [Event Procedure] - choose that. A little button with 3 dots on it will also show up at the end of the row. Click it and you should be taken to a code window with some code like this in it.
Private Sub imgVehicle_Click()
End Sub
Here is where you put your code. Something like this should work. This is it in its most simplistic form.
Private Sub imgVehicle_Click()
Forms!Form-A!txtVehicle=forms!Form-B!txtVehicleName
End Sub
Now although that will work, there are a few things that we should be doing in this method that we are not. We should reference Form-B directly since we are in it, we should verify that Form-A is in fact open.
Private Sub imgVehicle_Click()
If currentproject.allforms(“Form-A”).isloaded then
Forms!Form-A!txtVehicle=me!txtVehicleName
End if
End Sub
Hope that helps
You can create an instance of formB within formA and control it. Below is the VBA code for formA. When clicking on a button on formA, you create a new instance of formB and give it focus. At the same time, you can set properties for its controls. You can use this approach to set the right picture in your control on form B. Hope this helps.
Example:
Option Compare Database
Dim fB As Form_FormB
Private Sub btnA_Click()
Set fB = New Form_FormB
fB.SetFocus
fB.tbxB.Text = "Some text sent from A to B!"
End Sub
If you want both forms to be visible all the time, I suggest using a subform with the list of all the vehicles or just details for the one that the user selected.
I have a series of "on Change" Enabled/Disabled subroutines in the VBA for a form.
When scrolling through the form to view records however, only the main routine runs--the subroutines don't. As a result, questions appear disbaled that have responses displayed.
How do I get the subroutines to run when a record is viewed/changed?
The OnChange only fires when the relevant object is updated. If you want code to run whenever the record is scrolled, put it in the form's OnCurrent event.
I too have found Access form events to be a bit hard to work with/unpredictable. One thing that worked for me is to use a label or textbox and set the Control Source to a formula or a call to my own VBA function to get what I need done. Your control could also be invisible if it is not needed for the GUI. I doubt this is best practice but this "simulated" event worked for me.
If you need conditional presentation in a list, a continuous form and events are not going to do the job. In some cases CONDITIONAL FORMATTING will do the job, but only for appearance -- it can't do things like show/hide controls or alter the rowsource of dropdown lists or requery them.
Conceptually it would be impossible to do so. Form-level events fire for the record. Scrolling through the form does not move the record pointer.
I avoid using continuous forms for editing precisely because of this issue. Instead, I bind a detail subform to the PK value of the record selected in the continuous form, and then the detail form can do all the conditional formatting it needs to.