Results 1 to 12 of 12
  1. #1
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33

    Center Form On Screen Comparison / Confusion

    So. I started a project awhile back and for the last couple of years I've been building my "toolbox" of code. With this current project, I started with one form, then added another, and now I'm at three. With the first two, I wrote 2 subs to call on resize in which the objects are centered. An Example of that is as follows:



    Code:
    Option Compare Database
    Option Explicit
    
    
    Dim winWt, winHt As Integer
    
    
    Sub AdjustDash() 'Dashboard
        Dim mainWidth, mainHeight As Integer
        winWt = Forms!frm_02_Dashboard.InsideWidth
        winHt = Forms!frm_02_Dashboard.InsideHeight
        mainWidth = Forms!frm_02_Dashboard!Box1.Width
        mainHeight = 7500 '5.2 Inches coverted to twips
        
        If (winWt > mainWidth) And (winHt > mainHeight) Then
            Forms!frm_02_Dashboard.ScrollBars = 0
            Call CenterHz((mainWidth))
            Call CenterVt((mainHeight))
        ElseIf (winWt < mainWidth) And (winHt > mainHeight) Then
            Forms!frm_02_Dashboard.ScrollBars = 1
            Call CenterVt((mainHeight))
        ElseIf (winWt > mainWidth) And (winHt < mainHeight) Then
            Forms!frm_02_Dashboard.ScrollBars = 2
            Call CenterHz((mainWidth))
        Else
            Forms!frm_02_Dashboard.ScrollBars = 3
        End If
    End Sub
    
    
    Private Sub CenterHz(theWidth As Integer)
        Dim StartLeft As Integer
        StartLeft = (winWt - theWidth) / 2
        Forms!frm_02_Dashboard!lblRange.Left = StartLeft + 120
        Forms!frm_02_Dashboard!imgGRIcon.Left = StartLeft + 2460
        Forms!frm_02_Dashboard!Box1.Left = StartLeft
        Forms!frm_02_Dashboard!Box2.Left = StartLeft
        Forms!frm_02_Dashboard!Box3.Left = StartLeft
        Forms!frm_02_Dashboard!lblDelay.Left = StartLeft + 2460
        Forms!frm_02_Dashboard!lblShift.Left = (StartLeft + 2460)
        Forms!frm_02_Dashboard!cmdLogRange.Left = (StartLeft + 8700)
        Forms!frm_02_Dashboard!lblLastStops.Left = (120 + StartLeft)
        Forms!frm_02_Dashboard!lblDTG.Left = (120 + StartLeft)
        Forms!frm_02_Dashboard!lblLastShifts.Left = (120 + StartLeft)
        Forms!frm_02_Dashboard!lblLastShift.Left = (120 + StartLeft)
    End Sub
    
    
    Private Sub CenterVt(theHeight As Integer)
        Dim StartTop As Integer
        StartTop = (winHt - theHeight) / 3
        Forms!frm_02_Dashboard!lblRange.Top = (StartTop + 60)  '60 is distance from top
        Forms!frm_02_Dashboard!imgGRIcon.Top = StartTop + 1080
        Forms!frm_02_Dashboard!Box1.Top = (StartTop)
        Forms!frm_02_Dashboard!Box2.Top = (StartTop + 2760)
        Forms!frm_02_Dashboard!Box3.Top = (StartTop + 5520)
        Forms!frm_02_Dashboard!lblDelay.Top = StartTop + 2160
        Forms!frm_02_Dashboard!lblShift.Top = (StartTop + 60)
        Forms!frm_02_Dashboard!cmdLogRange.Top = (StartTop + 60)
        Forms!frm_02_Dashboard!lblLastStops.Top = (StartTop + 2820)
        Forms!frm_02_Dashboard!lblDTG.Top = (StartTop + 3270)
        Forms!frm_02_Dashboard!lblLastShifts.Top = (StartTop + 5580)
        Forms!frm_02_Dashboard!lblLastShift.Top = (StartTop + 6030)
    End Sub
    I wrote a similar module for the second form for centering. Now that I have a third form and have a possibility of more, I don't want to continue to write a module for each and with each module, I don't want to list the objects/controls w/ distance from left and top... as it is very time consuming. With the 2 forms that do have the resize module, I can move the access window around and resize it and the objects will move to the center of the window as intended.

    So the rewrite:
    Code:
    Option Compare DatabaseOption Explicit
    
    Dim winWt, winHt As Integer
    
    Public Sub colCtrlReq(frm As Form)
        
        Dim nWidth, nHeight, TPI, StartLeft, StartTop As Integer
        
        TPI = 1440 'Twips Per Inch
        nWidth = TPI * 7.5 'Original Width of Form
        nHeight = TPI * 5.2076 'Original Height of Form
        
        winWt = frm.InsideWidth
        winHt = frm.InsideHeight
    
    
        If (winWt > nWidth) And (winHt > nHeight) Then
            'No Scroll bars
            frm.ScrollBars = 0
            'Adjust Both Vertical and Horizontal Placement of objects
            Call AdjustHz(frm, (nWidth))
            Call AdjustVt(frm, (nHeight))
        ElseIf (winWt < nWidth) And (winHt > nHeight) Then
            'Only Horizontal Scroll bar added
            frm.ScrollBars = 1
            StartTop = (winHt - nHeight) / 3
            'Only Vertical Adjusted
            Call AdjustVt(frm, (nHeight))
        ElseIf (winWt > nWidth) And (winHt < nHeight) Then
            'Only Vertical Scroll bar added
            frm.ScrollBars = 2
            'Only Horizontal Adjusted
            Call AdjustHz(frm, (nWidth))
        Else
            'Both Scroll bars added
            frm.ScrollBars = 3
            'No adjustments made to objects
        End If
    End Sub
    
    
    Private Sub AdjustHz(frm As Form, theWidth As Integer)
        Dim StartLeft As Integer
        Dim ctl As Control
        
        StartLeft = (winWt - theWidth) / 2
        
        For Each ctl In frm
            If (ctl.ControlType > 99) And (ctl.ControlType < 115) Then
                'MsgBox ctl.ControlType & ": " & ctl.Name -> cmd to tblsht
                ctl.Left = StartLeft + ctl.Left
            End If
        Next ctl
        Set ctl = Nothing
    End Sub
    
    
    Private Sub AdjustVt(frm As Form, theHeight As Integer)
        Dim StartTop As Integer
        Dim ctl As Control
        
        StartTop = (winHt - theHeight) / 3
        
        For Each ctl In frm
            If (ctl.ControlType > 99) And (ctl.ControlType < 115) Then
                ctl.Top = StartTop + ctl.Top
            End If
        Next ctl
        Set ctl = Nothing
    End Sub
    With the rewrite, I'll throw Me in after the call on resize and initially, the objects are where they should be, centered accordingly. Once I try to resize the form, no matter what, the objects move in a southeast direction away from center. In the rewrite, it seems the values passed for top and left are the current locations of each object. Is this assumption correct? How would I get the values of the original placement of objects? Do I need to build a table every time this applyed to a form to get those distances?

  2. #2
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33
    This is what I have for the time being. Tested and works

    Code:
    Option Compare Database
    Option Explicit
    
    
    Dim winWt, winHt As Integer
    
    
    Public Sub GatherObjectData(frm As Form)
        'Sub must be called by form on the OnLoad Event
        Dim myRS As Recordset
        Dim ctl As Control
        
        'Previous objects deleted from working list
        DoCmd.SetWarnings False
        DoCmd.RunSQL "DELETE * FROM wkObjects"
        DoCmd.SetWarnings True
        
        Set myRS = CurrentDb().OpenRecordset("wkObjects", dbOpenDynaset)
        
        'Current objects attributes gathered
        With myRS
            For Each ctl In frm
                .AddNew
                .Fields("ObjectType") = ctl.ControlType
                .Fields("ObjectName") = ctl.Name
                .Fields("OrigTop") = ctl.Top
                .Fields("OrigLeft") = ctl.Left
                .Update
            Next ctl
        End With
        Set myRS = Nothing
    End Sub
    
    
    Public Sub colCtrlReq(frm As Form)
        'Sub must be called by form on the OnResize Event
        Dim nWidth, nHeight, TPI As Integer
        
        TPI = 1440 'Twips Per Inch
        nWidth = TPI * 7.5 'Original Width of Form
        nHeight = TPI * 5.2076 'Original Height of Form
        winWt = frm.InsideWidth 'Current Width of Form
        winHt = frm.InsideHeight 'Current Height of Form
        
        If (winWt > nWidth) And (winHt > nHeight) Then
            frm.ScrollBars = 0 'No Scroll bars
            Call AdjustHz(frm, (nWidth)) 'Horizontal Adjusted
            Call AdjustVt(frm, (nHeight)) 'Vertical Adjusted
        ElseIf (winWt < nWidth) And (winHt > nHeight) Then
            frm.ScrollBars = 1 'Only Horizontal Scroll bar added
            Call AdjustVt(frm, (nHeight)) 'Only Vertical Adjusted
        ElseIf (winWt > nWidth) And (winHt < nHeight) Then
            frm.ScrollBars = 2 'Only Vertical Scroll bar added
            Call AdjustHz(frm, (nWidth)) 'Only Horizontal Adjusted
        Else
            frm.ScrollBars = 3 'Both Scroll bars added
        End If
    End Sub
    
    
    Private Sub AdjustHz(frm As Form, theWidth As Integer)
        Dim rsLeft As Recordset
        Dim StartLeft As Integer
        Dim ctl As Control
        
        StartLeft = (winWt - theWidth) / 2
        Set rsLeft = CurrentDb().OpenRecordset("wkObjects", dbOpenSnapshot)
        
        For Each ctl In frm
            ctl.Left = StartLeft + rsLeft.Fields("OrigLeft")
            rsLeft.MoveNext
        Next ctl
        
        Set ctl = Nothing
        Set rsLeft = Nothing
    End Sub
    
    
    Private Sub AdjustVt(frm As Form, theHeight As Integer)
        Dim rsTop As Recordset
        Dim StartTop As Integer
        Dim ctl As Control
        
        StartTop = (winHt - theHeight) / 3
        Set rsTop = CurrentDb().OpenRecordset("wkObjects", dbOpenSnapshot)
        
        For Each ctl In frm
            ctl.Top = StartTop + rsTop.Fields("OrigTop")
            rsTop.MoveNext
        Next ctl
        
        Set ctl = Nothing
        Set rsTop = Nothing
    End Sub
    I'm unsure if there is a better way to do this. All I did call the first module on load and build a table of the original distances.
    Last edited by sgthuth; 08-03-2018 at 10:11 AM. Reason: fix code

  3. #3
    davegri's Avatar
    davegri is offline Excess Access
    Windows 10 Access 2016
    Join Date
    May 2012
    Location
    Denver
    Posts
    3,388
    Don't see need for all this code. Set DB option for Overlapping Windows, then set form properties AutoCenter =Yes.
    Last edited by davegri; 08-03-2018 at 11:56 AM. Reason: sp

  4. #4
    ssanfu is offline Master of Nothing
    Windows 7 32bit Access 2010 32bit
    Join Date
    Sep 2010
    Location
    Anchorage, Alaska, USA
    Posts
    9,664
    A couple of points (applies to all of the subroutines):
    Code:
    Dim winWt, winHt As Integer
    In this line, winHt is declared as an Integer type and winWt defaults to a variant type.
    You MUST explicitly declare variable types or else they default to the variant type.


    Code:
    Public Sub GatherObjectData(frm As Form)
        'Sub must be called by form on the OnLoad Event
        Dim myRS As DAO.Recordset  '<<--- You should use the library type for database and recordset declarations..
        Dim ctl As Control
        
        'Previous objects deleted from working list
    'Instead of
       '    DoCmd.SetWarnings False
       '    DoCmd.RunSQL "DELETE * FROM wkObjects"
       '    DoCmd.SetWarnings True
    
    'use   
        Currentdb.Execute "DELETE * FROM wkObjects",dbfailonerror
    
        Set myRS = CurrentDb().OpenRecordset("wkObjects", dbOpenDynaset)  ' <<-- the parentheses  are not needed
    
        'Current objects attributes gathered
        With myRS
            For Each ctl In frm
                .AddNew
                .Fields("ObjectType") = ctl.ControlType
                .Fields("ObjectName") = ctl.Name
                .Fields("OrigTop") = ctl.Top
                .Fields("OrigLeft") = ctl.Left
                .Update
            Next ctl
        End With
    
         myRS.close   '<<---- you should CLOSE the recordset before destroying it
        Set myRS = Nothing
    End Sub

    You do not need the line
    Code:
    Set ctl = Nothing
    The rule is:
    If you OPEN it, CLOSE it
    If you CREATE it, DESTROY it

    You open a record set, so you have to close it.
    Your create a pointer to the database or recordset by using the SET command, so you need to DESTROY them using SET XX = Nothing.
    So you don't need to destroy "ctl" - it is just a variable.

  5. #5
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33

    Thumbs up Thanks @ davegri

    Quote Originally Posted by davegri View Post
    Don't see need for all this code. Set DB option for Overlapping Windows, then set form properties AutoCenter =Yes.
    Thanks. I figured there was an easier way. I tried out the overlapping windows and it's very... plain. How do I get rid of the annoying looking borders?
    I think the idea of the call allows for more flexibility. I can for instance add a company logo and trademark statement and move them exactly where I need after the adjustments are made on resize.

    I think I was hoping that the idea of my module could be written better than what I have.

  6. #6
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33

    Thanks @ ssanfu

    I did not know globals had to be declared explicitly. Nice to know.

    Thanks for the open/close create/destroy... I'm not really sure why I had those in there like that.

    As far as the code function/efficiency... is the idea of my module good or is the a better way to accomplish the task of center a form/its objects in the same manner?

  7. #7
    isladogs's Avatar
    isladogs is offline MVP / VIP
    Windows 10 Access 2010 32bit
    Join Date
    Jan 2014
    Location
    Somerset, UK
    Posts
    5,954
    Quote Originally Posted by sgthuth View Post
    Thanks. I figured there was an easier way. I tried out the overlapping windows and it's very... plain. How do I get rid of the annoying looking borders?
    There are four choices for border style. Choose 'None'.
    For this to work well, use a form header and possibly a footer. Also set record selectors to No.
    For example
    Click image for larger version. 

Name:	Capture.PNG 
Views:	33 
Size:	51.3 KB 
ID:	34962

    For a really 'clean' look, you can also hide the application window leaving your form 'floating' on the windows desktop.
    Colin, Access MVP, Website, email
    The more I learn, the more I know I don't know. When I don't know, I keep quiet!
    If I don't know that I don't know, I don't know whether to answer

  8. #8
    ssanfu is offline Master of Nothing
    Windows 7 32bit Access 2010 32bit
    Join Date
    Sep 2010
    Location
    Anchorage, Alaska, USA
    Posts
    9,664
    Quote Originally Posted by sgthuth View Post
    <snip>As far as the code function/efficiency... is the idea of my module good or is the a better way to accomplish the task of center a form/its objects in the same manner?
    Don't have any problems with the idea.... but I question the implementation.

    You have a table "wkObjects" with fields "ObjectType", "ObjectName","OrigTop" and "OrigLeft". Each time a form opens and calls the sub "GatherObjectData", the records get deleted and re-added.

    It looks like in the subs "AdjustHz" and "AdjustVt", a record set is opened and then the code loops through the controls collection for the form and sets the Horz and/or Vert position. But nowhere in the code is the control name checked. It seem like you are relying on the record set having the same order as the controls on the form. The problem is that a table is a "bit bucket" - a table has no inherent order.

    In the For/Next loop, I would do a "FindFirst" on the control name, then set the Top/Left values.

  9. #9
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33
    @ridders52
    For future projects, I may use the idea of overlapping windows but now would mean I'd have to do some redesigning.

    @ssanfu
    I did notice in the collection of controls that I could not make out any type of ordering scheme. I ran it several times just to see if the order ever changes and even have added new objects. It runs in the same order each time. If something did happen and for assurance, I'll try to look at rs.findfirst. I've never used it.

    Thanks again guys.

  10. #10
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33
    @ssanfu,
    Code:
        For Each ctl In frm
            rsLeft.FindFirst "ObjectName = '" & ctl.Name & "'"
            ctl.Left = StartLeft + rsLeft.Fields("OrigLeft")
        Next ctl
    It worked. I'm definitely no expert and I was never shown these. I actually don't remember how I came across ADB. I can just remember finding a tool and thinking why has no one used this and why am I just now hearing about it and this was back in 06'. I haven't used constantly since then but I did start trying to figure out how to use it as a tool or make tools around 2012. Somehow, I got a job making use of access and have been toying around making stuff for about 2 years how. I'm definitely still learning. I tried to look into classes at a community college back when I was in service but when I saw the material, it had 3 stages and I thought the 3rd was still elementary. No code was even hinted at.

  11. #11
    ssanfu is offline Master of Nothing
    Windows 7 32bit Access 2010 32bit
    Join Date
    Sep 2010
    Location
    Anchorage, Alaska, USA
    Posts
    9,664
    Great!
    Another thing to know is the "NoMatch" property. Your use of "FindFirst" is very simple; you know that the control name is in the record set because you looped through the controls and added them to the table. But in other applications, you might be checking to see if a value is in the record set. How do you tell if the value being searched for was found in the record set??

    Any time you use "FindFirst" or 'Seek" methods, you should check the "NoMatch" property.(see Help). If the "NoMatch" property is TRUE, it means that the search/seek was not successful - the value was not found.

    Here is an example using your code:
    Code:
        For Each ctl In frm
            rsLeft.FindFirst "ObjectName = '" & ctl.Name & "'"
            If Not rsLeft.NoMatch Then
                ctl.Left = StartLeft + rsLeft.Fields("OrigLeft")
            Else
                'this is where you might have an error message
            End If
        Next ctl


    Good luck with your project..........

  12. #12
    sgthuth is offline Advanced Beginner
    Windows 10 Access 2016
    Join Date
    Dec 2017
    Location
    SC
    Posts
    33
    @ ssanfu
    Thanks for the help. I'll throw that in there for assurance.
    How come the average person that uses office products has no clue what ADB is?

    Thanks again for the help. I really did not know if my concept was written in the simplest or most efficient way. I'll mark this as solved.

Please reply to this thread with any new information or opinions.

Similar Threads

  1. Replies: 6
    Last Post: 05-01-2018, 04:20 PM
  2. Center a form on the screen
    By dniezby in forum Forms
    Replies: 2
    Last Post: 04-13-2017, 06:58 PM
  3. Replies: 8
    Last Post: 09-12-2016, 12:31 PM
  4. Replies: 2
    Last Post: 11-11-2013, 08:39 PM
  5. Center Form Vertically
    By injanib in forum Forms
    Replies: 5
    Last Post: 03-24-2011, 01:51 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums