Full Version: Tab through subform in both directions
UtterAccess Forums > Microsoft® Access > Access Forms
Egad! I started out trying to do something that I thought would be sooooooo easy and here I am hours later wondering why I started this.

I have a standard form/subform setup...no big deal. What I would like to do is include the subform in the Tab Order between fields of the main form. So, for instance, when Tab is pressed I would like it to go:

..Continuous Subform Fields
Back to Field1

..so if there are 2 records in the subform, I would like it to Tab to:

Subform Record1
Subform Record2
Subform NewRecord
Back to Field3 of Main Form

..if there are no records in the subform, then just:

Subform NewRecord
Back to Field3 of Main Form

AND (there's always an 'and') I want it to work in reverse, so that when Shift-Tab is pressed, it cycles backwards through the same type of routine.

I have attached a DB with the code I came up with. I guess the main questions I have are:
1. Is there a better way to accomplish this?
2. In your opinion, is the way the interface works right now intuitive to the user. (Currently when you move out of the subform with a Tab key, it moves the subform record pointer to the first record.)

It just seems like there has to be a more efficient way of creating this behavior, and it seems like I missed the 'easy way out'.
Walter -

Odon't see any problems with your technique; if there's an easier method to handle it, I don't know it.

However, I find the resetting of the subform record pointer on exit to not be exactly intuitive; I would expect, on TABbing forward into the subform, to move to the first record, but if SHIFT+TABbing backwards into it, to be on the new record (code-wise, you'd have to handle that in the main form's code, not the subform's). Alternately (since users can use the mouse to move from subform to main form without tabbing fully through the subform), just leave the pointer wherever it was last, so TABbing or SHIFT+TABbing just takes you to that position.
G’day Walter.
It depends.
For example:
If the user knows it’s a subform then it probably doesn’t matter.
However, if the subform were to be incorporated in the main form such that the user thought it was still part of the main form then the Tab sequence should be logically reversible.
To that end I’ve attached your demo so that you become the user.
(I just pushed a few pixels around. frown.gif )
Under those circumstances, what do you think?
First, I must confess I haven't looked at any of the attachments so my suggestion may be off-base.
seem to recall doing this by making a textbox control that had one purpose - when it GotFocus it just set the focus to the subform and then to the appropriate control in the subform.
If I recall correctly, the textbox cannot be hidden or the event won't fire so I believe I just set the ForeColor and BackColor to match the form section it was on and I reduced its size to a dot.
Same on the subform - set up a "sentry" textbox that (on got focus) sends the focus back to the primary form.
You can setup beginning and ending sentries so that the user can Tab and Shift-Tab through the form/subform.
Oused it in an contribution type application with tabbed form interface that had lots of data entry and the users loved it (as I recall - at least that's how I remember it ! )

I do like the suggestion about Shift-Tab taking you to the last record. I was having issues implementing it at first, but now that I've got it to work correctly, I think I like this approach best. An aesthetic (sp?) issue presents itself when there are more records on the subform than can be displayed without scrolling. You'll see what I mean in this new attachment. I'm not sure what, if anything, to do about it. This was the initial reason I reset it to the first record when moving out of the subform. Tell me what you think...


I think in my application of this, it would be presented as a true subform. As mention above to Peter, there may be more records than can be visually displayed to the user, so presenting them as just fields would only confuse. But when needed, the technique you describe can be very useful.


When I first read your response, I thought to myself... "DUH! That's the simplistic approach I was trying to think of!" When trying to implement it, though, issues arise because of the subform being continuous. Moving INTO the subform from the main form is great, and I have changed my code to use this techique. But moving OUT OF the subform presents a problem because there are various conditions that can arise based on if there are records already there or not.

Anyway, I have attached a second version with what I believe is improved/simplified code in both forms. Check it out and let me know what you think.....
Walter -
like the way the subform flows when tabbing backwards and forwards into it now; it just feels more intuitive. I am not sure, however, I like the new method (using the GotFocus event of the tiny textboxes, simply because if you decide to use your mouse, those are clickable, and I don't like the effect clicking them has (especially if you just click the bottom one; try it). Although it's a slightly more complicated solution code-wise, I would go with your first method (using the form's KeyDown), but that's just my personal preference; I don't like having the extra elements and UI issues that could accompany them if there is another way.
Thanks for the input. Obviously, I wouldn't have left the blue controls visible to the user....and would have shrunk them quite a bit to make it almost impossible to manually click, but your point is well taken.
Mostly I was just trying to reassure myself that I wasn't overcomplicating things too much with the solution. I guess there isn't really an easy way to achieve this effect. Either way, my client should be happy that they don't have to click into and out of the subform.
So you really prefer the KeyDown method? It's OK, I guess. For some reason in the back of my head I always think using it causes "too much" code to run, if that's even possible. It's just that the event has to fire on every keystroke. Maybe I'm paranoid, but I prefer to run as little code as possible. I feel the same way about the Timer event. Weird, huh?
If anybody's got anymore solutions or insights, feel free to chime in.
Walter -
Very true about the extra overhead with the KeyDown event, although you still have it with the subform.
I've done this before (actually, stringing together multiple subforms in this method); I actually used the KeyDown event of the first and last control on each subform to handle the processing, rather than inserting the "placeholder" controls. While there is only overhead on the first/last controls using this method, it's even more code to maintain than a single routine, so that adds a different complexity (especially if you modify the forms and change control orders).
I like the simplicity of the "placeholder" controls using GotFocus. A simple solution I can think of to keep them from being clicked with the mouse would be to layer a transparent button on top of them that did nothing when clicked (but wasn't in the tab order); of course, that means you have to remember to move both controls if you edit the form layout. Nothing's perfect. frown.gif
What's interesting about this scenario is that there is only one control on the subform and the subform is continuous. So the first control, the last control, and the new record control are all the same control!
uestion: What takes up less overhead? A transparent button that doesn't do anything when clicked? or a solid filled rectangle? The rectangle cannot receive focus, so the tab order shouldn't be an issue. I'm sure either would work, but it's Sunday afternoon and I feel like being inquisitive. Nevermind...it probably wouldn't matter.
I had recently posted a question on this topic. I was looking for a off-the-shelf Class or a Standard module that would manage this type of form/subform navigation. The whole idea, as you appear to grasp, is to allow the user to navigate through the subform as easily as if all the controls were part of just one form. There were no replies. I took that to mean that nobody had worked this out before (or maybe I just posted on the wrong day).
My form has five subforms, all continuous with multiple fields. My current solution involves a public function with custom collections that keep track of control tab orders and key events. It's a little sloppy. What you did seems to be cleaner. Thanx for the post!
I read that post. As of then, I don't think I had this built. But I'm glad you find this method useful. Feel free to incorporate it as you wish and if you come up with any improvements, I, for one, would be glad to see them. I think the reason for the no replies was because your post referred to an off-the-shelf type of solution. IMHO, I have found that around here customized solutions are the order of the day. UA tries very hard to get developers to fully understand the methods of implementation rather than pointing them to a pre-packaged solution. (Nobody wants to pay for something they can write for free.) You may also want to take a look at the commented out section of code in the main form (second attachment). This was the first method I used for navigation, which works just as well, but might be better suited for your needs since you will be jumping to multiple subforms.

InRe: "around here customized solutions are the order of the day."
greed. But I've also noticed that a number of posters, in particular people like freakazeud and Jack Cowley, keep track of useful solutions they've come across over the years and refer to them in their posts.
Anyway, I'm thinking along the lines of a dedicated class with event sinking to manage the navigation. You just got me going in the right direction. If you wish, I'll IM you when and if I come up with something usefull.
It's better to post any solutions/improvements here in the forum so that all can benefit. If you use the Reply link, instead of the Quick Reply, I'll get an email anyway.
esides, I never respond/answer to any technical questions in Private Messages.
See you on UA! frown.gif
Easy solutions (like the Microsoft sample databases and macros) are easy to implement but not very robust.
eversely, an involved coded solution may require more work and testing but allow the most versativity.
Sub-classing the controls and sinking events is an interesting idea for navigation control is an interesting idea. I've not come across any sample of that.
Oimagine code in Form_Load or Form_Open would cycle all controls and subform controls tracking each form's controls and their respective TabStop and TabIndex properties to determine the first and last TabIndex controls for each form. Then you'd instantiate the class passing in a reference to the form(s) and subclassing the first and last controls on each form so you could use the GotFocus() and LostFocus() events to SetFocus to the appropriate control.
Sounds interesting enough that I may give it a go...
stingly, I found a small bug in the code in the sample DB. When putting these methods into my production DB, instead of being a MainForm/SubForm setup, it was actually a MainForm/SubForm/SubSubForm scenario, with the two innermost forms being the two I needed to tab between. The SetFocus method breaks (or at least doesn't work as I expected it to) when trying to move between embedded forms and the only way around it that I could come up with was to do the following:
. Set focus to the MainForm.
2. Set focus to the SubForm.
3. Set focus to the SubSubForm.
4. Set focus to the SubSubForm control.
The method used is described here in detail, along with an example DB.
Yes, I was familiar with the two-step process to set focus to a control on a subform. First setting focus to the subform Control and then to the field on the subform.
I'll take a look at the sample.
That's the way I thought it should work. But it doesn't. At least not from a middle subform. You have to set focus 4 times, as detailed above.
This is a "lo-fi" version of UA. To view the full version with more information, formatting and images, please click here.