Gladly, you are not a freak.
Just a few comments, it is late in the UK as you know
You have to be selective in how to invest 'screen estate'
Questions to ask yourself:
1. Do I need all these buttons?
2. Do they need to be available all the time?
3. Are they doing things which I could achieve through an event procedure placed on the form or control.
4. Do they need to be this big?
5. Does the data displayed need to be displayed on the same form as the buttons?
6. Do any of the buttons magnetise into a natural groups
Solutions to your problem could involve hiding/showing overlapping buttons using a option group control's AfterUpdate event to toggle visibility.
Alternatively, if it is really turning into mayhem, you should consider building a custom menu and take the buttons off the form completely.
Most of my buttons dont need to be displayed all of the time, and that got me thinking. Setting visible etc.
QU: I have a Customer Details form with an 'Add Job' button and a 'Save Customer Details' button. How for example could the 'Add Job' button become visible after the details have been saved?
I wrote a little bit of VBA that looked at each button. I had a separate label associated with the buttons because I wanted both a picture and a label. Can't have both if you use the button wizard. So my routine took as inputs the name of the button, the name of its (non-standard) label, and a flag that was true or false depending on whether I needed to see that button.
I also selected one button that was ALWAYS there. (It is the one you click to exit the form. I do some special things for exits so did not want them to use the normal exit button, the little X in the upper right corner on the window bar.) It became my reference point. On Form_Load AND on Form_Current, I loaded the position of the top and right edges of the button and its label to variables in the declarations section of the class module. Therefore, they were global (and persistent) across calls to functions within the class module. You can look at the .Top, .Left, .Height, and .Width properties to figure these things out for all rectangular controls.
Eventually, I made a "state driver" subroutine that twiddled all of the button controls at once based on the information that defined which ones would be present. Then I just called the state driver every time something changed that would materially affect the state of ANY button. Everything except the reference point was local to this state driver.
Then for every button, I called this routine with the appropriate arguments...
Code:
Private Sub ButtonMucker( boNeedIt as Boolean, ctlButton as Control, ctlLabel as Control)
If boNeedIt Then
ctlLabel.Left = loRight
ctlButton.Left = loRight
ctlLabel.Top = loTop
ctlButton.Top = loTop + ctlLabel.Height + 1
loRight = loRight + ctlButton.Width + 1
End If
ctlButton.Enabled = boNeedit
ctlButton.Visible = boNeedit
ctlLabel.Visible = boNeedit
End Sub
Now in my case the geometry was perhaps more constrained than yours might be, because all my buttons had to fit on one line. But conceptually this would still work if you had more than one line free. You would have to add tests to see if the loTop and loRight variables needed to be adjusted.
When the flag was false, the button position didn't matter. All I did was disable it and set it to be invisible, along with its label. BUT if the flag was true, I made the left edge of the selected button (and label) go flush with the right edge of the previous button. Also, I forced the tops to align.
Then the only problem was to make sure I never turned on more buttons than would fit on my line. In your case, if you can move to the next line and start over again, that would work too.