Excel. Нужна помощь. Автоматическое создание гиперссылок
Всех приветствую. Возникла следующая, неразрешимая для меня, задача. Имеется excel таблица, в одном столбце серийные уникальные 15-значные номера оборудования. Также имеется папка, содержащая подпапки, в которых находятся .pdf файлы с паспортами оборудования. Каждый pdf файл переименован в соответствии с уникальным 15-значным серийным номером. Задача состоит в том, чтобы в excel таблице в соседнем столбце с номерами оборудования автоматически проставлялись гиперссылки на соответствующий файл pdf. Важный момент, почему бы не сделать это вручную – объем в тысячи штук + весь архив документов, включающий excel таблицу и все pdf файлы должен перемещаться на различные ПК, соответственно гиперссылки будут ломаться.
Что смог осилить я: получилось двумя способами составлять каталог гиперссылок на pdf файлы в вышеозначенной папке.
Способ 1. С помощью надстройки в excel ASAP Utillities на отдельном листе выводится список гиперссылок на файлы в заданной папке. Возможно есть шанс связать его с номерами оборудования через какую-то формулу, но обычный ВПР у меня не срабатывает, да и как сделать результат в ячейке гиперссылкой хотя бы на отдельный лист с гиперссылками я не понимаю.
Способ 2. Нашел excel файл с макросом, дающим тот же результат, как и в Способе 1, но так как с VBA у меня все довольно не очень, что дописать в макрос, чтобы он соотносил созданные гиперссылки с заданными номерами оборудования, я даже не представляю.
На этом светлые идеи у меня закончились. В каком направлении копать дальше – просто не понимаю. Возможно, кто-то уже сталкивался с подобной задачей и путями её решения, возможно я изначально начал действовать в не правильном направлении или в самом excel есть волшебная кнопка/функция, которая все это делает легко и просто, а я по своей бестолковости, единственный кто об этом не знает. Буду безмерно благодарен за любые подсказки.
И по традиции - кот пикабушника для привлечения хорошего настроения.
Помогите с макросом
Добрый день! Помогите пожалуйста макросом в Excel найти пустую ячейку в строке.
Знаю про Cells(Rows.Count, 1).End(xlUp).Select, но эта находит последнюю во всем столбце, не зависимо от того были ли промежутки пустых ячеек или нет. И еще поиск необходимо начинать не с первой, ну а допустим с 25 строки.
Всем заранее спасибо!!!
Немного VBA
Добрый день вам, мои подписчики, и те, кто случайно увидел этот пост.
Решил я делиться своими знаниями по интереснейшей и как ни крути очень востребованной теме – макросы на VBA.
На самом деле, я планирую рассказывать не только про VBA, но и всем что знаю и чему научился за долгие годы работы.
Не буду описывать самые азы – типы данных, их различия, типы макросов и т.п.. Нет, это будет курс по самым хардкорным вещам, с объяснениями тех моментов которые вы никогда не узнаете в самоучителях и которые обычно не рассказывают другие, такие как я, эксперты.
Начнем с малого – простой скрипт записи в txt файл
' - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +Итак, начнем по порядку:
' Создано: 2020.04.06 08:31:29
' Создатель: Фамилия Имя <vbawisard@gmail.com>
' Название: sc_String_In_TXT
' Тип: Sub
' Доступ: Public
' Описание: Записать строку в текстовый файл
' Параметр: strText {String} - Записываемая строка
' Параметр: strFile {String} - Полное имя файла
' - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
Public Sub sc_String_In_TXT(ByVal strText As String, _
ByVal strFile As String)
If Not DEBUGGING Then On Error Resume Next ' Игнорирование ошибки
' - - - - - - - - - - - - - - -
Dim objFSO As Object ' Объект взаимодействия с файловой системой
Dim objTextFile As Object ' Объект ссылка на файл
' - - - - - - - - - - - - - - -
Set objFSO = CreateObject("scripting.filesystemobject") ' Создаем объект взаимодействия с файловой системой
Set objTextFile = objFSO.OpenTextFile(strFile, 8, True) ' Открываем файл
objTextFile.Write vbNewLine & strText ' Записываем строку
objTextFile.Close ' Закрываем файл
Set objTextFile = Nothing ' Чистим память
Set objFSO = Nothing ' Чистим память
' - - - - - - - - - - - - - - -
Err.Clear ' Сбрасываем ошибку
End Sub
Для того что бы записать какую-то информацию в txt нам необходимо:
1. Записываемая строка (strText)
2. Имя файла в который будем записывать (strFile)
Оба значения мы получаем извне как параметры скрипта
Что бы взаимодействовать с файловой системой нам нужны два объекта:
1. Объект файловой системы (objFSO)
2. Файл в который будем записывать (objTextFile)
Их мы будем инициировать в момент выполнения
Теперь переходим к основной части. Для выполнения этого действия вам необходимо 4 шага:
1. Set objFSO = CreateObject("scripting.filesystemobject") - Создать объект взаимодействия с файловой системой
2. Set objTextFile = objFSO.OpenTextFile(strFile, 8, True) - Создать объект файла – для этого мы указываем:
2.1. strFile – имя файла
2.2. 8 – режим записи в конец файла
2.3. True – маркер что необходимо создать файл если он не существует
3. objTextFile.Write vbNewLine & strText - Записываем в файл не забыв добавить в начало записываемой строки vbNewLine
4. objTextFile.Close - Закрываем файл
Дальше для полного феншуя я обычно добавляю очистку памяти "убивая" объекты
Set objTextFile = Nothing
Я понимаю что по завершению скрипта эти объекты должны сами обнулиться, но я привык руководствоваться принципом "На VBA надейся, а сам не плошай".
Из того что не вошло в основной скрипт, но на что точно обратит внимание внимательный человек:
If Not DEBUGGING Then On Error Resume Next – игнорирование ошибки, причем режим игнорирования может включаться и отключаться глобальной константой DEBUGGING – когда она False – ошибки, игнорируются, когда True – значит включен режим отладки и при ошибке скрипт останавливает выполнение на строке с ошибкой.
Err.Clear – сброс ошибки, на тот случай когда режим дебага отключен, то скрипт пропустит7 ошибку, но при завершении эту ошибку лучше скинуть, иначе она может "потянуться" в другие скрипты и вызвать неожиданные последствия, о которых расскажу подробнее.
Очень надеюсь что мои посты кому-то будут интересны, и/или будут полезны в плане улучшения их навыков работы с VBA и Excel.
Экспорт данных между файлами в Excel. Нужна помощь (спасибо! Получилось)
Возникла немного нетривиальная задача в Excel, по экспорту данных в другой файл. Вопрос насколько это выполнимо с помощью макросов, и если да, то как это сделать. Если подробнее:
Есть первый файл - список заказов. Каждая строка, это полная информация об изделии: номер заказа, номер чертежа, габариты, масса, срок и т.д.
Второй файл это расчёт материала на изделие. В ячейку вводится необходимый номер строки. Через ВПР поддтягиваются необходимые, для расчетов, данные. В результате получаем список необходимого материала и его количество. И эти данные я в ручную переношу обратно в список заказов.
Вот и задумался возможно ли написание макроса, что бы данные расчетов переносить, согласно номера строка, по нажатию кнопки.
Нужна помощь с макросом Excel
Суть, открыт файл.
Визуальная его проверка и отправка как вложение в почтовом клиенте.
Записал мкрос , он срабатывает открывает почтового клиента.
Хочется, чтобы сразу подставлялась электронная почта получателя,
тема письма и подпись письма.
Sub ОтправкаПисьма()
'
' ОтправкаПисьма Макрос
' отправка письма партнеру
'
' Сочетание клавиш: Ctrl+q
'
Application.Dialogs(xlDialogSendMail).Show
End Sub
Помогите как подставить получателя в самом макросе.
Макросы VBA для Excel: выделение значений цветом (PERSONAL.xlsb, переменные, цикл For Each, всплывающие окна, заливка ячеек цветом)
Всем привет!
Вопреки сказанному в конце прошлого поста, решил второй пост писать про 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.
Буду рад видеть в комментариях ваши мнения, просьбы и советы.
Поиграем в бизнесменов?
Одна вакансия, два кандидата. Сможете выбрать лучшего? И так пять раз.
Макросы - это просто и полезно. Пост первый, вступительный
Всем привет!
Я долго вынашивал идею писать посты на тему макросов VBA в AutoCAD и Office, и решил все-таки попробовать.
Несмотря на то, что Microsoft уже давно заявил, что перестал развивать Visual Basic, VBA все еще пользуется спросом, что нет-нет, да доказывают мне окружающие, в том числе и пикабушники (@genrix4444 и @Alex0STR, привет!).
Я предлагаю вам учиться со мной на примерах из реальных задач.
Пишите мне о своих проблемах, и мы будем их решать. Вы получите нужный макрос и навык, а я - идею для поста.
Начнем мы сегодня с того, что определимся, зачем вообще могут пригодиться макросы на VBA, как их запускать и писать самим, а пример сегодня возьмем из AutoCAD.
Но сначала кое-что важное:
Материалы данного поста созданы непрофессиональным программистом.
Я не претендую на гордое звание преподавателя, коуча или сенсея.
Я буду показывать решения, которые просто будут работать.
Критика и советы горячо приветствуются.
При, по крайней мере, написании поста ни один настоящий программист не пострадал.
А теперь поехали!
1. Что такое VBA? Зачем оно человечеству?
VBA - Visual Basic for Applications - очень простой язык программирования, на котором можно писать макросы. Макросы – это небольшие программы, которые будут делать скучные и нудные вещи за вас. Или хотя бы делать их не такими скучными и нудными.
Самые популярные программы, которые поддерживают макросы VBA сейчас - AutoCAD и MS Office (Excel, Word и т.д.). Если вы работаете в одной их них (или всех), то мои посты могут вам пригодиться.
2. Как понять, что вам нужен макрос?
Если вы заметили, что в вашей работе в офисе или автокаде больше механической, чем умственной работы – нужен макрос. Если какие-то манипуляции вы проводите раз за разом, и они очень похожи – нужен макрос.
Появление макроса сделает вашу работу проще, у вас освободится время, чтобы поспать работать быстрее или играть в танки работать более качественно.
3. Что нужно, чтобы использовать макросы в AutoCAD? А в Excel, Word и т.д.?
Нужно установить эти программы с поддержкой VBA, либо установить отдельно. Если у вас будут сложности, пишите в комментариях, и я сделаю подробную инструкцию в одном из следующих постов.
4. Мне прислали макрос для авткада VBA в формате .dvb. Как его запускать?
Для этого нужно загрузить макрос в автокад.
Это делается во вкладке «Управление» кнопкой «Загрузить приложение», вот тут:
Макрос будет работать пока вы не закроете автокад. Выбирать файл нужно тут:
Если вас это не устраивает, и вы хотите, чтобы все примочки из этого макроса были отныне с автокадом навсегда, пока форматирование не разлучит их, то добавьте его в список автозагрузки (кнопка «Приложения» под портфельчиком с надписью «Автозагрузка»).
Чтобы автокад не пугал, что макрос неизвестно откуда и что «может ну его?», лучше папку, в которой лежит dvb, добавить в «Доверенные местоположения», вот тут:
Теперь можно нажать кнопку «Запустить макрос VBA», выбрать, собственно, что запускать, и нажать «Выполнить»:
Как видно, в списке тут прописано, из какого файла запускается макрос, потом после «!» идет имя модуля (подробнее о них – ниже), чаще он один на файл, и название «команды».
В моем случае файл запускает «draw_XY» из Module1 файла UTILS.dvb.
Если кому интересно, оно просто подписывает координаты X и Y в точке, в которую пользователь тычет мышкой.
Так вот, все, что произойдет после нажатия кнопки «Выполнить», решается программным кодом. Ничего сложного там нет, смелее читайте дальше. Я смог, и вы сможете.
5. Как написать свой макрос для AutoCAD?
Для начала нужно создать новый проект. Для этого нужно в командной строке автокада ввести VBAMAN (вы стали свидетелем рождения нового супергероя), либо мышкой нажать на список открыть «Диспетчер VBA» вот тут:
В появившемся окне, нужно нажать кнопку «Новый», тогда у вас появится строка Global# (в моем случае Global10):
Это и есть наш новый проект. Пока он не сохранен в файл нигде, поэтому так странно называется и путь к нему не указан.
Теперь нажмем кнопку «Редактор Visual Basic», и увидим что у него, проекта, внутри.
А внутри – пустота. Есть только объект «ThisDrawing», который создается по умолчанию. Его даже не удалить (и не надо). Можно писать код прямо туда, но лучше делать отдельный модуль под отдельный набор функций (для чего – расскажу позже, когда это станет легче объяснить). Для этого на папку «AutoCAD Objects» нажимаем правой кнопной, выбираем «Insert – Module».
Теперь у нас есть отдельный модуль. Самое время разобраться целиком с окошком редактора VBA.
1 – Структура проекта. Там всегда будет объект «ThisDrawing» (он тоже своего рода модуль). Еще туда можно надобавлять модулей и форм. Формы – это привычные нам окошки с кнопками, галочками и всем подобным. Окошки – это основная фишка Visual Basic (он поэтому так и называется), с ними оно, конечно, интереснее, но будем разбираться в следующих постах (если хотите вообще).
2 – Свойства выбранного объекта. В нашем случае единственный объект – модуль. Его единственное свойство – его имя. По щучьему велению я переименовал его в EasyMacro1.
Все, что находится правее 1 и 2 – редактор самого программного кода. Считай блокнот, только специальный.
3 – Список объектов внутри модуля. У нас их там нет, поэтому у нас только строка «(General)». Если вы выберите объект «ThisDrawing» (два раза щелкаем левой кнопкой), то там у нас будет еще «AcadDocument».
4 – Список процедур, функций и событий (те же процедуры) этого объекта. У нас оптяь только «(Declarations)». И теперь самое время сказать:
СТОП!
Какие еще процедуры, какие еще функции? Вы бы еще про переменные написали тут!
Вот и приехали. Теперь начинается само программирование.
Для начала чуть-чуть теории, определимся с тем, кто как называется, а потом начнем писать сами, и станет понятно.
VBA – процедурный язык программирования. Все, что он делает – выполняет по порядку, строчка за строчкой, либо процедуру, либо функцию. Обе эти штуки – наборы команд, и единственная разница между ними в том, что процедура просто выполняет какие-то действия и уходит в закат, а функция еще и выдает какой-то результат (число или строку, например).
И внутри всего этого хаоса могут быть переменные – заранее застолбленные «имена», по которым компьютер будет хранить значения, например, числа, строки, опять-таки, или даты, например.
Теперь приступим.
Начнем с самой идеи макроса, обдумаем в голове, что он будет делать и для чего.
Вот есть у меня чертеж. Пусть это будет, условно, три электрических подземных кабеля, начерченных в плане (вид сверху) в миллиметрах.
Вот мы видим, что у одной из «веток» длина 52083.65 миллиметра, что, считай, 52 метра 8 сантиметров.
И представим, что кто-то мне сказал, что надо подписать длины этих кусочков. А мне лень. Или их очень много. Или и то, и другое.
Я подумал, попил кофейку, и решил написать макрос, который будет в начало каждой «ветки» вставлять текст, в который будет записывать строчку «L = X.XX м».
Для этого я создам процедуру (а мы помним, что она-то как раз что-то там делает), назову ее writeLengths, чтобы было понятно, что она делает.
Для этого я пишу Sub writeLengths() в редакторе кода, и жму Enter. А редактор сам за меня допишет End Sub.
Sub – это так в VBA обозначается процедура. Если бы мы хотели написать функцию, то у нас было бы
Function <имяФункции>() … End Function
Все, что мы напишем промеж строк
Sub writeLengths()
И
End Sub
и будет теми командами, которые будет выполнять процедура до своего ухода в закат.
В тех круглых скобках, при необходимости, пишут входные параметры. Когда появится в них необходимость, вы быстро поймете, как и зачем их использовать. Сегодня не будем.
А что нам надо? Да только свет в оконце. Нам надо, чтобы макрос брал все полилинии в чертеже (пускай пока вообще все полилинии, ок?), узнавал, какой они длины (ДАННЫЕ УДАЛЕНЫ) и вставлял в чертеж текст с ее значением.
Код будет очень простой, а он будет выглядеть вот так:
Первые две строки – это объявление переменных. Оно всегда начинается с ключевого слова Dim, потом идет имя переменной, затем ключевое слово As и ее тип.
Имена переменных не должны повторяться, не должны начинаться цифры, не должны содержать пробелов и не должны быть ключевыми словами. Еще хорошо бы, чтобы они были понятны хотя бы вам (а лучше всем, кто может увидеть ваш код).
Типов в VBA бывает не так много, какой когда использовать – отдельная микронаука. Для наших скромных целей давайте пока использовать:
Integer – целое число: 1, 42, -12, 0 и т.д. VBA ограничивает их значениями от -2 147 483 648 до 2 147 483 647. Нам хватит.
Double – дробное число: 3.14, 0.0, -0.124 и т.д. Диапазон значений у них очень большой, даже писать не буду. Вам хватит, можете поверить.
String – строка текста. Пишется всегда, обязательно в кавычках: “СТРОКА”.
Boolean – логическая переменная. Ее значение может быть только либо Труъ True либо False. Одно или другое, просто и понятно.
Теперь еще раз посмотрите на код и на меня. Сразу все не так пошло, правда?
У нас объявлена переменная point, ее тип – Double. Но что это за скобки, почему там пробелы?
Дело в том, что это point – это не одно значение Double, а целый их массив.
Массив – это целый набор значений какого-то конкретного типа, со своим размером.
В нашем случае в нем есть три элемента, первый начинается с нуля. В скобках написано (0 to 2), что значит что в массиве будут элементы от 0 до 2, то есть 0, 1, 2. Чтобы получить конкретное число, нужно написать его номер в массиве, например point(1). Если написать point(4), то произойдет апокалипсис ошибка после запуска макроса. Можете попробовать.
Массив (для примера из трех элементов) можно задать так:
<название массива>(0 to 2) as <тип>
или так
<название массива>(2) as <тип>
А можно так
<название массива>(1 to 3) as <тип>
тогда его элементы будут считаться от 1.
Мы сделали от 0, потому что по умолчанию делается так, и это поможет нам избежать путанницы. Ниже увидите в чём.
Дальше у нас идет цикл For each … Next.
Если знание английского языка позволяет, то можно понять, что там творится просто прочитав.
А творится вот что:
Для
каждого
объекта (это, кстати, тоже переменная, просто мы ее отдельно не объявляли вначале, потому что кроме как внутри цикла она нам больше нигде не нужна)
В
«этого чертежа» (имеется в виду тот, который был отрыт, когда мы запустили макрос)
пространстве модели (вы ведь знаете, что кроме модели еще есть листы в автокаде, да?)
выполняются какие-то действия.
Действия, как вы уже поняли, находятся между строк
For Each object In ThisDrawing.ModelSpace
и
Next
Так как в пространстве модели могут быть разные объекты: полилинии, круги, отрезки, текст, штриховки и т.д., нам нужно как-то определять, какой из них – полилиния. И если это полилиния, тогда уже с ней что-то делать.
Это можно сделать с помощью условного оператора:
If <условие> then … End if
В нашем случае берется object.ObjectName (это такое «внутреннее текстовое название» объектов в автокаде, для полилиний оно всегда будет равно «AcDbPolyline»). Если оно как раз равно «AcDbPolyline», то у нас полилиния.
Еще, кстати, условный оператор может выглядеть так:
If <условие> then
<действия1>
Else
<действия2>
End if
В этом случае действия1 выполнятся, если условие верно (то есть равно true, там как раз Boolean), а если не верно (равно false), то выполнятся действия2.
Теперь разберем, что будет происходить, если макрос нашел полилинию (то есть, условие выполнилось).
Мы хотим записать в массив point координаты X и Y первой точки найденной полилинии, чтобы туда вставлять текст.
object.Coordinate(0) – это как раз они - координаты первой точки объекта object (ага, масло масляное, соус сальса). Вершины полилинии тоже считаются с нуля, да. Про это я и говорил выше, когда объяснял, зачем я сделал массив, элементы которого начинается с нулевого. Так вот, эти координаты (X, Y) представлены тоже в виде массива Double (дробных чисел). И тоже считаются от нуля.
Поэтому мы берем первый элемент массива point – point(0) и приравниваем, присваиваем ему значение первого элемента массива object.Coordinate(0) - object.Coordinate(0)(0).
Еще раз: получить массив с координатами первой вершины мы смогли при помощи записи object.Coordinate(0), а уже потом дописываем опять (0), чтобы получить его первый элемент.
Далее уже второму элементу массива point присвоили значение второго элемента массива object.Coordinate(0) - point(1) = object.Coordinate(0)(1)
point(2) = 0,
потому что мы чертим в 2D и координата Z нас не волнует совсем.
А вот дальше – самое интересное.
С помощью ключевого слова Call мы вызываем метод (тоже, считай, процедура) AddText, который есть у пространства модели «этого чертежа».
То есть, получается
Call ThisDrawing.ModelSpace.AddText(...)
В скобках через запятую мы пишем параметры, с которыми оно вызывается:
значение текста, который надо написать (в нашем случае мы туда отправляем object.Length – длина объекта)
точка, в которую этот текст вставляется (наш массив point)
и высота текста (я выбрал 200 единиц, чтобы его было видно без микроскопа сильного приближения).
Теперь макрос можно запустить и посмотреть, что получилось.
Кстати, из окна редактора VBA можно запустить нажав зеленую стрелочку вверху (рядом с кнопками «Пауза» и «Стоп»).
А получилось вот что. Длина проставилась в первой точке. Но она проставилась в миллиметрах. И после запятой знаков слишком много.
Это можно исправить, если отформатировать строку со значением текста.
Делается это так:
Format(<выражение>, <формат выражения>)
Формат выражения – это тоже строка, но которая описывает, как должно выглядеть значение.
Например, если мы напишем “#”, то получим только целые части чисел. Было 1,23 стало 1.
Если написать “#.#”, то получим один знак после запятой.
Если вместо решетки писать нули, то они как бы занимают место. То есть с форматом “00.00” число 1.2 будет написано как "01.20". Причем если у нас было бы не 1.2, а 101.2, все рано получилось бы "101.2". До запятой знаки не отрезаются. Логично же, это уже совсем другое число получится.
Еще в формат можно дописывать другие символы, они просто пропишутся как есть. Можно, например, написать “L = 0.00 м”, и мы получим из числа 52083.6472… запись «L = 52083.65».
А это как раз то, что нам нужно, только нам нужно еще и в метрах это все. Для этого object.Length надо просто разделить на 1000.
В общем, исправим код вот так:
Call ThisDrawing.ModelSpace.AddText(Format(object.Length / 1000, "L = 0.00 м"), point, 200)
И результат получим такой:
Макрос в определенной мере готов, осталось его сохранить, нажав Ctrl+S, либо “File – Save Global#”.
Конечно, такой макрос дает не очень удобный результат.
Можно сделать так, чтобы текст разворачивался вдоль линии, и вставлялся в ее середину. И в отдельный слой. И другим цветом, например.
Но пост получился уже достаточно объемный из-за долгого вступления, поэтому на этом пока остановимся.
Следующий пост, наверное, напишу тоже на тему автокада, потому что придумать что-то простое, но полезное для Excel пока не удается.
Буду рад видеть в комментариях ваши мнения, просьбы и советы.
Если вы поняли все, но сели писать сами, и у вас ничего не получается - не переживайте. Просто практикуйтесь, ставьте цели и добивайтесь их, а я постараюсь помочь :)