Vba excel userform убрать кнопку закрыть
While working on a project recently, I thought about hiding the [X] close button which is at the top of the VBA UserForm. I managed to identify three options for achieving this. If you are thinking about the same thing, then this post will give you the answers you’re looking for.
To hide, or not to hide, that is the question
Before we start looking at the three options, I want to cover the most critical question of all: should we hide a UserForm’s close button?
The close button is a recognized part of the Windows environment. Pretty much every application uses a cross at the top right corner to close a window. Therefore, based on their experience of other applications, all users already know what the cross should do. It doesn’t matter which country the user is in or what language they speak, it is a universally understood icon to close a window. Therefore you should be asking yourself why you want to hide the close button at all. With this in mind, I would say that generally the close button should not be hidden or disabled.
However, there are some circumstances where we may want to break this general rule. One such example is a progress bar. If the user closes a progress bar, they may not know when the macro has finished running, or how long is left. Therefore, it might be useful to hide the close button in this scenario.
By default, the close button will unload a UserForm, but it can be adapted to have a custom close procedure. As we can control this functionality, it may be better to control it rather than hide or disable it.
About Windows API codes
- They will not work on a Mac, only on Windows. So if designing for Windows and Mac, you will need to identify which platform is used and adapt the code accordingly.
- The code sections marked “Include this code at the top of the module” must be included before any other Subs or Functions are declared, and must be below the Option Explicit statement (if you have one).
3 Options for disabling/hiding a UserForm close button
If you are still intent on hiding or disabling the close button, then read on to understand the three options.
(1) The unobvious disable with a message box
This first option is the worst of the three. It does not disable or hide the close button, but prevents the user from using it to close the window.
Even though it is the worst option, it is the easiest to use and understand. The following code can be used within the UserForm’s QueryClose event.
If the user clicks on the close button, the following message box will appear.
This is effectively disabling the close button, as the UserForm will not close. But from a user’s perspective, this solution is just frustrating. Why would there be a button which doesn’t do anything apart from telling us it doesn’t do anything? This is why it’s not a great option.
(2) Disable the close button (Windows API)
The second option will disable the close button; it will be visible, but will be greyed-out and cannot be clicked.
The first image below shows the close button when it is enabled; the second image shows the close button when it is disabled.
From a user’s perspective, this option is better than the first, but still not great. What is the point of a button which cannot be clicked; it just creates confusion?
Basic code
The code below should be copied into a new standard module and must be included before any other code, but after the Option Explicit statement (if there is one).
- frm – a reference to the UserForm for which the close button should be enabled/disabled
- show – a True or False value where True = enable the close button and False = disable the close button
Disable the close button on UserForm initialize
If inserted into the UserForm’s initialize event it will disable the button when the form is created.
Disable or enable the close button at any point
The close button can be enabled or disabled as and when required with the following macros:
Disable the close button
Enable the close button
(3) Hide system menu (Windows API)
The third option is to hide the system menu section of the window. The System menu section includes the maximize, minimize and close buttons. The screenshot below shows the close button is not visible.
By hiding the system menu section, we are also removing the ability to see the minimize and maximize buttons. By default a UserForm does not have these buttons visible (separate Windows API calls are required to enable this), therefore this is probably a good option in 99.9% of circumstances.
Basic Code
The code below should be copied into a new standard module and must be included before any other code, but after the Option Explicit statement (if there is one).
- frm – a reference to the UserForm for which the close button should be shown/hidden
- show – a True or False value where True = show the system menu and False = hide the system menu
Hide the system menu buttons on UserForm initialize
If inserted into the UserForm’s initialize event it will disable the button when the form is created.
Show or hide the close button at any point
The close button can be shown or hidden as and when required using the following macros.
Hide the close button
Show the close button
Download the example file
Want to see these examples working? Then download the example file.
Get our FREE VBA eBook of the 30 most useful Excel VBA macros.
Automate Excel so that you can save time and stop doing the jobs a trained monkey could do.
Don’t forget:
If you’ve found this post useful, or if you have a better approach, then please leave a comment below.
Do you need help adapting this to your needs?
I’m guessing the examples in this post didn’t exactly meet your situation. We all use Excel differently, so it’s impossible to write a post that will meet everybody’s needs. By taking the time to understand the techniques and principles in this post (and elsewhere on this site) you should be able to adapt it to your needs.
- Read other blogs, or watch YouTube videos on the same topic. You will benefit much more by discovering your own solutions.
- Ask the ‘Excel Ninja’ in your office. It’s amazing what things other people know.
- Ask a question in a forum like Mr Excel, or the Microsoft Answers Community. Remember, the people on these forums are generally giving their time for free. So take care to craft your question, make sure it’s clear and concise. List all the things you’ve tried, and provide screenshots, code segments and example workbooks.
- Use Excel Rescue, who are my consultancy partner. They help by providing solutions to smaller Excel problems.
What next?
Don’t go yet, there is plenty more to learn on Excel Off The Grid. Check out the latest posts:
Иногда при разработке интерфейсов программы с помощью форм пользователя(UserForm) бывает необходимо запретить закрытие формы крестиком. Причин много: например на форме много элементов выбора и пользователь не должен просто закрывать форму крестиком, не выбрав что-то конкретное. Или может форма должна висеть постоянно на листе до тех пор, пока программа не сделает все необходимые действия и т.д.
Варианта два
Вариант 1
Можно просто запретить закрывать форму. Это значит, что после нажатия на крестик ничего не произойдет. Для этого надо перейти в модуль формы и на событие QueryClose прописать такой код:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode = 0 Then 'CloseMode = 0 - попытка закрыть форму крестиком Cancel = True 'даем VBA понять, что надо отменить закрытие формы End If End Sub
данный код не даст закрыть форму нажатием на крестик, но если форма выгружается другими методами(вроде Unload) - форма закроется. За это отвечает параметр CloseMode, который может принимать следующие значения:
- 0 или vbFormControlMenu - попытка закрытия формы пользователем через элемент управления крестик
- 1 или vbFormCode - закрытие формы через выгрузку методом Unload
- 2 или vbAppWindows - завершение сеанса Windows(в кодах VBA практически не используется)
- 3 или vbAppTaskManager - завершение программы через диспетчер задач(в кодах VBA практически не используется)
Можно(скорее даже нужно!) дать понять пользователю, что он должен сделать что-то конкретное для закрытия формы и что крестиком это сделать нельзя, чтобы он не нервничал и не пытался завершить работу Excel через Clt+Alt+Delete;
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode = 0 Then 'CloseMode = 0 - попытка закрыть форму крестиком MsgBox "Вы должны нажать на кнопку в центре, чтобы закрыть форму", vbInformation, "www.excel-vba.ru" Cancel = True 'даем VBA понять, что надо отменить закрытие формы End If End Sub
Вариант 2
Но порой надо не просто запретить закрывать форму - но и для эстетики убрать заголовок с крестиком вообще - чтобы не смущал пользователя. Здесь чуть посложнее - придется применить функции API. Код надо будет помещать уже на инициализацию формы(событие Initialize), а не на закрытие(QueryClose). Следующий код необходимо будет поместить в самое начало модуля той формы, меню которой требуется убрать(первой строкой или сразу после строк деклараций, таких как Option Explicit, Option Base, Option Compare Text):
Это константы и функции API, которые и будут делать основную работу по удалению меню. Теперь останется на событие инициализации формы применить все эти функции:
Я постарался кратко описать действия с формой в комментариях, поэтому не буду дублировать это еще и отдельным текстом.
После этого кода форма получается более эстетичного вида:
С такой формой у пользователя точно не возникнет желания закрыть форму как-то в обход наших желаний. В коммерческих разработках такой подход будет более правильным. Однако здесь тоже есть недостаток: т.к. строка меню убирается полностью, то форму невозможно переместить при помощи мыши. В каких-то случаях это может мешать, а в каких-то наоборот быть преимуществом. Так или иначе это следует учитывать.
С легкой руки моего старого друга и модератора нашего форума ЮрияМ дополняю статью еще одним кодом. Если на запуск формы применить такой код:
То заголовок будет и можно будет форму за него хватать и перемещать, но крестика на форме вообще не будет:
Для этого кода так(же как и для предыдущего) в модуле формы необходимо разместить приведенные выше функции API.
ВАЖНО: Применяя любой из подходов советую заранее продумать как форма будет вообще закрываться, в том числе в режиме отладки программы. Т.к. если просто вставить этот код, то сами же не сможете закрыть форму - только завершением выполнения кода через Run -Reset.
Я создал форму пользователя, чтобы показать индикатор выполнения, когда макрос все еще импортирует листы
проблема в том, что пользователь может нажать красный [X] кнопка, которая закроет и прервет обработку.
есть ли способ скрыть это красная кнопка doom так что потенциальные пользователи не имеют каких-либо запутанных кнопок, чтобы нажать во время его запуска.
Я пробовал этот
и я использовал это в userform_initialize
этот код был взят из здесь. Я не знаю, что я делаю неправильно, и я уже удалил комментарии. Это самый простой код, который я нашел, поэтому я хотел бы интегрировать его в свою пользовательскую форму. Любая помощь приветствуется.
ниже-это рутина, что можно назвать такой:
или из вашей формы:
вот код, который вам понадобится:
вы можете решить это из следующих фрагментов:
выберите В строке меню выберите View | Code Где курсор мигает, введите следующий код:
в строке меню выберите View | Object , чтобы вернуться к UserForm.
чтобы пользователи могли закрыть форму, нажав клавишу Esc:
выберите кнопку cmdClose В окне Свойства измените Cancel свойство True
чтобы запретить пользователям закрывать форму, нажмите кнопку X
когда UserForm открывается, есть X вверху справа. В дополнение к кнопке закрыть форму, люди смогут закрыть форму с помощью X. Если вы хотите предотвратить это, выполните следующие действия.
щелкните правой кнопкой мыши на пустой части UserForm Выберите View | Code В раскрывающемся списке процедура в правом верхнем углу выберите QueryClose
где курсор мигает, вставьте выделенный код из следующего примера
Я нашел вклад Джастина Дэвиса довольно полезным: если вы замените строку
пользовательская форма скрыта от пользователя, но все еще активна, пока она не выгружена.
это улучшение вышеуказанного ответа @Peter Albert
- вызовы Windows API теперь Office x64 safe
- FindWindow вызов был улучшен, чтобы найти только Excel UserForms. Функция в исходном ответе ищет каждый класс окна (например, окна Проводника и окна другой программы). Поэтому может случиться, что кнопка [x] других программ или окон Проводника была удалена, когда их имя было тем же именем, что и имя Пользовательская форма.
ThunderDFrame?
UserForms в Excel на самом деле относятся к классу Windows ThunderDFrame , который является классом для всех UserFroms в приложениях Microsoft Office после 2002. До этого это было ThunderXFrame .
спросите пользователя, хотят ли они закрыть форму - и потерять изменения (скажем). На основе идей от Justin & Peter.
Edit: на самом деле я понимаю, что это немного не по теме, поскольку OP хотел удалить опцию X, но все же я нахожу это удобным для интерактивных форм.
Я знаю, что это старый вопрос, но для типа пользовательской формы OP цитируется, вам не нужно удалять, скрывать или отключать кнопку закрытия. Существует гораздо более простой способ;)
для любой пользовательской формы, которая не имеет каких-либо элементов, с которыми пользователь взаимодействует (кнопки и т. д.), И которая закроется, когда она закончит свое назначение, просто отключить форму нормально.
для отключить пользователя : В свойствах пользовательской формы против Enabled установлено значение False. Этот пользовательская форма будет отображаться, пока код не скажет ей скрыть. Пользователь не сможет ничего сделать с формой (не может закрыть, не может переместить и т. д.).
обратите внимание также, что если вы хотите, чтобы пользователь мог делать что-либо еще в главном окне, пока пользовательская форма все еще показывает, решает, устанавливаете ли вы ShowModal.
полезный способ отключить кнопку сделать следующее:
хотя это не избавиться кнопки, но нажатие на нее ничего не добьетесь.
проверьте следующие ссылки. У меня получилось. Он удаляет заголовок из пользовательской формы.
I created a userform to show a progress bar when the macro is still importing sheets
The problem is the user can press the red [X] button that will close and interrupt the processing done.
Is there a way to hide this red button of doom so that potential users don't have any confusing buttons to click while it runs.
I have tried this
and I used this on userform_initialize
I am getting this error message
this code was taken from here. I don't know what I'm doing wrong and I already removed the comments. This is the simplest code that I found so I would like to integrate it to my userform. Any help is appreciated.
Could you clarify and change the word 'disable' to 'hide and disable' if this is what you intend to do? Disabling the functionality is relatively simple. Hiding it appears to not be.
To fix the problem you show in the screenshot: move all the API declaration to the top of the module!
6 Answers 6
Below is a routine that you can call like this:
or from within your form:
Here's the code you'll need:
@amadeus: what do you need the DrawMenuBar for? And which declaration is messed up? (I don't have a 64bit Excel at hand to test. ) thanks!
If you call subRemoveCloseButton() when the form is already rendered (i.e. not from within Userform_Initialize()), then the Menu does not change. In that case you have to call DrawMenuBar() to rerender. As for the 64bit support, all Long values representing pointers must be replaced by LongPtr. For example FindWindow() does return a LongPtr, not a Long. Same for the hwnd parameters.
ATTENTION: With this call of FindWindow(vbNullString, frm.Caption) it may happen, that if your UserForm has the same caption as any other program's window, that its [x] button is being removed instead of the UserForm's [x] button. I posted an improved function below binding FindWindow to UserForms and including x64 safe API calls.
You can work it out from the following snippets:
Select the cmdClose button On the Menu bar, choose View | Code Where the cursor is flashing, enter the following code:
On the Menu bar, choose View | Object , to return to the UserForm.
To allow users to close the form by pressing the Esc key:
Select the cmdClose button In the Properties window, change the Cancel property to True
To prevent users from closing the form by clicking the X button
When the UserForm is opened, there is an X at the top right. In addition to using the Close Form button, people will be able to close the form by using the X. If you want to prevent that, follow these steps.
Right-click on an empty part of the UserForm Choose View | Code From the Procedure dropdown, at the top right, choose QueryClose
Where the cursor is flashing, paste the highlighted code from the following sample
On the Menu bar, choose View | Object , to return to the UserForm. Now, if someone clicks the X in the UserForm, they'll see your message.
VBA UserForms are a key tool for managing user interactions. When a UserForm is well designed, it guides the user through the options and settings without any help file or guidance. From my own UserForm development, I know one of the most overlooked aspects is the closure of the UserForm itself.
This post will cover some of the key considerations to ensure the closure process achieves the desired outcome.
Basic VBA code
To start with, let’s look at the basic VBA code for opening and closing UserForms. In this post, the UserForm is called myUserForm, and it looks like this.
The button names are cmdHide and cmdUnload, and the text box is called txtTextBox.
Display a UserForm
The code to display a UserForm is usually stored outside of the UserForm itself, in a standard module. The following code will show the UserForm.
Hide a UserForm
To hide a UserForm using a button, the code can be contained with the UserForm itself, or in a separate module.
The code below shows an example where the code is contained within the UserForm. Me is used to reference the UserForm object.
Where the code is contained within another module, we must refer to the name of the UserForm, as shown by the code below.
Unload a UserForm
Another way to close a UserForm is to unload it. Just like the examples above, the code can be referenced from within or outside the UserForm code module.
Referenced from within the UserForm module:
Referenced from outside the UserForm module:
Close button
The simplest option to close a UserForm is the standard close button. It is convenient as it right there at the top of the window. By default, It doesn’t require any code to work as it’s part of the Windows framework.
Be aware that the close button will use the unload method when closing the UserForm.
Assigning the Esc key
The Esc key is commonly used within interface design to close a window. We can use this on our UserForm too, though the option to apply the setting is in a strange place.
Select a button on the UserForm and set the Cancel property to True.
When the UserForm is displayed, pressing the Esc key will trigger the button you applied the Cancel property to. Therefore Cancel can be assigned to a button with hide or unload.
Hide vs Unload
As there is an option to hide or unload, which should you choose? Does it matter? YES, it definitely does matter.
The two options are different in their approach because they achieve slightly different things.
Unload
Unload will close the form completely; it will no longer exist in memory. It will be as if the initialize event has not triggered, so if we refer to any of the objects on the UserForm, they will have no value.
Hide makes a UserForm invisible, it’s still there, we just can’t see it. As it still exists, we can still reference the objects on the form to retrieve their values.
As an example, if there is text in a text box, we can still reference it after the form has closed. The code below will display a message box with the text from the UserForm after the form has been closed.
As the form remains open, it continues to hold the memory.
report this ad Preloading the UserForm
What if we want to reference an object on a UserForm before we display it? The initialize event has not executed and the form does not exist in memory. To get around this issue, we can use the load command to create the UserFrom, but not display it.
By using this method, the initialize event will trigger, but not the activate event. The activate event will trigger only once the UserForm is displayed.
To guarantee the UserForm is always in memory, load the form during the workbook open event.
How to close using the X button
By default, the [X] close button will unload the UserForm. Which is a problem if we want to hide it. But we can hijack the [X] button control to achieve the same as the hide command.
The UserForm has an event called QueryClose. Using this event, we can cancel the unload action, then hide the UserForm.
Once you’ve canceled the unload action, you could now refer to the elements on the UserForm, just like the normal hide.
How did the user close the form?
As there are multiple ways to close a UserForm, it may be useful to know which option the user selected. Did they click “OK” or “Cancel”? In this situation, it is easier to use a public variable. Assign the value to the variable as part of the close procedure.
The public variable can then be accessed by any module.
Get our FREE VBA eBook of the 30 most useful Excel VBA macros.
Automate Excel so that you can save time and stop doing the jobs a trained monkey could do.
Don’t forget:
If you’ve found this post useful, or if you have a better approach, then please leave a comment below.
Do you need help adapting this to your needs?
I’m guessing the examples in this post didn’t exactly meet your situation. We all use Excel differently, so it’s impossible to write a post that will meet everybody’s needs. By taking the time to understand the techniques and principles in this post (and elsewhere on this site) you should be able to adapt it to your needs.
- Read other blogs, or watch YouTube videos on the same topic. You will benefit much more by discovering your own solutions.
- Ask the ‘Excel Ninja’ in your office. It’s amazing what things other people know.
- Ask a question in a forum like Mr Excel, or the Microsoft Answers Community. Remember, the people on these forums are generally giving their time for free. So take care to craft your question, make sure it’s clear and concise. List all the things you’ve tried, and provide screenshots, code segments and example workbooks.
- Use Excel Rescue, who are my consultancy partner. They help by providing solutions to smaller Excel problems.
What next?
Don’t go yet, there is plenty more to learn on Excel Off The Grid. Check out the latest posts:
Читайте также: