MSAccess VBA:
Assume, in an arbitrary form, the focus is set to MyControl on that form.
How to "unset" the focus without giving the focus to another control?
I'm lokking for a code like
MyControl.UnsetFocus
In your circumstance, you probably want to just set focus back to the parent form. This meets the conditions of unsetting focus without giving another control focus, and tabbing or clicking will activate the focus / tab-navigation again from that form.
Here's an example:
Forms![MyForm].SetFocus
Note that per the documentation for SetFocus, if you attempt to SetFocus to a Form with child controls that have Enabled set, this will cause focus to automatically bounce to the first eligible child control per the documentation.
Form.SetFocus method (Access) # Microsoft Docs
The option to give focus to the parent form does work as proposed by meklarian
Alternatively, I recently had to do something similar but I wanted to update a textbox value and simply go back to whatever had focus before. This is another case where something like an "unsetfocus" would be awesome, but unfortunately doesn't exist.
Should you need to do something like this, the following works well
Screen.PreviousControl.SetFocus
Related
I'm working on a fairly complex Access Database, trying to build forms with custom buttons for working with records. I'm using list boxes to display and navigate through records and all fields for existing records are disabled unless the user presses an edit button. The problem I'm having is that if I press the Edit or Add New button, enabling all of the fields, and then try to change the selection in a combo box, it does not update on the first try.
If I edit a text box first then the combo boxes work fine.
I've determined that the control's beforeUpdate and afterUpdate events are not firing on the first try but the action triggers the form_Dirty event and then it works as expected. I tried setting Me.Dirty = True with the Edit button and that solved the problem but it causes problems with some of my other code and it seems like an unnecessary workaround if only I understood the actual cause of the problem. It also works as expected if I leave the Combo Box unbound, but I am trying to build a template that doesn't require too much work to build new forms off of and I would rather not go that route.
It must have something to do with some bit of code I'm using because I can start a basic form and the combo boxes work fine.
I've started a basic test form and am adding code from my template form bit by bit until the problem arises, but it's a tedious process. Any help would be appreciated.
What am I missing? Is there some way of getting the Combo Box events to fire before the form is dirty?
UPDATE:
I have templates for a basic form, a form with a single subform, and a form with multiple subs in a tab control.
After some more testing I discovered that this problem does not apply to the basic form which has no subforms. This template uses similar code to the others for new, edit, cancel, save and delete buttons and for preventing accidental changes, preventing Form_unload during an edit and so on. The main difference I can think of off the top of my head is that the templates with subforms use class modules and collections to hold various data and pass it between the main form and subforms. Not sure if or how this might relate to combo box functionality.
I built most of this last winter then got too busy over the summer to work on it. Just now picking it up again and I'm having to re-learn a lot of the details of how my code works.
you can try to use Me.CboName.Requery in your After Update event.
I figured it out. I was calling a procedure with a form refresh in it from the Form_Dirty event and for whatever reason the refresh at exactly the wrong time was causing the combo box Before_Update and After_Update events to be skipped and the combo box value to not change. It was also causing text entered into a textbox to overwrite existing text on the first keystroke.
I want to go to a control in a subform in order to be able to enter data.
I can make a DoCmd.OpenForm but then I get an extra copy of the subform on top of the main form. I would rather go directly to the subform. I have tried a lot of options and the following I thought was the most promising
Me.Subform.SetFocus
Me.Subform.Form.mycotrol.SetFocus
DoCmd.GoToControl "mycontrol"
This piece of code does not stop at the Subform to let me enter data. I have also tried Me!Subform with the same result. I have thought of adding a Stop statement, but then I don't know how to resume execution when data has been entered to the subform.
I think there is something I have not understood. Can someone help me out?
Biørn Veirø
VBA is single threaded. It can't work with Access forms this way. You could do it with a modal popup that returns a value, like an InputBox. Access forms don't return a value this way.
If you really want to have a step by step using Access forms then you need to hook in to form events. For this specific case I think the event you want is TextBox.AfterUpdate
https://learn.microsoft.com/en-us/office/vba/api/access.textbox.afterupdate-event
You can have different events on each control object, allowing you to have code that runs after each input.
First set focus to the subform control, then the control in the form:
Me!YourSubformControlName.SetFocus
Me!YourSubformControlName.Form!YourControl.SetFocus
I have my form with a menu bar and space underneath to display my controls. One of the buttons in my menu bar is suppose to be a print button that prints a graph that's currently in a User Control I display in the form. If the graph was on the form in the print button's eventhandler I could just simply call
graph.printing.print(true)
which isn't going to work in my case since the graph is in the control and not the form.
How do I communicate with a User Control from the containing form and access or pass its variables when needed? I also have a status bar on the bottom of the form which would also need to get updated from the User Control, but I'll be able to deal with that if I got help with just this one part. Please bear in mind, I also have another User Control I'm going to add to the form which will also contain a graph which will need the same treatment as the other graph on the first control when the print button is pressed. I plan on swapping these two out so I have one form displaying one control at a time.
I got this idea from this answer: https://stackoverflow.com/a/18191630/2567273 but after further research I can't find anyone asking about the actual communication process between a form and the control it contains.
I think this answer is close to what I'm looking for, but I think it's leading me down the path to using panels instead of User Controls.
After typing this I noticed the closest answer to my question may be this, but that question has the child raising events and the parent responding while I have the parent raising the event and the parent has to get information from the child.
One way to think about this is Roles. Presumably you built this UserControl to handle the management of the data related to the graphs. As such you can think of them in the Role of a Graphs Specialist . Once you do that, printing them is actually just one more thing it should perhaps do.
The form on the other hand, is not special just because it happens to get receive the command from the user to print. Its role in this might simply to be to know which usercontrol to contact and which method to invoke:
Sub PrintGraphMenuClick....
Select Case something ' determinant as to which UC to contact
Case operation.Foo
ucFoo.PrintGraph
Case operation.Bar
ucBar.PrintGraph
Other menu options like Clear, NewGraph, Save and whatever else there is somewhat the same way. The Form's Role here may be to receive the command from the user and pass it along to the right control, invoking the correct right method and passing the correct parameters - that is not a trivial task.
Of course, rather than a MainMenu, the usercontols could alternatively implement a ContextMenu and even receive those commands directly.
Very often offloading an operation to something else results in so many properties, filenames, streams etc having to be moved from here to there that it becomes burdensome. In this case it is not like the MainForm has some special ability regarding printers that the UserControl cannot handle.
There is only one right solution:
1) Add an event to your user control.
2) Raise the event when the particular "thing" happens in the user control.
3) Attach a handler to the event in Form code.
4) Add code to update the bottom bar in the event handler.
Hi I have a VBA application with a combobox selection option.One of the combobox option is Other which when user select that option an invisibled label will pops up and prompt the user to fill the txtOther control.now my question is how I can get rid of the prompted label and make it to invisible after user fill the txtOther and move(focused)in other control?
here is a shot of my app:
Thanks for your time and help
It depends on how often or when you want the check to be done. I couldn't find a good reference to show you all of this, but you can view your VBE.
Within the code behind your userform you can use events for the text box.
If you want the check done every time you leave the text box:
Use the TextBox_Exit event.
If you want it to fire whenever the contents are changed, used TextBox_Change. There's lots of options, but based on your explanation I'd probably use Exit.
This answer shows some syntax examples for using the Textbox_Exit event.
I am trying to hide specific columns in an Access 2007 split form through code. I need the form to check certain conditions to see whether it needs to display a column or not. I have code in the form's 'Activate' event to hide the column like this:
txtControl.ColumnHidden = True
This code works in the "Open" event, but if I hide the column on Activate, it won't display these changes until I close the form and open it again. I have tried calling the form's refresh, repaint, and requery methods, but this doesn't work. Please help!
Edit: Ideally, I need this event to occur whenever the focus switches to this form.That's why I'm using the Activate event rather than the Open event.
Try setting it in either the form's Current or Load events. You will also probably need to requery the control after setting that property: Me.TextControl.Requery Current is called every time a form's record is changed, the form is repainted or requeried. Load, as its name suggests, is called once, after the form has opened when the form loads its records. These have always been more reliable for me than using Activate, which really has to do with more the focus of the form, not really what you want.
I've had a problem like this before working in Access 2002. I was able to solve the problem with a subform by setting the subform source object equal to itself and then running the requery.
Me.SubForm.SourceObject = Me.SubForm.SourceObject
Me.SubForm.Requery
See if this technique works for your particular situation.