I have form that displays information on a project. Most of the fields on the form are bound to a Project table and display and update as bound fields do. However, I also have 10 checkboxes that come from a ProjectAudience table. Only if the box on the form is checked, is there is a matching record in the table. Therefor, I need to insert and delete records as these boxes are checked and unchecked.
I can do it at the checkbox level with the AfterUpdate event, but that would require 10 different events. I looking to do it at the Form level by deleting all records in the ProjectAudience table for that project and adding in the checked ones.
Basically, I'm looking for the opposite of the Form_Current event that will fire when either the record navigation button is fired or the form is closed. I'm trying to avoid either writing my own navigation buttons or adding a "SAVE" button to the form that the user must press. I want something automatic that will update this table when the user navigates away from the record.
Based on a comment below: Any combination of boxes from none to all can be checked not just a single box. Therefore, it is possible that I would wipe out all records and not insert any back... or add 10 records if every box was checked. (Also, I am using Microsoft Access 2003)
Have you considered adding these checkboxes to an Option Group and using events from that group?
EDIT re Comment, Alternative approach, do not use an option group, but add code to an event line for all relevant options.
You do not need code for 10 different events, you can set the event line for, say, On Click to the name of a function, let us say:
On Click : =TestMe()
Event Line http://ltd.remou.com/access/EventLine.png
You then need a function:
Function TestMe()
MsgBox "You clicked " & Screen.ActiveControl.Name
End Function
You can use the BeforeUpdate method. However, if only the checkboxes have been changed this event will not fire since the record to which the form is bound didn't change.
I would advise to link events to the checkboxes. Create a function UpdateCheckbox(CheckboxID as integer) that does what you want and put this in the 'OnClick' event from the ckeckboxes: =UpdateCheckbox(1). Change the 1 for the different checkboxes.
Related
I have a Tab Control element containing 2 tabs: Tab1 and Tab2. Tab2 contains a ListBox element whose RowSource queries the data that gets submitted in Tab1.
Say the user opens this form containing these 2 tabs. They are originally on Tab1. in the Form_Load event for Tab2, it queries the data it needs to populate its ListBox. Now they switch tabs to Tab1. They enter some data and submit a new record to the corresponding table (the same table that the Tab2 ListBox uses as its RowSource). When the user switches back to Tab2, they don't see this newly added record.
What I have done so far is that when the user clicks anywhere in the ListBox, it calls Requery, and then the record will show up. This isn't enough as it's not intuitive for the user to have to click on the listbox to update its contents.
I have tried putting this Requery code in a Form_Load, Form_Activate, GotFocus, but nothing works. I know you can detect the TabControl clicks, but how can I access the forms and the elements that they contain?
Any ideas on how to requery this listbox whenever the tab gains control?
If you want to add code for a specific tab on a tabcontrol, the most convenient way to do that is to write code in the TabCtl_Change event. That occurs when the tab control is changed. E.g.:
Private Sub MyTabCtl_Change()
If MyTabCtl.Pages(MyTabCtl.Value).Name = "Tab2" Then 'The tab control just changed to your page
'Requery that list box
End If
End Sub
Note that, if you're not using a tab control at all, but a navigation control (which it does sound like, tab controls don't necessarily have subforms on them, and don't have Form_Load events, forms do)
You're most likely looking for the On Activate trigger.
Then, in the code just use Form.Requery or Form.Recalc depending on which you're actually looking to do.
Alternatively, you could use the same control the user is using to submit records to trigger a requery. Although, that would require a specific Form to be called into focus.
I have an unbound combo box that gets it's row source values using a select query in VBA. The values shown are filtered by other selections on the form. If a value entered is not on the list I have a prompt to ask the user if they would like to add a new record. So far this has worked without any problems.
I overlooked one issue. If the "new" item is a partial match the selection defaults to the partial match entry. (Ex. I want to add part 4321437 but part 4321437-01 is already present.) How can I get the field to match using the full field?
I have tried playing with auto expand, allow value list edits, show only row source values, and inherit value list. Nothing seems to stop it from auto-filling. I have also tried clicking out of the field versus tabbing out.
If I remove my for key-down event that displays the list options with the arrow keys, it works. However, the customer would like to keep that feature.
Is there a way to have both?
Thinking outside the box, perhaps consider using a TextBox in place of a ComboBox.
This way, using the AfterUpdate event, you would have full control over how the entered value is handled: test for a match in your dataset using a simple query and branch accordingly.
You could even cycle through existing options by successively populating the TextBox with existing values from your dataset on the KeyDown event triggered by the arrow keys.
I found a way to have both. In my Key Down Event, I check if the down arrow is pressed. If it is, I display the drop down menu.
If KeyCode = vbKeyDown Then
Me![cboNewPart].Dropdown
End If
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 hope someone can help me out, or at least help figure out a workaround.
I'm using Access 2007's split form feature, and have the code below run on the Form_Open event, as well as after two button_click events. The code works fine when run after the button_click events, but when it runs on the form_open event, it causes problems.
If form is opened and user enters text in the first field, he/she cannot use Tab or mouse to select the next form field. The user is stuck on the first form field until pressing Esc to cancel the data entry. In order to successfully enter data in the first form field when the form is opened, a user must first select another form field, then re-select the first form field then enter text in first form field. After this nonsense, the user CAN select next form field with Tab or mouse. This must be performed once every time the form is launched. The same VBA code on the button_click events works fine.
Noteworthy: When the form is first opened, NONE of the form fields in the datasheet section of the form appear 'Selected'. When a user begins to enter data in the first form field, the 'new record' marker (*) moves to the second row as it should, but the first row does not show the data being input. This behavior is odd.
After performing the clear field, click another field, click back to first field workaround described above, the datasheet shows properly selected fields and Data as it is input.
Any ideas? Is this a bug? Is there an easy workaround, such as performing the field-select workaround via VBA at form open?
Any help is MUCH appreciated.
Code:
DoCmd.ApplyFilter , "([Contractor].[CheckOutStamp] Is Null)"
DoCmd.GoToRecord , "", acNewRec
Link to mdb:
https://docs.google.com/leaf?id=0B-jx09cwIQDsYWM2MzMzMDQtYjUzNi00N2E5LWFjYTktNzFiYWYzMDZiYWU1&hl=en&authkey=CPPmoMEF
Some thoughts:
Try moving it from OnOpen to OnLoad. The events in OnOpen can happen before the data is actually loaded, where as OnLoad happens after that is already done.
Also, you might want to just set the form's Filter property to [Contractor].[CheckOutStamp] Is Null and set the FilterOn to Yes, and set the form to DataEntry, which means it defaults to a new record upon open, and doesn't load any of the older records. Once it's open, you can change the form's edit/add mode to whatever you like.
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.