Семинар по VBA от Cepreu4`а #01 Отсекаем хвосты или половина прокрустова ложа. 1. Вступление, которое читать не обязательно Почему Visual Basic Application(VBA)? Часто встречаются просьбы: "Есть файл, в нём такие-то строки, нужно из них извлечь такую-то информацию или изменить их". Иногда, спрашивающему советуют воспользоваться редактором, имеющим свой скриптовый язык, или использовать какой-нибудь скриптовый язык и даже приводят готовый текст скрипта. И если с редактором обычно всё просто, остаётся лишь выучить язык написания макросов или скриптов, то с отдельным скриптовым языком ещё, скорее всего, предстоят дополнительные хлопоты. И, если PHP, Perl и тому подобные языки ещё могут пригодиться, то язык, встроенный в редактор, навряд ли найдёт дополнительное применение. Я не являюсь поклонником языка Basic и всех его диалектов(хотя моя первая программа для Windows, тогда ещё 3.11, была написана на Visual Basic(VB) 2.0). Тем не менее, на большинстве персональных компьютеров на территории бывшего СССР, по крайней мере, одной из установленных операционных систем является MS Windows, а с ней часто устанавливают и пакет MS Office. Одной из особенностей этого пакета является язык для написания макросов, являющимся одним из диалектов Basic. Следовательно, VBA в большинстве случаев, находиться под рукой и никаких дополнительных телодвижений по скачиванию, установки и настройке делать не требуется. Полезными могут оказаться и встроенная функция автозавершения кода и функция подсказки списка параметров функций, в некоторой степени заменяющие систему помощи. Этот язык поддерживается с вариантами во всех основных приложениях пакета. Кроме того, основы языка совпадают с языком VBS и языком VB, поддерживаемым средой разработки MS Visual Studio. Т.е. знания, приобретённые при изучении VBA, с большей вероятностью не будут лежать мёртвым грузом. 2. Вступление, которое желательно прочитать Эта статья является первой в задуманном цикле. Статьи цикла ни в коем случае не являются уроками, а тем более весь цикл не будет являться курсом. Я не ставлю своей целью научить читателей программированию. Здесь не будет объясняться, что такое алгоритм, константа, переменная, оператор, цикл, условный и безусловный переходы и т.п. термины и понятия. По этим вопросам написано очень много умных книг, и соревноваться с их авторами у меня нет желания. Я хочу лишь показать, что обработать информацию с помощью компьютера в удобный для Вас вид при некотором приложении мозгов и рук не сложно, но называть себя программистом после прочтения моих статей из этого цикла я бы Вам не советовал. Также, я не ставлю своей задачей научить Вас конкретному языку программирования. Наверняка существуют книги, наподобие «VBA для чайников», «VBA за NN дней» и т.п. Если хотите узнать язык – поищите их в магазинах, у знакомых или в сети. Посему, мы будем называть эти занятия семинарами, на которых будем выполнять упражнения, разбирая как решить конкретную задачу по обработке данных. Я буду приводить конкретный код, чаще всего не объясняя, что делает тот или иной оператор или функция и почему именно это надо применять. Не исключено, что будут и домашние задания(скорее всего без этого не обойдётся), однако оценок я выставлять не буду , и уровень Ваших знаний Вам придётся определять самим. На первом семинаре я, так и быть, расскажу про самые элементарные операции в среде разработки. В дальнейших статьях это повторяться не будет. Под щелчком далее подразумевается одиночное нажатие левой кнопки мыши. 3. Постановка задачи и алгоритм Для первого подопытного кролика возьмём задачу по ограничению длины строк в текстовом файле и записи результата в другой файл. Следовательно, алгоритм достаточно прост: 1. Выбрать входной файл, задать имя и/или расположение выходного файла и задать максимальную длину строки в выходном файле. 2. Открыть входной файл на чтение и выходной – на запись. 3. Пока не кончились строки во входном файле – прочитать строку, вычислить её длину и, если она больше заданного значения, то отсечь лишнее. Записать строку в выходной файл. 4. Если входной файл исчерпан – закрываем все рабочие файлы и завершаем работу. 4. Запускаем среду разработки(IDE) Итак, считаем, что на Вашем компьютере запущена операционная система MS Windows с версией, начиная от 95, и у Вас установлен MS Office с версией, начиная от 97. В моём случае это Windows XP SP3 и русская версия MS Office 2003. Запускаем MS Word. Дабы избежать трудностей с запуском наших творений в дальнейшем, вызываем окно настройки параметров безопасности программы. Для этого в главном меню Word идём путём Сервис->Макрос->Безопасность. Если у Вас уже выбран вариант <Средняя> или <Низкая>, то Вы можете ничего не менять. В противном случае, советую Вам выбрать уровень <Средняя> - при загрузке документов с макросами придётся лишний раз щёлкнуть мышкой, но некоторую защиту от лишних приключений Вы получите. Впрочем, любители экстрима могут рискнуть и разрешить исполнять макросы всегда. Теперь можно запустить и саму IDE. Выбираем в главном меню Сервис->Макрос->Редактор Visual Basic. В дальнейшем можно сократить затраты на это, нажав на клавиатуре «горячую» комбинацию клавиш <Alt-F11>. С этого момента пункты меню и окон у нас будут относиться к окну IDE Visual Basic, и писаться на английском языке. 5. Создаём главную форму(окно) программы После появления визуальных средств разработки мне стало удобнее чаще всего сначала создать большую часть визуального интерфейса, а затее уже программировать логику работы программы. Итак, для начала, нам нужно создать саму форму. В меню выбираем Insert->UserForm(можно воспользоваться и кнопкой на панели инструментов, расположенной под меню) и у нас появляется окно редактора форм с новой формой внутри. Рядом возникнет окно ToolBox с визуальными элементами управления(контролами). При перемещении курсора мыши Вы увидите всплывающие подсказки с названиями контролов. Вы можете с помощью мыши изменить размер формы до нужного Вам размера, а затем подогнать размер окна редактора форм под размер формы, чтобы не занимать лишнее место на экране. Справа располагается окно проекта, а под ним – окно свойств(Properties) выбранного элемента интерфейса в окне редактора форм. Щёлкним на слове Project в окне проекта и в окне Properties поменяем значение свойства (Name) на желательное Вам название. Впрочем, менять не обязательно. В окне Properties, в частности есть поля Height и Width. Меняя значения этих полей, Вы также можете менять размеры формы. У меня Height=134, а Width=344. Сохраним наши труды на диск, одним из обычных способов, принятых в программах для Windows. Например, нажав комбинацию клавиш <Ctrl-S>. Имя файла и его размещение можете придумать сами. Я назвал файл Workshops(от перевода слова семинары). По мере продвижения работы не забывайте сохранять сделанное. Я привык элементы, относящиеся к какой-то одной функции группировать с помощью контрола, называемого в VB Frame(я чаще буду писать группа). Щёлкните мышкой по форме. Выберите мышкой на ToolBox контрол Frame (прямоугольник с надписью XYZ наверху), переместите курсор мыши на форму и щёлкните мышью по форме. На ней появится рамка контрола. Если часть рамки вышла за границы формы, то временно измените размеры последней, увеличьте временно её и подгоните размеры и положение фрейма под необходимые. Можно не меняя размеры формы изменить свойства Left, Top, Height и Width фрейма в окне Properties. Я сделал Left=6, Top=6, Height=36, Width=330. Кстати, колесо мыши ни в редакторе форм, ни в редакторе кода у меня не работало. Теперь выберем контрол TextBox (поле редактирования) и поместим его внутри группы. Положение и размеры: Left=6, Top=6, Height=18, Width=276. Справа от поля редактирования поместим кнопку (CommandButton) Положение и размеры: Left=282, Top=6, Height=18, Width=36. Теперь займёмся немного писаниной. Во-первых, надо дать внятные заголовки элементами управления для удобств пользователя, а так же, не забыв себя дорого, внятные имена для удобства написания программы. Итак, щёлкаем по свободному месту формы. В окне Properties появляются её свойства. Раз наша программа занимается усечением строк, то в самом верхнем поле – (Name) поменяем значение на frmTruncate, а в поле Caption - на Truncate. Далее щёлкаем по рамке фрейма группы. В этой группе мы будем задавать имя входного файла. Поэтому зададим Caption группы Input, а её (Name) - grpInput. Аналогично, у кнопки (Name) - btnInput, а Caption, поскольку мы будем читать из этого файла, припишем Read. Полю редактирования зададим (Name) - edtInput. Текст по умолчанию введём позже. Естественно, Вы можете написать, в именах и заголовках, то, что Вам больше нравится, но потом не запутайтесь, когда мы приступим к программированию. В итоге должно получиться примерно так: Аналогично создаём вторую группу, отличающуюся только параметром Top, который будет равен 48. Располагаем в ней такие же поле редактирование и кнопку. Имена и заголовки меняем по аналогии, только вместо Input везде пишем Output. Заголовок кнопки я поменял на Write. Нам нужно будет также как-то инициировать обработку информации. Для этого поместим кнопку под второй группой в правом нижнем углу формы. В качестве имени припишем ей btnRun, а заголовок – Run. Размеры: Height=18, Width=48. Теперь займёмся заданием длины получаемой строки. Можно в самой программе жёстко задать число и каждый раз менять на желаемое. Однако удобнее его задавать интерактивно. Для этого внизу формы поместим поле редактирования и левее рядом с ним надпись(Label), чтобы не забыть, а что туда надо вводить. Заголовок у надписи поменяем на Length (я ещё поменял значение свойства TextAlign на 3 - fmTextAlignRight), а у поля редактирования поменяем имя на edtLength. Свойству Value этого поля зададим значение, например, 8. Это будет значение длины по умолчанию. Вы можете поставить то значение, которое планируете использовать наиболее часто. Если хотите, чтобы уровень символов в надписи и поле редактирования был одинаков, то подгоните положение надписи, изменяя её свойство Top вручную. Завершать работу программы можно будет щелчком по крестику в правом углу заголовка формы(или другими стандартными способами). Однако, для порядка, разместим на форме внизу слева кнопку для завершения работы. Изменим её заголовок на Close, а имя на btnClose. Изменим текст по умолчанию в поле edtInput, для этого свойству Text зададим значение input.txt, а в edtOutput – output.txt. Окончательный вид формы у меня такой: 6. Пишем код, он же текст программы Для проверки работы нашей программы создадим тестовый текстовый файл input.txt с содержанием Code: qwerty asdfgh zxcvbnm poiuytre lkjhgfdsa 1234 12345 1234567890 1111111111111111111111111111111111 2222222222222222222222222222222222222222222222 33333333333333333333333333333333333333333333333333333333333333333 44444444444444444444444444444444444444444444444444444444 555555555555555555555555555555555555555555555555555555555555 6666666666666666666666666666666666666666666666666 и поместим его в один каталог с нашим творением. Файл следует сохранять, как неформатированный(обычный) текст(plain text), а не документ Word. IDE выполняет довольно большую часть работы по набору текста программы. Сделайте двойной щелчок на кнопке в группе Input. Будет активизировано окно редактора кода и в него IDE вставит шаблон обработки события щелчка по кнопке. Code: Private Sub btnInput_Click() End Sub Нам остаётся добавить лишь свой код. Вызовем диалог открытия файла, обработаем результат его работы и, в случае успешного результата, заменим в поле редактирования имя файла по умолчанию на имя выбранного файла. В итоге у меня получился текст Code: Private Sub btnInput_Click() With Application.FileDialog(FileDialogType:=msoFileDialogOpen) .AllowMultiSelect = False .InitialFileName = "*.txt" If .Show = -1 Then edtInput.Text = .SelectedItems(1) End If End With End Sub Наша программа уже кое-что может делать. Запустите макрос на выполнение. Для этого можно выбрать пункт меню Run->Run Sub/UserForm или щёлкните мышью по кнопке с зелёной стрелочкой на панели инструментов под главным меню или нажмите на клавиатуре клавишу <F5>. Появится окно нашей программы. Можете щёлкнуть по кнопке Read. Откроется окно выбора файла для открытия. Выберите файл и нажмите кнопку выбора. В русскоязычной Windows это кнопка Открыть. В результате в поле редактирования изменится текст. Выйдите из программы. Проделаем аналогичную операцию с кнопкой в группе Output. Code: Private Sub btnOutput_Click() With Application.FileDialog(FileDialogType:=msoFileDialogSaveAs) .AllowMultiSelect = False .InitialFileName = edtOutput.Text If .Show = -1 Then edtOutput.Text = .SelectedItems(1) End If End With End Sub Подготовительные работы сделаны, теперь приступим к основной функции программы, ради чего мы всё и затеяли. Делаем двойной щелчок по кнопке Run. Поскольку бейсик работает с файлами через их номера и, чтобы не запутаться какой файл для чего предназначен, я советую Вам при работе с файлами определять поименованные константы(я выбрал идентификаторы InputFile и OutputFile). После задания констант определим рабочие переменные и начнём обработку. Прочитаем желаемую максимальную длину строк из поля редактирования в соответствующую переменную. Откроем входной файл с подопытным материалом и выходной файл для записи результата. После этого создадим главный цикл программы, который будет работать, пока не кончаться строки во входном файле. В теле этого цикла мы читаем строку из входного файла и проверяем её длину. Если длина больше заданной, то мы её укорачиваем, в противном случае ничего не делаем(именно поэтому у нас не полностью прокрустово ложе). После чего записываем строку в выходной файл. После исчерпания входного файла выходим из цикла и закрываем рабочие файлы. Code: Private Sub btnRun_Click() Const InputFile = 1, OutputFile = 2 Dim S As String Dim N As Integer N = Str(edtLength.Text) Open edtInput.Text For Input As InputFile Open edtOutput.Text For Output As OutputFile Do While Not EOF(InputFile) Line Input #InputFile, S If Len(S) > N Then S = Left(S, N) Print #OutputFile, S Loop Close OutputFile Close InputFile End Sub Да, мы чуть не забыли про ещё один контрол на форме приложения - кнопку Close. Дважды щелкаем по ней и добавляем в шаблон команду удаления формы. Code: Private Sub btnClose_Click() Unload Me End Sub /code] В принципе, программа уже вполне рабочая, но для её запуска надо входить в среду разработки. Избавимся от лишних движений и окон на рабочем столе. Жмём [B]Сервис[/B]->[B]Макрос[/B]->[B]Макросы...[/B](<Alt-F8>), там щёлкаем на стрелку поля с выпадающим списком [B]Макросы из[/B] и выбираем документ, в котором мы пишем программу. Затем в поле имя пишем название запускающего макроса(я написал [B]ShowTrunc[/B]) и щелкаем кнопку [B]Создать[/B]. В теле открывшейся подпрограммы вписываем строку [B]frmTruncate.Show[/B] [code] Sub ShowTrunc() frmTruncate.Show End Sub Теперь для запуска макроса после загрузки документа надо пройти Сервис->Макрос->Макросы... выбрать нужный макрос и нажать кнопку Выполнить. 7. Заключение Итак, в ходе семинара было показано, как, использовав подручные средства, можно написать простенькую, но, тем не менее, полезную в некоторых случаях, программку по обработке текстовой информации. Было создано окно(форма) приложения с размещёнными на нём элементами управления. Эта программа может послужить шаблоном для создания других программ. 8. Домашнее задание Можете попробовать написать макрос удаляющий начало строки до достиженя последней заданной длины. (c)2010, Cepreu4. Оригинал статьи расположен на GraBBerZ.CoM . При копировании ссылка обязательна. PS Приветствуется конструктивная критика.