Vba excel убрать заливку ячейки

Обновлено: 07.07.2024

Иногда при разработке интерфейсов программы с помощью форм пользователя(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;

Вариант 2
Но порой надо не просто запретить закрывать форму - но и для эстетики убрать заголовок с крестиком вообще - чтобы не смущал пользователя. Здесь чуть посложнее - придется применить функции API. Код надо будет помещать уже на инициализацию формы(событие Initialize), а не на закрытие(QueryClose). Следующий код необходимо будет поместить в самое начало модуля той формы, меню которой требуется убрать(первой строкой или сразу после строк деклараций, таких как Option Explicit, Option Base, Option Compare Text):

Это константы и функции API, которые и будут делать основную работу по удалению меню. Теперь останется на событие инициализации формы применить все эти функции:

Private Sub UserForm_Initialize() Dim ihWnd, hStyle 'ищем окно формы среди всех открытых окон If Val(Application.Version) < 9 Then ihWnd = FindWindow("ThunderXFrame", Me.Caption) 'для Excel 97 Else ihWnd = FindWindow("ThunderDFrame", Me.Caption) 'для Excel 2000 и выше End If 'получаем информацию о найденном окне(стили и т.д.) hStyle = GetWindowLong(ihWnd, GWL_STYLE) 'назначаем переменной новый стиль для окна формы hStyle = hStyle And Not WS_CAPTION And Not WS_BORDER 'изменяем вид окна: убираем меню(заголовок) и рамку SetWindowLong ihWnd, GWL_STYLE, hStyle SetWindowLong ihWnd, GWL_EXSTYLE, 0 'перерисовываем форму, точнее строку меню(заголовка) DrawMenuBar ihWnd 'меняем размер формы, т.к. сделали смещение элементов формы вверх на высоту заголовка Me.Height = Me.Height + GWL_EXSTYLE End Sub

Форма без заголовка

Я постарался кратко описать действия с формой в комментариях, поэтому не буду дублировать это еще и отдельным текстом.
После этого кода форма получается более эстетичного вида:

С такой формой у пользователя точно не возникнет желания закрыть форму как-то в обход наших желаний. В коммерческих разработках такой подход будет более правильным. Однако здесь тоже есть недостаток: т.к. строка меню убирается полностью, то форму невозможно переместить при помощи мыши. В каких-то случаях это может мешать, а в каких-то наоборот быть преимуществом. Так или иначе это следует учитывать.

С легкой руки моего старого друга и модератора нашего форума ЮрияМ дополняю статью еще одним кодом. Если на запуск формы применить такой код:

Private Sub UserForm_Initialize() Dim ihWnd, hStyle 'ищем окно формы среди всех открытых окон If Val(Application.Version) < 9 Then ihWnd = FindWindow("ThunderXFrame", Me.Caption) 'для Excel 97 Else ihWnd = FindWindow("ThunderDFrame", Me.Caption) 'для Excel 2000 и выше End If 'получаем информацию о найденном окне(стили и т.д.) hStyle = GetWindowLong(ihWnd, -16&) 'убираем кнопку крестика SetWindowLong ihWnd, -16&, hStyle And Not &H80000 End Sub

То заголовок будет и можно будет форму за него хватать и перемещать, но крестика на форме вообще не будет:

Для этого кода так(же как и для предыдущего) в модуле формы необходимо разместить приведенные выше функции API.

ВАЖНО: Применяя любой из подходов советую заранее продумать как форма будет вообще закрываться, в том числе в режиме отладки программы. Т.к. если просто вставить этот код, то сами же не сможете закрыть форму - только завершением выполнения кода через Run -Reset.

Начиная с Excel 2007 основным способом заливки диапазона или отдельной ячейки цветом (зарисовки, добавления, изменения фона) является использование свойства .Interior.Color объекта Range путем присваивания ему значения цвета в виде десятичного числа от 0 до 16777215 (всего 16777216 цветов).

Заливка ячейки цветом в VBA Excel

Пример кода 1:

Range ( "C12:D17" ) . Cells ( 4 ) . Interior . Color = 568569

Поместите пример кода в свой программный модуль и нажмите кнопку на панели инструментов «Run Sub» или на клавиатуре «F5», курсор должен быть внутри выполняемой программы. На активном листе Excel ячейки и диапазон, выбранные в коде, окрасятся в соответствующие цвета.

Есть один интересный нюанс: если присвоить свойству .Interior.Color отрицательное значение от -16777215 до -1, то цвет будет соответствовать значению, равному сумме максимального значения палитры (16777215) и присвоенного отрицательного значения. Например, заливка всех трех ячеек после выполнения следующего кода будет одинакова:

Cells ( 2 , 1 ) . Interior . Color = 16777215 + ( - 12207890 )

Проверено в Excel 2016.

Пример кода 2:

Использование предопределенных констант

В VBA Excel есть предопределенные константы часто используемых цветов для заливки ячеек:

Предопределенная константа Наименование цвета
vbBlack Черный
vbBlue Голубой
vbCyan Бирюзовый
vbGreen Зеленый
vbMagenta Пурпурный
vbRed Красный
vbWhite Белый
vbYellow Желтый
xlNone Нет заливки

Присваивается цвет ячейке предопределенной константой в VBA Excel точно так же, как и числовым значением:

Пример кода 3:

Цветовая модель RGB

Цветовая система RGB представляет собой комбинацию различных по интенсивности основных трех цветов: красного, зеленого и синего. Они могут принимать значения от 0 до 255. Если все значения равны 0 — это черный цвет, если все значения равны 255 — это белый цвет.

Выбрать цвет и узнать его значения RGB можно с помощью палитры Excel:

Палитра Excel

Чтобы можно было присвоить ячейке или диапазону цвет с помощью значений RGB, их необходимо перевести в десятичное число, обозначающее цвет. Для этого существует функция VBA Excel, которая так и называется — RGB.

Пример кода 4:

Очистка ячейки (диапазона) от заливки

Для очистки ячейки (диапазона) от заливки используется константа xlNone :

Свойство .Interior.ColorIndex объекта Range

Пример кода 5:

Просмотреть ограниченную палитру для заливки ячеек фоном можно, запустив в VBA Excel простейший макрос:

Пример кода 6:

Номера строк активного листа от 1 до 56 будут соответствовать индексу цвета, а ячейка в первом столбце будет залита соответствующим индексу фоном.

Готовую стандартную палитру из 56 цветов можете посмотреть здесь.

Содержание рубрики VBA Excel по тематическим разделам со ссылками на все статьи.

59 комментариев для “VBA Excel. Цвет ячейки (заливка, фон)”

Спасибо, наконец то разобрался во всех перипетиях заливки и цвета шрифта.

Пожалуйста, Виктор. Очень рад, что статья пригодилась.

как проверить наличие фона?

Подскажите пожалуйста, как можно посчитать количество залитых определенным цветом ячеек в таблице?

Привет, Иван!
Посчитать ячейки с одинаковым фоном можно с помощью цикла.
Для реализации этого примера сначала выбираем в таблице ячейку с нужным цветом заливки. Затем запускаем код, который определяет цветовой индекс фона активной ячейки, диапазон таблицы вокруг нее и общее количество ячеек с такой заливкой в таблице.

Каким образом можно использовать не в процедуре, а именно в пользовательской функции VBA свойство .Interior.Color?
Скажем, проверять функцией значение какой-то ячейки и подкрашивать ячейку в зависимости от этого.

Фарин, пользовательская функция VBA предназначена только для возврата вычисленного значения в ячейку, в которой она расположена. Она не позволяет внутри себя менять формат своей ячейки, а также значения и форматы других ячеек.

Однако, с помощью пользовательской функции VBA можно вывести значения свойств ячейки, в которой она размещена:

В сети есть эксперименты по изменению значений других ячеек из пользовательской функции VBA, но они могут работать нестабильно и приводить к ошибкам.

Для подкрашивания ячейки в зависимости от ее значения используйте процедуру Sub или штатный инструмент Excel – условное форматирование.

а как можно закрасить только пустые ячейки ?

Евгений, спасибо за ссылку на интересный прием.

Евгений, день добрый.
Подскажите пожалуйста, как назначить ячейке цвет через значение RGB, которое в ней записано. Или цвет другой ячейки.

Привет, Александр!
Используйте функцию InStr, чтобы найти положение разделителей, а дальше функции Left и Mid. Смотрите пример с пробелом в качестве разделителя:

Range ( "A1" ) . Interior . Color = RGB ( Left ( Range ( "A1" ) , n1 - 1 ) , _ Mid ( Range ( "A1" ) , n1 + 1 , n2 - n1 - 1 ) , Mid ( Range ( "A1" ) , n2 + 1 ) )

Или еще проще с помощью функции Split:

Range ( "A1" ) . Interior . Color = RGB ( a ( 0 ) , a ( 1 ) , a ( 2 ) )

Добрый день!
подскажите, пожалуйста, как можно выводить из таблицы (150 столбцов х 150 строк) адрес ячеек (списком), если они имеют заливку определенного цвета.
Заранее спасибо!

spisok = spisok & vbNewLine & Cells ( i1 , i2 ) . Address If Cells ( i , "D" ) . Interior . Color = c Then Cells ( i , "E" ) = "Да"

Евгений, спасибо за подсказку.
Все получилось

добрый день! подскажите, пожалуйста, как сделать, чтобы результаты выводились на отдельный лист ?
заранее спасибо!

Sheets ( "Лист2" ) . Cells ( n , 1 ) = "Список адресов ячеек с цветом " & tsvet Sheets ( "Лист2" ) . Cells ( n , 1 ) = Cells ( i1 , i2 ) . Address

Добрый день, Алексей!
Примените условное форматирование:

Многие при работе с таблицами любят их окрашивать в различные цвета по "категориям": красный - прогул; синий - больничный; желтый - коммандировка и т.д. и т.п. Это вполне может быть визуально наглядно и красиво, но в последствии хочется по подобной боевой раскраске осуществить с ячейками какие-то иные операции, чем просто полюбоваться. Например: подсчитать количество ячеек определенного цвета, отфильтровать по цвету и т.п. Сегодня я хочу рассказать, как можно защитить ячейки в зависимости от цвета заливки, шрифта. Один из случаев, когда закраска ячеек может быть оправдана - можно каким-то определенным цветом отметить ячейки с формулами, а потом их защитить кодом ниже.
В принципе это можно сделать руками: выделить все ячейки нужного цвета, правая кнопка мыши -Формат ячеек -Защита -Защищаемая ячейка. После чего защитить лист. Подробнее можно прочитать в статье Как разрешить изменять только выбранные ячейки? и в статье Защита листов и ячеек в MS Excel. Но если ячеек много, да еще они разбросаны по листу, то такой метод довольно утомителен. Однако это очень просто сделать при помощи кода ниже:

Как использовать код в своей книге: копируем код выше, в нужной книге переходим в редактор VBA( Alt + F11 ) -Insert -Module. В появившееся окно вставляем скопированный код.
Теперь выделяем все ячейки на листе, среди которых есть те, которые надо защитить -нажимаем сочетание клавиш Alt + F8 и выбираем из списка PrCellsByInterior , если надо защищать ячейки на основании цвета заливки или PrCellsByFont , если защищать надо в зависимости от цвета шрифта.
Защищать ячейки с конкретным цветом получилось, но что делать, если окрашены как раз те ячейки, защищать которые не надо? Да еще и ячейки окрашены разными цветами? Все просто: для защиты выбираем весь диапазон значимых ячеек, а в качестве ячейки-образца с заливкой указываем любую ячейку без заливки. Вот и все. Все ячейки без заливки будут защищены, а с заливкой - разрешены для ввода.

Tips_Macro_LockCellByColor.xls (48,0 KiB, 1 327 скачиваний)

Что важно знать: ячейки, цвет заливки или шрифта которых установлен при помощи условного форматирования, не будут защищены корректно. В этом случае код увидит реальную заливку, а не ту, что отражается.

Если вы когда-нибудь использовали защиту ячеек на листе (вкладка Рецензирование - Защитить лист или в старых версиях Excel - меню Сервис - Защита - Защитить лист), то, возможно, сталкивались с этой проблемой. Как известно, будет данная конкретная ячейка на листе защищена от изменений после включения защиты листа, или нет - определяется галочкой Защищаемая ячейка (Locked) в диалоговом окне Формат ячейки (Format Cells) на вкладке Защита (Protection) :

highlight-unprotected1.jpg

В случае применения защиты листа к большой и сложной таблице или экранной форме, где должно быть много областей ввода, не всегда понятно - у каких ячеек на листе эта галочка уже выключена, а у каких еще осталась включена? Опубликованные ниже макросы как раз и позволяют включить/выключить подсветку цветом для незащищенных ячеек на текущем листе, чтобы их было наглядно видно.

Для добавления этих макросов в текущую книгу:

  • нажмите сочетание клавиш ALT+F11, чтобы открыть редактор макросов Visual Basic
  • вставьте новый пустой модуль в книгу, используя команду меню Insert - Module
  • скопируйте и вставьте туда код приведенных ниже макросов

Как легко догадаться, первый из этих двух макросов включает подсветку красным для незащищенных ячеек, а второй - выключает ее, восстанавливая исходный цвет заливки. Запустить эти макросы можно, нажав сочетание клавиш ALT+F8 или воспользовавшись кнопкой Макросы (Macros) на вкладке Разработчик (Developer) .

Работа макроса на примере экранной формы выглядит примерно так:

highlight-unprotected2.jpg

И не надо ломать голову и проверять - где ты снял защиту с ячеек, а где она осталась.

Читайте также: