Всем привет!
Вопреки сказанному в конце прошлого поста, решил второй пост писать про Excel, потому что на макросы для него спрос намного выше, судя по всему. Пример будет практически малополезный, но зато попроще.
Сразу договоримся вот о чем: у меня стоит Office 2016 на домашнем ноуте и 2019 на рабочем компьютере. Они почти не отличается интерфейсом. Я прошу разрешить мне не расписывать, где что нажимать в других версиях, чтобы не раздувать посты еще сильнее. Если у вас что-то не будет получаться, просто спросите в комментариях, и я вам помогу.
Посты я теперь буду называть так, как этот, чтобы было понятно, о чем он конкретно и какие темы VBA в нем разбираются.
Но сначала кое-что важное:
Материалы данного поста созданы непрофессиональным программистом.
Я не претендую на гордое звание преподавателя, коуча или сенсея.
Я буду показывать решения, которые просто будут работать.
Критика и советы горячо приветствуются.
При, по крайней мере, написании поста ни один настоящий программист не пострадал.
А теперь поехали!
1. Что такое VBA? Зачем писать на нем макросы и что нужно, чтобы они работали?
Об этом писал в первом посте. В вашего позволения, повторяться не буду.
2. Мне прислали книгу в Excel, где там макросы?
Если VBA установлен в ваш эксель, то все манипуляции с макросами нужно проводить во вкладке «Разработчик».
Если вы открыли Excel, а вкладки нет, ее нужно включить. Для этого нажмите A, C, вверх, B, вверх, B, A, вниз откройте настройки («Параметры» в самом низу, если нажать «Файл» сверху слева). Слева в списке выберите «Настроить ленту». У вас будет два списка с набором команд и вкладок. В правом найдите строчку «Разработчик» и включите напротив нее галочку, вот так:
Кстати, неплохо бы еще прогуляться в «Центр управления безопасностью», нажать кнопку «Параметры центра управления безопасностью…», затем выбрать «Настройки макросов» и выбрать подходящий вам пункт. У меня лично так:
Не хочу вас пугать, но буду на VBA можно написать и вредоносную программу, которая запустится сразу после открытия файла, поэтому включать все макросы по умолчанию стоит только на ваш страх и риск, если вы часто ими пользуетесь и вам сильно надоели всплывающие окошки с предупреждениями. Лично я на всякий случай выключаю поддержку макросов перед тем, как открыть файл, который мне кто-то малознакомый присылает. За пять лет проблем не было.
Итак, если вы все сделали правильно, у вас появится такая вкладка:
Кнопка с подписью «Visual Basic» откроет редактор проектов VBA, который почти такой же, как в прошлом посте про AutoCAD.
Через кнопку «Макросы» можно увидеть и запустить макросы, которые сейчас доступны и загружены в Excel.
Еще есть кнопка поменьше, «Запись макроса». Нажав на нее, можно сделать макрос без программирования. Можете попробовать сами, я объяснять подробно не буду, потому что лично мне кажется, что написанные таким образом макросы подходят только для имитации бурной деятельности разовых и крошечных задач. Нам эта кнопка пригодится чуть ниже для кое-чего другого.
3. Как написать свой макрос для Excel?
В редакторе проектов VBA вы увидите объекты листов, книги, а также можете добавлять свои модули и формы.
Опять-таки, пока я советую добавлять новые модули, а не писать их в книгах или листах. Со временем нам попадется ситуация, когда это будет необходимо. Если вообще будет.
В общем, добавляем модуль, чтобы потом писать туда код:
Наверное, вы уже заметили, что в отличие от AutoCAD, в Excel не нужно подгружать макросы в виде отдельных файлов .dvb, они сохраняются вместе с книгами. Это отчасти удобно, но есть и минус: чтобы запустить какой-то макрос, надо держать открытой книгу, в которой он сохранен. Или копировать его каждый раз в каждую новую книгу.
Решить такую проблему помогает специальная книга PERSONAL.xlsb, которая в скрытом режиме открывается автоматически вместе с самим Excel. В ней можно хранить макросы, и тогда они всегда будут доступны. На предыдущем изображении ее как раз видно в редакторе VBA.
У вас ее, скорее всего нет.
Чтобы она появилась, нужно три раза позвать Битлджуса сделать макрос через «Запись макроса». Нажимаете эту кнопку, потом обязательно в списке «Сохранить в» выбираете «Личная книга макросов», что-нибудь делаете (например, выделяете ячейку, пишете в нее что-нибдуь) и нажимаете «Остановить запись». Потом нажимаете кнопку «Остановить запись», она будет на месте кнопки «Запись макроса».
Если вы теперь откроете редактор VBA (нажав кнопку «Visual Basic»), то в списке проектов увидите книгу PERSONAL.xlsb, а в ней модуль с кодом того, что вы делали, пока записывали макрос. Советую удалить его, но я вам не командир.
Теперь мы можем писать туда свой код, и он будет работать во всех книгах, если мы его запустим через кнопку «Макросы».
Давайте прикинем задачу.
Например, мы владеем приютом для кошек, и мы отслеживаем вес наших подопечных. Все же любят котиков? В целях демонстрации на еженедельном собрании мы хотели бы эффектно и быстро подстветить красным цветом тех котеек, кому пора на диету. Представим данные в таком виде:
Пока давайте заранее решим, что максимальная снаряженная масса котиков – 5 кг. Тогда код будет такой:
Работает он так: выделяете какой-то диапазон ячеек (или одну), запускаете макрос. Те ячейки, в которых написано число больше 5 заливаются красным.
Давайте разбирать код подробно.
В самой первой строке:
Sub findLargeValues()
мы с помощью ключевого слова Sub объявляем процедуру (процедура просто выполняет какой-то список команд по порядку и завершает работу) findLargeValues без параметров, потому что после ее названия идут пустые круглые скобки ().
Дальше идут строки:
Dim maxWeight As Integer
maxWeight = 5
здесь мы используем ключевое слово Dim, чтобы объявить переменную и через другое обязательное ключевое слово As задаем ей тип Integer (целое число).
Но нам мало объявить машине, что теперь будет такая переменная такого типа, VBA по умолчанию придаст ей значение 0 (это так для Integer и Double, например). Поэтому в следующей строке мы присваиваем ей значение 5, с помощью простого знака равенства.
Закрепим напоследок:
процедуру мы объявляем через Sub
функцию (которая выполняет команды, но потом еще возвращает какое-то значение) через Function
все переменные через Dim.
Далее идет цикл For Each … In … Next.
Я не случайно уже второй раз использую его в примерах, потому что он очень часто оказывается полезен, поэтому лучше понять, как он работает, как можно раньше.
Я понимаю, что это непросто, но давайте представим, что вы – Гринч Санта Клаус.
Вся ваша ежегодная работа будет описываться циклом:
Для Каждого ребенка В спискеХороших
ребенку.подаритьПодарок
Следующий
На языке VBA это будет выглядеть так:
For Each child In niceList
child.makeAGift
Next
Этот цикл берет массив или коллекцию (простыми словами – какой-то набор чего-то), перебирает по очереди каждый ее элемент, к каждому из которых мы можем обращаться через переменную, чтобы производить с ним какие-то действия.
В примере с Сантой, коллекцией будет niceList, переменной – child. Циклю For Each … In … Next будет брать каждого child, который содержится в niceList, и вызывать для него метод makeAGift (читай – дарить подарок ему).
В макросе, который мы пишем, коллекцией послужит Selection. В Excel Selection – это коллекция того, что выделено на экране. Но может быть выделен диапазон ячеек, изображение и еще много чего. Мы этот момент сегодня рискованно опускаем, и считаем, что выделяется диапазон ячеек с числами. Переменную мы назвали cell, просто потому что это будет понятно.
Дальше идет условный оператор, If <условие> Then <код1> Else <код2> End if.
Я уже разобрал его в первом посте, но давайте еще раз.
<условие> - это что-то, что можно подать машине как Boolean, как величину True или False (Да или Нет).
Это может быть переменная, которая объявлена как Boolean (if <переменная> then … ), это может быть сравнение величин (x = 5, y < 12, z >= -4, x = y).
Если <условие> = True, то выполняется код1. В противном случае выполняется код2.
Если Else <код2> вообще нету, то код1 выполняется, если <условие> = True, а в противном случае вообще ничего не происходит в программа просто идет по строчкам дальше, что там написано после End if.
В нашем случае <условие> - это выражение Val(cell.Value) > maxWeight.
Что мы имеем в нем:
cell – это та самая переменная из цикла For Each … in … Next. Она олицетворяет одну отдельно взятую ячейку из выделенного диапазона.
Через cell.Value мы получаем доступ к тому, что написано в этой ячейке, к ее значению.
Функция Val(“строка”) извлекает из строки число, если оно там вообще есть. Мы применяем ее, чтобы обезопасить себя от ситуации, когда в Excel e ячейки cell значание будет, например «5а». В этом случае функция Val(cell.Value) вернет нам просто число 5.
Далее все это выражение просто сравнивается с нашей переменной maxWeight.
Таким образом, все это выражение Val(cell.Value) > maxWeight будет True, если в ячейке cell будет написано число больше 5, и будет False, если оно будет меньше или равно 5.
Ну и дальше мы видим, что в случае True, то есть когда вес нашего отдельно взятого кота, который записан в cell, больше 5 кг, выполняется «код1»:
cell.Interior.Color = vbRed
Он обращается к свойству Interior, которое есть у ячейки cell (а точнее, у всех ячеек и диапазонов ячеек в Excel, у каждой со своим значением). У этого свойства, в свою очередь, есть своё свойство Color, которому мы присвоили значение vbRed. Иными словами, назначает ей красный цвет заливки.
В случае False в условии происходит то же самое, только цвет присваивается xlNone, то есть «никакой», «без заливки».
Цвета, начинающиеся с vb… «вшиты» в сам Visual Basic, они бывают
vbBlack (черный),
vbBlue (синий),
vbCyan (бирюзовый),
vbGreen (зеленый),
vbMagenta (пурпурный),
vbRed (красный),
vbWhite (белый),
vbYellow (желтый).
xlNone – это специальный для Excel цвет, который обозначает отсутствие цвета. Кроме как в экселе работать код с его использованием нигде больше не будет.
Если вам хочется повыёживаться использовать какой-то другой цвет, то можно написать
cell.Interior.Color = RGB(rr, gg, bb),
а вместо rr, gg и bb подставить число от 0 до 255, обозначающее интенсивность красного, зеленого и синего соответственно.
Последняя строка в нашем коде End Sub обозначает, что все, что процедура кончилась.
Результат его выполнения будет такой:
Такой вот нехитрый макрос.
Но давайте добавим в него чуть-чуть универсальности и интерактивности.
Давайте очень легко и просто сделаем так, чтобы максимальное значение веса можно было менять прямо перед выполнением макроса.
Изменим код вот так
То есть, вместо скучной пятерки вы получаем число от пользователя через метод InputBox:
Вообще, этот метод в полной форме выглядит так:
InputBox(prompt, [ title ], [ default ], [ xpos ], [ ypos ], [ helpfile, context ])
prompt – обязательный параметр, сообщение в самом окошке, значение String (строка, пишется обязательно в кавычках);
[title] – необязательный параметр, заголовок этого окошка, тоже значение String;
[default] – необязательный, то, что по умолчанию уже будет написано, можете писать туда любое число или String;
[ xpos ], [ ypos ] – необязательные, положение окна на экране от верхнего левого угла, любое число;
[ helpfile, context ] – необязательные, helpfile - String, ссылающаяся на файл справки, а context – на пункт в ней (в виде числа).
Мы, как вы заметили, использовали только первые три параметра.
Если бы вы, например, хотели указать только prompt, title и xpos, ypos, то нужно было бы писать так:
InputBox(“Сообщение”,”Заголовок”,,100,150), то есть ставить запятую, перед тем местом, где должен был быть default, а потом еще одну, перед xpos. А после ypos просто закрывать скобку.
На этом, пожалуй, остановимся. Всем спасибо за внимание, желаю успехов в освоении VBA.
Буду рад видеть в комментариях ваши мнения, просьбы и советы.