Link to home
Start Free TrialLog in
Avatar of wsturdev
wsturdevFlag for United States of America

asked on

Tabbing into and out of a subform, both forward and in reverse

I have a form A with 4 fields and a subform B with 4 fields.  The subform is set up so it looks to the user like it is part of Form A.

The tabbing order should be:
A1==>A2==>B1==>B2==>B3==>B4==>A3==>A4

And then with the Shift key held down, the reverse should happen:
A4==>A3==>B4==>B3==>B2==>B1==>A2==>A1


Tabbing from A2 to B1 work without any special code.  But, once I get to form B, tabbing keeps rotating through the Form B fields and never gets out to form A.

So, in field B1, I am using a KeyDown handler:
Private Sub B1_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        If Not Shift = 1 Then
            Me.B2.SetFocus
        Else
            Form_A.A2.SetFocus
        End If
    End If
End Sub

In field B4, I also have a Keydown handler:
Private Sub B4_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        If Not Shift = 1 Then
            Form_A.A3.SetFocus
        Else
            Me.B3.SetFocus
        End If
    End If
End Sub

Forward tabbling from B1 to B2 works.  Reverse tabbing from B4 to B3 works.
Reverse tabbling from B1 to A2 does not work.  Forward tabbing from B4 to A3 does not work.

What happens is that with the Shift Key down in B1, hitting the tab causes the control to go to A2, but then it immediately goes to A1.

With no Shift Key down in B4, hitting the tab causes the control to go to A3, but then it immediately goes to A4.  

I am looking for 1 of 2 solutions here.  The first would be, how do I modify my logic to fix the problem.  The second would be, what technique SHOULD I be using to forward tab out of a subform to the next control on the main form, and backward tab our of a subform to the previous control on the main form -- am I making this too complex and is there a simpler way?
Avatar of Rey Obrero (Capricorn1)
Rey Obrero (Capricorn1)
Flag of United States of America image

see this link

How to Move from Subform to Main Form by Using TAB or ENTER
http://support.microsoft.com/kb/q210011/
Avatar of wsturdev

ASKER

capricorn1 --
Unfortunately, the solution you pointed me to only solves the problem of tabbing forward out of a subForm to a chosen control on a main form.  In my exmple that would be going from field B4 to field A3.  Unfortunately, if you then click into field A2 and attempt to Tab, you go to field B4, not field B1, because somehow the most recently used field on the sub form is remembered.  And the solution does nothing about backward tabbling out of field B1 to A2.

I have finally figured out the correct code and am including it below.  My disappointment is that it takes so much code to accomplish this apparently simple logical tabbing order.

Here is the code that works.  I am still open to a simipler way to do this.

This example requires 2 forms:

Form A with 4 fields and one sub form laid out so the tabbing order is as follows:
A1, A2, SubFrm_B, A3, A4

Form SubFrm_B with its border set to transparent, its view set to single form and no navigation of any kind, with 4 fields laid out so the tabbing order is as follows:
B1, B2, B3, B4

The net result of this organization is that, to the user, it looks like a single form with fields in this tabbing order:
A1, A2, B1, B2, B3, B4, A3, A4

When tabbing forward through the fields the order will be:
A1==>A2==>B1==>B2==>B3==>B4==>A3==>A4

And then with the Shift key held down, the backward tabbing order will be:
A4==>A3==>B4==>B3==>B2==>B1==>A2==>A1

It also requires 2 public variables:
Public varTabKeyDown as variable
Public varShiftKeyDown as variable

In the code behind for Form A

Private Sub A2_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub A2_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = False Then
            varTabKeyDown = False 'Must do this before setting the focus of the destination control
            Form_SubFrm_B.B1.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub

Private Sub A3_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub A3_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = False Then
            varTabKeyDown = False 'Must do this before setting the focus of the destination control
            Form_SubFrm_B.B4.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub


In the code behind for SubFrm_A:

Private Sub A1_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub B1_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            Form_A.A2.SetFocus
        Else
            Me.B2.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub


Private Sub B4_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub B4_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            Me.B3.SetFocus
        Else
            Form_A.A3.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub
OK, I left this question open because I wondered about an extension to this problem, and sure enough, I found it.

I introduced a second sub form SubFrm_C with 4 fields.  I want the tabbing order to be:

A1==>A2==>B1==>B2==>B3==>B4==>C1==>C2==>C3==>C4==>A3==>A4

I used the code I laid out above, that works fine when there is only one subform in the chain of tab sequence.

The extension to the problem is that when I hit the Exit handler in field B4 it executes the code with the exception of this line, which it passes over without reacting to it:

Form_SubFrm_C.C1.SetFocus

The next insertion point ends up being in SubFrm_B field B1.

It does not produce an error.  I have trapped all handlers on SubFrm_C and it does not hit any of them.  It is as though the line of code is treated as a comment.

Any suggestions?
wsturdev,
can you zip your db and upload here http://www.ee-stuff.com
so we can both see what is happening
I am working in something very large and proprietary, but let me create a sample and post it.
I have created a sample DB, zipped it and uploaded to the upload area.  Please let me know if whether you got it.
can you post the returned url message that the upload was succesful
I will repost and capture that.
ASKER CERTIFIED SOLUTION
Avatar of Rey Obrero (Capricorn1)
Rey Obrero (Capricorn1)
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you, capricorn1, for your input.  I had to do a slight further modification, but now I have the example working perfectly.

This is the correct code to accomplish forward tabbing from a main form, into one subform, then directly into a second subform, then back to the next sequential field on the main form, and also perform correct backward tabbing through the same setup.

The example assumes:
A main form called Example_3 with 4 fields, A1, A2, A3 and A4
A sub form called SubFrm_D with 4 fields, D1, D2, D3 and D4
A sub form called SubFrm_E with 4 fields, E1, E2, E3 and E4

Each form only works with a current record and is a single form view.

The correct tabbing sequence is:
Forward: A1==>A2==>D1==>D2==>D3==>D4==>E1==>E2==>E3==>E4==>A3==>A4
Backward: A4==>A3==>E4==>E3==>E2==>E1==>D4==>D3==>D2==>D1==>A2==>A1

The 2 subforms have transparent borders, with the net effect being it looks like the main form has a total of 12 fields all appearing sequentially.

In the code behind for Form Example_3:
Option Compare Database

Private Sub A2_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub A2_Exit(Cancel As Integer)
        If varTabKeyDown = True Then
        If varShiftKeyDown = False Then
            varTabKeyDown = False 'Must do this before setting the focus of the destination control
            Form_SubFrm_D.D1.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub

Private Sub A3_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub A3_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            varTabKeyDown = False 'Must do this before setting the focus of the destination control
            Me.SubFrm_E.SetFocus  ' to get out of the subform and reference another subform
            Form_SubFrm_E.E4.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub




In the code behind for form SubFrm_D:
Option Compare Database

Private Sub D1_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub D1_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            Form_Example_3.A2.SetFocus
        Else
            Me.D2.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub


Private Sub D4_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub D4_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            Me.D3.SetFocus
        Else
            varTabKeyDown = False
            varShiftKeyDown = False
            Me.Parent.SubFrm_E.SetFocus  ' to get out of the subform and reference another subform
            Form_SubFrm_E.E1.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub



In the code behind for form SubFrm_E:
Option Compare Database

Private Sub E1_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub E1_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            varTabKeyDown = False
            varShiftKeyDown = False
            Me.Parent.SubFrm_D.SetFocus  ' to get out of the subform and reference another subform
            Form_SubFrm_D.D4.SetFocus
        Else
            Me.E2.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub


Private Sub E4_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 9 Then
        varTabKeyDown = True
        If Shift = 1 Then
            varShiftKeyDown = True
        End If
    End If
End Sub

Private Sub E4_Exit(Cancel As Integer)
    If varTabKeyDown = True Then
        If varShiftKeyDown = True Then
            Me.E3.SetFocus
        Else
            Form_Example_3.A3.SetFocus
        End If
    End If
    varTabKeyDown = False
    varShiftKeyDown = False
End Sub





cool, good luck to your project..