How to prevent Excel UserForm from shrinking/expanding autonomously? - excel

My Excel UserForms contain a variety of objects, including text boxes, combo boxes, radio buttons, etc. The UserForm and the objects on the UserForm shrink and expand when my laptop is on a docking station and the VBA window is open on a larger monitor.
When I access the UserForm editor from the Forms tab in VBA, I can drag the UserForm resize handles and the objects in the UserForm will immediately snap back to their original state, but I want to do this programmatically so that the end user will not deal with shrunken/expanded UserForms.
I have tried resizing the UserForm upon opening (UserForm_Initialize), but it seems as if the shrinking/expanding takes place while the UserForm is not active, meaning that my UserForm resizing only acts to return the UserForm to its shrunken/expanded state and not its original state.
Sub UserForm_Initialize()
Call ResizeUserform(Me)
End Sub
Sub ResizeUserform(UserForm_Name As Object)
UserForm_Name.Width = UserForm_Name.Width + 0.001
UserForm_Name.Width = UserForm_Name.Width - 0.001
UserForm_Name.Height = UserForm_Name.Height + 0.001
UserForm_Name.Height = UserForm_Name.Height - 0.001
End Sub

Don't leave your form's dimensions ambiguous or prone to logic circularity (i.e. as a function of itself); set them up before loading/showing.
i.e.:
'where XX and YY are integer constants:
With YourFormName
.width=XX
.height=YY
.show
end with
If you absolutely need to incur in circular statements, do it indirectly by storing your calculated variable in a global/local variable, and then proceed to declare its properties (i.e. YourFormName.width=variable)
Good luck!.

I had a similar issue, ever time the program opened the Login user form would be smaller than the last time. It only did it on my lap top with extra monitors. I finally used
Private Sub UserForm_Initialize()
With Userform
.Width = Application.Width * 0.3
.Height = Application.Height * 0.6
End With
End Sub
in the userforms code and it kind of stopped meaning it no longer showed the user the change but if I open the VBA it had changed size on the Height and Width but since it was only in the VBA and the user didn't have to try and enter a password in a mini box its fine.

I had a similar problem. The only thing that worked for me was going into the Advanced Options of Excel and checking the box, "Disable hardware graphics acceleration." I wasted several hours trying to find this. I hope this helps someone else!

Don't make the form maximized. "Maximized" means you don't know at design-time what the size of the form will be, because you're making that depend on what monitor size it's being displayed in.
Larger monitor = larger maximized form, that's by design.
If you don't want the form to resize automatically when it's displayed in a different-size monitor, then don't maximize it.
Alternatively, handle the form's Resize event, and programmatically move each control where it needs to be relative to the bottom-right edge. Note, that's tricky and extremely annoying code to write, especially if the form is any kind of complicated. Much simpler to just not have a maximized form.

this operation can also be done with a loop. I used the button to increase and decrease the height of userform. I created a loop and assigned it to the button.At the same time there was a nice animation.
You set a height value, when the button is pressed, the userform becomes longer if the height is less than this value, and the userform becomes shorter if it is larger.
Codes:
Private Sub CommandButton4_Click()
Dim X, d, yuk, mak As Integer
For X = 1 To 100
DoEvents
If e = 0 Then
d = d + 10
yuk = 242
mak = 342
Else
d = d - 10
yuk = 345
mak = 245
End If
UserForm2.Height = yuk + d
If UserForm2.Height >= mak And e = 0 Then GoTo 10
If UserForm2.Height <= mak And e = 1 Then GoTo 20
Next
10 CommandButton4.Caption = "<"
e = 1
ListBox1.ListIndex = 0
ScrollBar1_Change
Exit Sub
20 CommandButton4.Caption = ">"
e = 0
ListBox1.ListIndex = 0
End Sub
It's video :https://www.youtube.com/watch?v=1LCxgQGy9tU
Source and Example file here

Related

Windows Media Player embedded in Excel-Form: Player starts to flicker when changing ".Width"

About four years ago I built an Excel (Version unknown) app in vba to view Videos in a form. It worked fine at that time. I didn't use the program for quiet a while, and now (Excel 365 V2203) the player starts to flicker, as soon as the program tries to assign a new .width or .heigth to the player (Code below).
When I comment out the block, everything works fine. Yet, the player window is too small.
Even reassigning .Width parameter the value dWith does not lead to a problem
When I resize the Player Window in the properties window, the size is automatically reset during initalisation of the form.
Any ideas? Thanx in advance.
Gin
Private Sub UserForm_Activate()
Dim dHeight, dWidth, dMaxHeight As Double
Dim i As Double
i = Timer
Do While Timer < i + 1 'Seconds
DoEvents
Loop
' No problems if next block is commented out (yet, video too small)
With WindowsMediaPlayer1
.settings.autoStart = False ' also does flicker, if set to True
dWidth = .Width
.Width = 2 * dWidth
.stretchToFit = True ' also does flicker, if set to False
End With
' End of block (to comment out in order to avoid problems)
End Sub
```

How to display progress bar when userform is loading in VBA excel

I have created Macro using Userform and it has many controls which are Static in nature and displays upon userform intialization. But it also has (Userform initialize code) code written add checkboxes in one of the frame dynamically using the data in the sheet1. which is taking a bit of time(say 30 sec-1 min) depending on the data present in the sheet.
during this period i want to user to be shown a progress bar of % completion.
I tried Application.Statusbar functionality but it didnt workout. So thought to go for Progressbar. Can anyone please help in this regard?
This is the progress bar I've used for the last five or six years (originally posted in http://www.mrexcel.com/forum/excel-questions/527468-progress-bar.html).
I'd follow Rorys advice though and use a listbox if you're creating potentially hundreds of controls.
Create a form called 'Progress Bar'
Give it these dimensions:
Name: ProgressBar
Height: 49.5
Width: 483.75
ShowModal: False <---- Important this bit or it won't update properly.
Add a label to the form with these dimensions:
Name: BoxProgress
Caption: BoxProgress
Height: 18
Left: 6
Top: 6
Width: 468
BackColour: &H008080FF&
In a normal module add this procedure:
Sub UpdateProgressBar(n As Long, m As Long, Optional DisplayText As String)
'// DarkSprout April08
'// Omit DisplayText to display progress percentage
On Error GoTo ERR_HANDLE
If n >= m Then
ProgressBar.Hide
Else
If ProgressBar.Visible = False Then ProgressBar.Show
ProgressBar![BoxProgress].Caption = IIf(DisplayText = "", Round(((n / m) * 10000) / 100) & "%", DisplayText)
ProgressBar![BoxProgress].Width = (n / m) * 468
DoEvents
End If
Exit Sub
ERR_HANDLE:
Err.Clear
ProgressBar.Hide
End Sub
Use it in your code like this:
Sub test()
Dim x As Long
For x = 1 To 100
UpdateProgressBar x, 100
Next x
End Sub
You'll need to call the procedure every time you want the progress bar to update.
The variables:
m represents the maximum number the bar will reach and n represents the current value to display.

deactivate Excel VBA userform

I am having some macro in Excel vba and in that I am performing some functions on the excel sheets which takes around 30 seconds to complete. So I want to show a user form with a progress bar during that span of time.
I tried using userform.show in very start of the function and userform.hide at the end but I found that No action can be performed in background.
So just want to know if there is any turn around to let the processing be done in the background while the form is being displayed.
Many thanks :)
Private Sub CommandButton1_Click()
'--------------Initialize the global variables----------------
UserForm1.Show
nameOfSheet2 = "Resource Level view"
nameOfSheet3 = "Billable Hours"
nameOfSheet4 = "Utilization"
'-------------------------------------------------------------
Dim lastRow, projectTime, nonProjectTime, leaveAndOther
Dim loopCounter, resourceCounter
lastRow = 0
projectTime = 0
nonProjectTime = 0
leaveAndOther = 0
resourceCounter = 2
Set workbook1 = Workbooks.Open(File1.Value)
Sheet3Creation
Sheet2Creation
Sheet4Creation
UserForm1.Hide
End Sub
The usage of Progress Bar is to show the progress of currently running code. And I wouldn't know if anyone want to do anything with the sheet while the code is running...
Anyway if you want to interact with the sheet while Form is displaying you may try to add the following code:
UserForm.Show vbvModeless
And to update a Modeless form you must add DoEvents within your subroutine.
When you want to close the form at the end, do this:
UserForm.Unload
Here is what I would do:
Click a button to run your macro
Private Sub Button1_Click()
Call userform.show vbMmodeless
End Sub
Private Sub UserForm_activate()
Call Main '-- your macro name
End Sub
Sub Main()
'-- your code
DoEvents '-- to update the form *** important
useroform.Unload
End Sub
After OP showed his code:
Why do we need a progress bar?
When macros take a long time to run, people get nervous. Did it crash? How much longer will it take? Do I have time to run to the bathroom? Relax...
In your case I do not really see that you are using any sort of heaving codes running at the background. So adding a progress bar could make your code slow as to update it, you may be calling an extra loop... check this reference article if you really want to have the progress bar :),
You can also use Application.StatusBar to display a message.
The other is to use Timer or a littel bit more technical way would be to wrap system timer ticks and refresh/update form accordingly. In VBA Excel we don't get that lucky as for C# or VB..
VBA Macro On Timer style to run code every set number of seconds, i.e. 120 seconds.
How do I show a running clock in Excel?
How do you test running time of VBA code?

VBA Excel Button resizes after clicking on it (Command Button)

How can I stop a button from resizing? Each time I click on the button, either the size of the button or the font size changes.
Note: I cannot lock my sheet as my Macro will write into the sheet.
Autosize is turned off. I run Excel 2007 on Windows 7 (64 Bit).
I use the following for ListBoxes. Same principle for buttons; adapt as appropriate.
Private Sub myButton_Click()
Dim lb As MSForms.ListBox
Set lb = Sheet1.myListBox
Dim oldSize As ListBoxSizeType
oldSize = GetListBoxSize(lb)
' Do stuff that makes listbox misbehave and change size.
' Now restore the original size:
SetListBoxSize lb, oldSize
End Sub
This uses the following type and procedures:
Type ListBoxSizeType
height As Single
width As Single
End Type
Function GetListBoxSize(lb As MSForms.ListBox) As ListBoxSizeType
GetListBoxSize.height = lb.height
GetListBoxSize.width = lb.width
End Function
Sub SetListBoxSize(lb As MSForms.ListBox, lbs As ListBoxSizeType)
lb.height = lbs.height
lb.width = lbs.width
End Sub
I added some code to the end of the onClick thus:
CommandButton1.Width = 150
CommandButton1.Height = 33
CommandButton1.Font.Size = 11
Seems to work.
I got the issue a slightly different way. By opening the workbook on my primary laptop display, then moving it to my big monitor. Same root cause I would assume.
Seen this issue in Excel 2007, 2010 and 2013
This code prevents the issue from manifesting. Code needs to run every time a active X object is activated.
Sub Shared_ObjectReset()
Dim MyShapes As OLEObjects
Dim ObjectSelected As OLEObject
Dim ObjectSelected_Height As Double
Dim ObjectSelected_Top As Double
Dim ObjectSelected_Left As Double
Dim ObjectSelected_Width As Double
Dim ObjectSelected_FontSize As Single
ActiveWindow.Zoom = 100
'OLE Programmatic Identifiers for Commandbuttons = Forms.CommandButton.1
Set MyShapes = ActiveSheet.OLEObjects
For Each ObjectSelected In MyShapes
'Remove this line if fixing active object other than buttons
If ObjectSelected.progID = "Forms.CommandButton.1" Then
ObjectSelected_Height = ObjectSelected.Height
ObjectSelected_Top = ObjectSelected.Top
ObjectSelected_Left = ObjectSelected.Left
ObjectSelected_Width = ObjectSelected.Width
ObjectSelected_FontSize = ObjectSelected.Object.FontSize
ObjectSelected.Placement = 3
ObjectSelected.Height = ObjectSelected_Height + 1
ObjectSelected.Top = ObjectSelected_Top + 1
ObjectSelected.Left = ObjectSelected_Left + 1
ObjectSelected.Width = ObjectSelected_Width + 1
ObjectSelected.Object.FontSize = ObjectSelected_FontSize + 1
ObjectSelected.Height = ObjectSelected_Height
ObjectSelected.Top = ObjectSelected_Top
ObjectSelected.Left = ObjectSelected_Left
ObjectSelected.Width = ObjectSelected_Width
ObjectSelected.Object.FontSize = ObjectSelected_FontSize
End If
Next
End Sub
(Excel 2003)
It seems to me there are two different issues:
- resizing of text of ONE button when clicking on it(though not always, don't know why), and
- changing the size of ALL buttons, when opening the workbook on a display with a different resolution (which subsist even when back on the initial display).
As for the individual resizing issue: I found that it is sufficient to modify one dimension of the button to "rejuvenate" it.
Such as :
myButton.Height = myButton.Height + 1
myButton.Height = myButton.Height - 1
You can put it in each button's clicking sub ("myButton_Click"), or implement it
a custom Classe for the "onClick" event.
I experienced the same problem with ActiveX buttons and spins in Excel resizing and moving. This was a shared spreadsheet used on several different PC's laptops and screens. As it was shared I couldn't use macros to automatically reposition and resize in code.
In the end after searching for a solution and trying every possible setting of buttons. I found that grouping the buttons solved the problem immediately. The controls, buttons, spinners all stay in place. I've tested this for a week and no problems. Just select the controls, right click and group - worked like magic.
Use a Forms button rather than an ActiveX one, ActiveX controls randomly misbehave themselves on sheets
Do you have a selection command in the buttons macro?
Shortly after I renamed some cells in a worksheet including one that the toggle button selects after its toggle function, the font size shrunk. I fixed this by making sure Range("...").Select included the new cell name, not the coordinates.
It happens when the screen resolution / settings change after Excel has been open.
For example:
Open a workbook that has a button on it
Log in with Remote Desktop from a computer with different screen size
Click on the button => the button size will change
The only solution I found is to close Excel and reopen it with the new screen settings. All instances of Excel must be closed, including any invisible instance executed by other processes without interface must be killed.
Old issue, but still seems to be an issue for those of us stuck on Excel 2007. Was having same issue on ActiveX Listbox Object and would expand its size on each re-calculate. The LinkCells property was looking to a dynamic (offset) range for its values. Restructuring so that it was looking to a normal range fixed my issue.
I had this problem using Excel 2013. Everything for working fine for a long time and all of sudden, when I clicked on the button (ActiveX), it got bigger and the font got smaller at the same time.
Without saving the file, I restarted my computer and open the same Excel file again and everything is fine again.
Mine resized after printing and changing the zoom redrew the screen and fixed it
ActiveWindow.Zoom = 100
ActiveWindow.Zoom = 75
Found the same issue with Excel 2016 - was able to correct by changing the height of the control button, changing it back, then selecting a cell on the sheet. Just resizing did not work consistently. Example below for a command button (cmdBALSCHED)
Public Sub cmdBALSCHED_Click()
Sheet3.cmdBALSCHED.Height = 21
Sheet3.cmdBALSCHED.Height = 20
Sheet3.Range("D4").Select
This will reset the height back to 20 and the button font back to as found.
After some frustrated fiddling, The following code helped me work around this Excel/VBA bug.
Two key things to note that may help:
Although others have recommended changing the size, and then immediately changing it back, notice that this code avoids changing it more than once on single toggle state change. If the value changes twice during one event state change (particularly if the second value is the same at the initial value), the alternate width and height properties may not ever be applied to the control, which will not reset the control width and height as it needs to be to prevent the width and height value from decreasing.
I used hard-coded values for the width and height. This is not ideal, but I found this was the only way to prevent the control from shrinking after being clicked several times.
Private Sub ToggleButton1_Click()
'Note: initial height is 133.8 and initial width was 41.4
If ToggleButton1.Value = True Then
' [Code that I want to run when user clicks control and toggle state is true (not related to this issue)]
'When toggle value is true, simply change the width and height values to a specific value other than their initial values.
ToggleButton1.Height = 40.4
ToggleButton1.Width = 132.8
Else
' [Code that I want to run when user clicks control and toggle state false (not related to this issue)]
'When toggle value is false adjust to an alternate width and height values.
'These can be the same as the initial values, as long as they are in a separate conditional statement.
ToggleButton1.Height = 41.4
ToggleButton1.Width = 133.8
End If
End Sub
For a control that does not toggle, you may be able to use an iterator variable or some other method to ensure that the width and height properties alternate between two similar sets of values, which would produce an effect similar the toggle state changes that I used in this case.

Can't close userform

Let me set up the environment.
This is VBA code running in Excel.
I have a userform that contains a msflexgrid. This flexgrid shows a list of customers and the customer', salesperson, csr, mfg rep, and territories, assignments. When you click in a column, let's say under the Territory column, another userform opens to show a list of Territories. You then click on the territory of your choice, the userform disappears and the new territory takes the place of the old territory.
This all works great until you click on the territory of your choice the 'Territory' userform does not disappear (it flickers) and the new territory does not transfer the underlying userform.
I should mention that when I'm stepping through the code it works great.
I'm assuming it has something do to with the flexgrid as all the other userform (that don't have flexgrids) that open userform work just fine.
Following is the some code sample:
** Click event from flexgrid that shows Territory userform and assignment of new territory when territory userform is closed.
Private Sub FlexGrid_Customers_Click()
With FlexGrid_Customers
Select Case .Col
Case 0
Case 2
Case 4
Case 6
UserForm_Territories.Show
Case Else
End Select
If Len(Trim(Misc1)) > 0 Then
.TextMatrix(.Row, .Col) = Trim(Misc1)
.TextMatrix(.Row, .Col + 1) = Trim(Misc2)
End If
End With
End Sub
** The following Subs are used in the Territory userform
Private Sub UserForm_Activate()
Misc1 = ""
Misc2 = ""
ListBox_Territory.Clear
Module_Get.Territories
End Sub
Private Sub UserForm_Terminate()
Set UserForm_Territories = Nothing
End Sub
Private Sub ListBox_Territory_Click()
With ListBox_Territory
Misc1 = Trim(.List(.ListIndex, 0))
Misc2 = Trim(.List(.ListIndex, 1))
End With
Hide
UserForm_Terminate
End Sub
I know this a long winded explanation but I'm a fairly decent VBA programmer and this has me stumped.
Any help would be greatly appreciated.
I'm not going to say what you're doing is wrong (in that it won't ever work), but it scares the heck out of me. This is not the way I'd deal with forms.
Firstly, you're using UserForm_Territories (the class/form name) to refer to an implicitly-created instance of the form. This is something I've always avoided doing. I would always create an instance of a form explicitly, so instead of:
UserForm_Territories.Show
I would do:
Dim oTerritoriesForm As UserForm_Territories
Set oTerritoriesForm = New UserForm_Territories
oTerritoriesForm.Show vbModal
' get the values from the form here
Unload oTerritoriesForm
Next, and much more worryingly, you're subverting the UserForm_Terminate behaviour by calling it explicitly. Why you're doing this I can't imagine, unless you thought that it would work around your stated problem. My advice: don't do that.
Worse, you're attempting to assign to the implicitly-created instance of the form within that Terminate method. You shouldn't be doing that, either. I'm surprised that even compiles.
It seems like you're trying to force the implicitly-created instance of the form to mimic an explicitly-created one. In which case, create it explicitly, as shown above.

Resources