Centralising Record in Continuous Subform (1 Viewer)

cosmarchy

Registered User.
Local time
Today, 00:22
Joined
Jan 19, 2010
Messages
116
If I have a subform on a form with its view as continuous form which is sized to show three records at a time, is there any way to keep the current record in the center?

1687982849596.png

From the image above, record 2 is selected. When I click on the next button I'd like the next record to be where record 2 is now ie all the records shift up maintaining the new current record 3 in the center position.

The reason for this is that I'd like to be able to see the records either immediately either side of the current record.

Thanks
 

theDBguy

I’m here to help
Staff member
Local time
Today, 00:22
Joined
Oct 29, 2018
Messages
21,473
One way I could think of to do something like that is to use the GoToRecord method to scroll the next record so that's at the bottom and then move back one record to select the one in the middle.
 

Josef P.

Well-known member
Local time
Today, 09:22
Joined
Feb 2, 2023
Messages
826
With Form.CurrentSectionTop you can calculate the position of the current record.
Scrolling could be done using SendMessage.
Code:
Private Const WM_VSCROLL = &H115
Private Const SB_LINEUP = 0
Private Const SB_LINEDOWN = 1

Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" ( _
                              ByVal Hwnd As LongPtr, ByVal wMsg As Long, _
                              ByVal wParam As LongPtr, lParam As Any) As Long
....
SendMessage Me.Hwnd, WM_VSCROLL, SB_LINEUP, 0&
SendMessage Me.Hwnd, WM_VSCROLL, SB_LINEDOWN, 0&
 

cosmarchy

Registered User.
Local time
Today, 00:22
Joined
Jan 19, 2010
Messages
116
Thanks for this guys. I'll have a look and see if I can get something working :)
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 03:22
Joined
May 21, 2018
Messages
8,529
If this is truly a requirement, you may consider making this an unbound form. Then you can format to exactly three records and be able to move the records up and down. If you plan to edit then do that through a pop up instead of directly editing. However, this will require somewhat more advanced coding to use unbound forms.
 

561414

Active member
Local time
Today, 02:22
Joined
May 28, 2021
Messages
280
CurrentSectionTop would indeed help with that task. Depending on the full behavior you want to program, you could modify the following code to suit your needs. It's a combination of the suggestions by theDBguy and Josef, but with built in functionality.
Code:
Public Function bounceRecordView(frm As Form, targetSectionTop As Long)
    With frm
        'going up
        If .CurrentSectionTop < targetSectionTop Then
            If Not .Recordset.BOF Then
                .Recordset.MovePrevious
                .Recordset.MoveNext
            End If
        Else
        'going down
            If Not .Recordset.EOF Then
                .Recordset.MoveNext
                .Recordset.MovePrevious
            End If
        End If
    End With
End Function

I was lazy to find a way to get the section top of the record in the middle programmatically, so I just debug.print CurrentSectionTop in the Form_Current event to get that magic 1935 argument that you'll see in the sample. Very important to have this number right though, so analyze what it does.

NOTE:
It works fine in A2016, but in A2021 the record with focus is at the top when going down. It may need to be more explicit, I'll check it out later. Cheers.
NOTE2:
The problem was with the size of the subform control, I just had to make it a little bit bigger.
 

Attachments

  • test.accdb
    436 KB · Views: 89
Last edited:

Josef P.

Well-known member
Local time
Today, 09:22
Joined
Feb 2, 2023
Messages
826
I was lazy to find a way to get the section top of the record in the middle programmatically, so I just debug.print CurrentSectionTop in the Form_Current event to get that magic 1935 argument that you'll see in the sample. Very important to have this number right though, so analyze what it does.
that magic 1935 argument should be:
Code:
With Me.sf_somedata.Form
      MagicArg = .Section(acHeader).Height + .Section(acDetail).Height
End With

BTW:
From a programming point of view, I would put this routine into a public process of the subform and call it from the main form.
It is then more nicely encapsulated.
Or create a reusable procedure for it at all.
 
Last edited:

561414

Active member
Local time
Today, 02:22
Joined
May 28, 2021
Messages
280
From a programming point of view, I would put this routine into a public process of the subform and call it from the main form.
It is then more nicely encapsulated.
Or create a reusable procedure for it at all.
I put it in a regular module in case it needs to be reused somewhere else, such was the case in the sample, where it's using the on click event of the subform and the buttons in the main form. I was going to add another form to test another variation with arrows, but I hope someone else implements it if necessary.

that magic 1935 argument should be:
Code:
Code:
With Me.sf_somedata.Form
      MagicArg = .Section(acHeader).Height + .Section(acDetail).Height
End With
I made a note about the versions, it works fine in A2016, but not in A2021 when going down, I'll check it out later. Thanks for the MagicArg code, that number is screen-dependent so it'll help adapt the code better.
NOTE:
The subform control just needed to be slightly taller. Readers may want to make sure it's not too tight to fit exactly 3 records and allow a little padding for good measure.
 
Last edited:

Users who are viewing this thread

Top Bottom