Access form's Detail's event only triggers on first record - ms-access

I'm designing a Form in Access 2003. My goal is that when the user double-clicks on a record (aka Detail), a second form opens. This is easy enough to do when I start from scratch.
But of course, I'm not starting from scratch. I've been working on this for a few hours now, have added some conditionally formatted textboxes, fields, etc, and don't want to start over if I can avoid it.
I don't know if I turned on/off some obscure property, but I've been working on this form for a few hours now and the Double-Click event of the Details section only triggers when I double-click on the first record or any other with conditional formatting.
To troubleshoot this, I've gone so far as to comment out all the other VBA script except this:
Private Sub Form_Load()
Me.Application.DoCmd.Maximize
End Sub
Sub GotoFrmDetails()
MsgBox "You Double Clicked Me!"
End Sub
Even with the VBA script reduced to just these lines, the DoubleClick event only triggers on the first record and no other. Can anyone tell me what wrong? I'd rather not have to rebuild this from scratch.

I find the click events of form sections to be more trouble than they are worth (click event doesn't pass through to the form if user clicks on a control or label, etc). What I use instead are transparent command buttons.
Just add a command button to your form and set its Transparent property equal to True. Then you can use the Z-order to make fine-grain changes if necessary (send to front/back, send forward/back).
They can be hard to find once you make them transparent, so be sure to give them descriptive names.
If you want the user to be able to double click anywhere in the detail section, just make the transparent command button's height/width match the section height/width.
Move your code from the Detail section DoubleClick event to the transparent command button's DoubleClick event and you should be good to go.

I'm wondering if the rows are getting their Locked property set to Yes, or their Enabled property set to No during your condition formatting.

Related

Unable to replicate Refresh All quick access toolbar button in form

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

Prevent 'save design changes' for an open form when closing Access

I have a split form as my main interface in an Access 2010 application. As normal, users are able to resize the datasheet portion, reorder columns, etc.
However, I don't want them to save such changes when leaving the form. Each time the form is opened the default format should be loaded.
I've taken care of all but one closing method. To avoid them closing using the default close button I've set Border Style = None. Instead I have a Close Form button that uses DoCmd.CLOSE acForm, "Main_form", acSaveNo
But if the user clicks the close button for the Access application, it pops the 'Do you want to save changes to the design of form` dialog like always.
I looked into disabling the application's Close button, but messing with Windows API is beyond my skill (and there should be a way to accomplish this without going to extreme measures).
I found a way to do this. A combination of database options, form format options, and vba can do it.
Go to the 'Current Database' options screen in the main Access
options and uncheck 'Enable design changes in Datasheet view'. This will prevent all datasheet view design changes in the database, so you will have to go into design mode for any table changes. Users can still reorder and resize columns within a form, but Access no longer considers that a valid design change and will not prompt to save it no matter how you close the form
Set the form format property 'Save Splitter Bar Position' = No. The form will now clear any change to the bar location when the form is closed. Access got really weird on me about this setting, however. Once I had ever set the option to no, I could no longer use design view or layout view to set a new default bar position; it always reverted to the location where it was when I first tried this setting. Even resetting the option to Yes, saving the design change, and fully exiting the database did not fix this.
So I added an On Load event to reset the split form size when the form opens: Me.SplitFormSize = 9000. The numbers involved are surprisingly high; in the form properties list this is set in inches. Mine was 6.5", which apparently translates to 9000.
With these three changes (along with the steps I detailed in the question) Access no longer prompts to save design changes when the form is closed, even if the user is closing the Access application entirely. The form also snaps the split form bar back to where it should be on load.
Since the API is beyond my skill too, here is a left-field workaround.
Duplicate Main_Form and rename it "Main_Form_Template". Create an Autoexec module or edit an existing one and add:
DoCmd.DeleteObject acForm, "Main_Form"
DoCmd.CopyObject , "Main_Form", acForm, "Main_Form_Template"
That should reinstate the standard template for the user each time they open the database even if they were to save the form when closing Access.
Turn your close button off on the form.
On the form's property sheet, format tab, about 2/3 of way down. Set Close Button = No
This forces the user to close it via the button you created.

Run VBA code whenever a tabbed form is reselected in Access

EDIT: For clarification, I'm talking in the below post about tabbed document browsing, not a Tab Control. However, if you're looking for roughly the same problem but regarding a Tab Control, Gord Thompson's answer is correct. Two answers for the price of one!
I've got an Access 2007 database that uses tabbed documents. I need to run some VBA code every time a user selects the form called "Reports", either via opening it or clicking on its tab if it's already open.
I could achieve much the same thing by closing it each time it's used and running the code on an OnLoad event, but ideally I'd like to keep it open so that users can keep the settings of the various drop down boxes, radio boxes etc that they've already set on "Reports".
I was hoping for an event that could run code on tab reselection, but neither of my guesses (OnCurrent and GotFocus) seem to work (OnCurrent works only when the form is opened, like OnLoad would).
Any ideas greatly appreciated - can't find what I'm looking for on Google, though I suspect that's because I don't know exactly what I'm looking for.
The .Value property of a TabControl returns the index (zero-based) of the current page. So, if I have a TabControl named TabCtl14 that contains two pages, FirstPage and SecondPage, then the code...
Private Sub TabCtl14_Click()
If Me.TabCtl14.Value = 1 Then
MsgBox "SecondPage was clicked."
End If
End Sub
...displays the MsgBox whenever I click the "SecondPage" tab in the TabControl.
Have found the answer I was looking for. It's the OnActivate event.

Obtaining textbox value in change event handler

I've written a form that performs queries asynchronously as text is typed into a textbox, however I somewhat arbitrarily seem to get the following error thrown: "You can't reference a property or method for a control unless the control has focus."
The immediately relevant code is:
Dim UpdateRequested As Boolean
Dim qryText As String
.
.
.
Private Sub txtBox_Change()
qryText = txtBox.Text
UpdateRequested = true
End Sub
Some place in the ellipses is the code that handles dynamically loading an ADODB record set, populating a local table, and refreshing a sub form. However, even when I disable this code, the problem persists: Sometimes I get the error. Sometimes I do not.
This seems to be persistent through closing the database and reopening it. Every time it starts working again, it's because I've been fooling around with code in the debugger, but I'm not sure what exactly is causing it to magically "just work" or what is causing it to not work at all.
Update
Just to make things more puzzling, I added a couple of simple event handlers:
Private Sub txtBox_GotFocus()
MsgBox "Got focus"
End Sub
Private Sub txtBox_LostFocus()
MsgBox "Lost focus"
End Sub
I run the form. I click in the test box. I receive the "Got focus" message. As soon as I type I see the error as described above. If I re-open the form, I can click between the text box in question (which itself is unbound) and a bound text box in the sub form and see both "Got focus" and "lost focus" messages as one would expect. Furthermore, showing a message box with the current value of "Screen.ActiveControl.Name" shows the expected name just before the Text property is accessed.
I know this is an old thread but it's the first I found when I had the same problem. None of the answers helped except Kaganar's own solution, which pointed me in the right direction. I'm guessing the reason people had trouble reproducing the error is there are some important details missing from Kaganar's description:
The Textbox was in the form header (or footer).
The form did not allow additions.
Because I believe the full answer is...
The Text property of any control is inaccessible when the form has a record source with no records to edit
I think there is part of Access that does not realise the textbox exists :) To understand how that might come about...
Put the unbound TextBox in the detail of the form
Do not allow additions
Set the recordsource to return no records
Open the form.
Hey presto! No Textbox.
Return a record, or allow additions, or delete the recordsource, et Voila! There is your Textbox with it's Text.
I added a text box named txtFoo to my form. Here is the procedure for its change event.
Private Sub txtFoo_Change()
Debug.Print "Value: " & Nz(Me.txtFoo.value, "*Null*") & _
"; Text: " & Nz(Me.txtFoo.Text, "*Null*")
End Sub
Then, with nothing in txtFoo (IOW its value is Null) when I type "abc" into txtFoo, here is what I see in the Immediate window.
Value: *Null*; Text: a
Value: *Null*; Text: ab
Value: *Null*; Text: abc
Basically, each character I add to the text box triggers its change event and prints the text box's current contents to the Immediate window.
As far as I understand, you want to do something similar ... except you want a different action in place of Debug.Print. Take another look at your change event procedure and compare it to mine.
Private Sub txtBox_Change()
qryText = txtVendorName.Text
UpdateRequested = true
End Sub
That is the change event for a control named txtBox. Within that procedure you reference the .Text property of a control named txtVendorName. However txtBox is the active control at the time its change event code runs ... so you can not access the .Text property of txtVendorName because it is not the active control.
Given that this problem surfaces for only the one form, but not on other new forms, I would suspect the problem form has become corrupted. Read the 2 answers to this SO question and try decompile to cure the corruption: HOW TO decompile and recompile. Decompile is often recommended as a routine practice during development.
You could also use the undocumented Application.SaveAsText method to save your form as a text file. Delete the bad form, and use Application.LoadFromText to import the saved text copy.
Make sure you have a backup copy of your db file in case anything goes wrong.
To set or return a control's Text property, the control must have the focus, or an error occurs.
To move the focus to a control, you can use txtBox.SetFocus or DoCmd.GoToControl "txtBox".
Also, the Text property is not always available:
While the control has the focus, the Text property contains the text data currently in the control; the Value property contains the last saved data for the control. When you move the focus to another control, the control's data is updated, and the Value property is set to this new value. The Text property setting is then unavailable until the control gets the focus again.
The form had a lingering data source. I'm not sure why this would cause to the behavior described above, especially considering the text box controls are unbound, however since removing the data source the text boxes are behaving as expected.
You said "somewhat arbitrarily" I think if everything is fine you must get the error when your form's recordset is empty.
In fact it's a know bug in Access and this error can occur if these conditions are met:
a) The control is in the Form Header or Form footer section
b) The form is filtered such that no records match (or there are no records)
c) No new record can be added.
In this case, the Detail section of the form goes blank. The controlis still
visible, but Access gets really confused and can throw the error you
describe.
More info:
http://allenbrowne.com/bug-06.html
I know my answer is out of date. Yet you just can set focus three times. On TextBox in header, on any texbox in detail space and On TextBox in header again. I use access 2003.

MS Access: How do forms communicate values to each other?

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.