Vba for application word

Время на прочтение
7 мин

Количество просмотров 8.1K

Картинка pch.vector, freepik

Практически каждый из читателей, наверняка не раз (а кто-то и на постоянной основе), имеет потребность в написании и редактировании документов в среде Word.

Однако если подобная деятельность производится с некоторой периодичностью, пытливый ум сразу начинает думать о способах оптимизации своего труда. Одним из таких способов является программирование в среде Visual Basic for Applications,- среде разработки, которая встроена в известные офисные продукты: Word, Excel, PowerPoint и т.д. Статья больше вводная, для тех, «кто совсем не в теме» :-).

Следует сразу оговориться, что любое программирование требует для изучения достаточных временных ресурсов и, в ряде случаев, подобные трудозатраты могут быть неоправданными.

Поэтому, в этих случаях имеет смысл просто — напросто записать макрос. Которой представляет собой записанную последовательность ваших действий, которая должна быть повторена многократно для некой, часто повторяющейся обработки.

Макрос
Тут следует сказать, что по умолчанию, меню для записи макроса скрыто и его необходимо явным образом включить. Для этого нужно пройти по пути: Файл-Параметры

В открывшемся окне перейти в настройку ленты:

Далее, в правом окне, под названием «Основные вкладки», поставить галочку рядом с опцией «разработчик»:

В результате этих действий на ленте сверху у вас появится вкладка «разработчик»:

Войдя в которую, в левой части, вы как раз и сможете найти две интересующие нас опции: «Visual Basic» и «Макросы»:

Соответственно, далее если мы нажимаем на кнопку «Запись макроса», то мы сможем записать нашу последовательность действий:

Созданный макрос можно сохранить либо в конкретном документе, либо сделать его доступным для всех документов (если сохраним его в шаблоне normal.dotm):

После чего, записанный макрос может быть воспроизведён, если мы перейдём, нажав на кнопку «Макросы»:

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

Здесь существуют 2 опции:

  • правка кода уже имеющегося макроса
  • написание кода с нуля.

Для первого случая, нам нужно перейти нажав на «макросы», для того чтобы открылась окно выбора макроса и нажать на кнопку «отладка»:

Это приведёт к запуску среды разработки, где вы сможете увидеть свой записанный макрос в виде кода. Кстати говоря, это является одним из интересных лайфхаков, когда недостаточное знание программирования на VBA вы подменяете сгенерированным кодом макроса и реверс-инжинирингом, с попыткой вникнуть, «а как оно там внутри устроено?»:

Чуть выше, мы произвели ряд манипуляций, для того чтобы вынести вкладку «разработчик» на ленту. Однако если вы хотите не писать макросы, а писать код сразу, совершенно необязательно добавлять эту вкладку на ленту.

Среду разработки можно вызвать нажатием сочетания клавиш Alt+F11, после чего, написав нужный код, запустить его прямо из среды разработки.

Список готовых макросов можно вызвать нажатием сочетания клавиш ALT+F8.

Visual Basic for Applications(VBA)
Как мы уже говорили, разработка кода для приложений Office ведётся с использованием специального кода, который является версией интерпретируемого языка Visual Basic (несколько упрощённой его версией).

Благодаря использованию объектной модели компонентов (COM), могут применяться компоненты, используемые в ряде программ одновременно, для этого используется технология OLE (Object Linking and Embedding), суть которой заключается передаче части работы от одной программы к другой (в рамках среды Windows), и получение обратно результата.

Это означает, что теоретически, вы можете на VBA написать программу, которая будет использовать, например, средства Photoshop или Corel Draw, если конечно они установлены у вас на компьютере (однако, есть подозрение, что для этого потребуется более расширенная версия языка, чем тот, который идёт в комплекте с пакетом Office).

В рамках VBA объекты представлены в виде иерархии: Application/Document/Paragraph и т.д., то есть, как можно видеть в этой строке, каждый предыдущий — содержит последующий.

Получается своего рода «матрёшка», где одно вложено в другое и, если задуматься, это достаточно логично.

Например, главным объектом является Application. Создание этого объекта, другими словами, означает просто запуск Word. Но программа сама по себе никому не интересна, необходимо, чтобы внутри этой программы был создан или открыт некий документ (объект Document). В свою очередь, этот объект содержит целый ряд других элементов иерархии, которые служат для задания его параметров и оформления.

Согласно этому источнику, несмотря на то, что Word содержит множество объектов, по большому счёту, для успешной работы достаточно понимания всего лишь 5 объектов:

  • Application
  • Document
  • Selection
  • Range
  • Bookmark

Логика здесь следующая:

  • мы запустили Word (Application),
  • создали или открыли в нём документ(Document),
  • дальнейшие манипуляции в этом документе происходят либо с постановкой курсора в определенное место, либо с выделением определённого места в документе(Range).

Последний же объект (Bookmark) имеет смысл изучить для создания удобной навигации по документам, так как он просто управляет созданием удобных закладок.

Каждый из перечисленных выше объектов, имеет свой набор свойств и методов.

Более подробно о их сути вы можете почитать вот здесь.

В свою очередь, наиболее полный список всех объектов, с их описанием вы можете найти вот здесь.

Вкратце, любая программа на Visual Basic представляет собой сочетание приложения (в нашем случае Word), среды разработки и модулей.

Под модулями понимаются процедуры, которые содержат в себе программный код.

Для создания модуля, всего лишь нужно перейти в соответствующий шаблон (например, если мы создаём модуль, который должен быть доступен для всех документов, мы создаём его в шаблоне Normal). Для этого нажимаем на папке Microsoft Word Objects — правой кнопкой мыши и проходим по пути:

Модули могут быть представлены двумя видами:

  • подпрограммы
  • функции (предназначены для вычисления конкретного значения).

Структура типичной подпрограммы выглядит следующим образом:

Sub имя_подпрограммы ([Параметры])
Тело подпрограммы
End Sub

Структура функции выглядит следующим образом:

Sub имя ([Параметры])
Тело функции
имя=выражение
End Sub

Например, если у нас существует некая функция которая должна возвращать определённое значение, она может выглядеть следующим образом:

Sub TextFinder ([Параметры])
Тело функции
TextFinder=Selection.Find.found
End Sub

На примере тех же самых макросов, если у нас их более 1, они открываются в среде разработки, разделённые на отдельные подпрограммы, располагаясь друг за другом:

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

Visual Basic for Applications является объектно-ориентированном языком программирования и полностью поддерживает постулаты этой концепции.

Типичная команда выглядит как разделённая точками в стиле ООП, где мы спускаемся по иерархии в самый низ, — до конкретного действия:

Application.ActiveDocument.PageSetup.Orientation = wdOrientLandscape

Например, приведённая выше команда, служит для того, чтобы установить альбомную ориентацию листа.

В редакторе кода присутствует система автодополнения кода: после того как вы ввели первый уровень объектной модели и поставили после него точку, система сама предлагает вам доступные варианты следующего уровня:

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

Достаточно интересным является режим отладки программы. Для этого, вам необходимо
записать какой-либо макрос, далее, войти в режим его отладки:

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

Для того чтобы исполнить следующую команду, следует каждый раз нажимать на клавишу F8:



Если параллельно с редактором кода вы откроете документ Word, на примере которого вы отрабатываете этот макрос, то вы будете сразу визуально видеть, что делает каждая построчно выполняемая команда (например, если это переход в некую ячейку таблицы и её выделение, — вы будете видеть этот процесс пошагово).

Но тут есть один нюанс: как вы могли видеть выше, программа начинает исполняться с самого начала. Но программа может быть достаточно длинной! Как сделать так, чтобы можно было провести, условно говоря, «юнит-тест» участка программы, который находится не в самом начале?

Для этого нужно всего лишь кликнуть в серую зону слева от программы — и там появится красная метка. Она означает то место, с которого стартует выполнение кода. Теперь, если мы нажмём на F8, — начало исполнения перескочит на эту метку:


Вообще говоря, программирование на VBA может быть достаточно мощной штукой, так как позволяет не только писать некие простые макросы, но даже и создать свой программный продукт, для генерации каких-либо отчётов или форм (и не только). Да, конечно, я сам имею такую слабость, — не желая изучать имеющиеся у продукта инструменты, пытаюсь решить проблему собственными знакомыми костылями (ну, знаю я, например, Java, — значит, буду решать проблему в рамках этого языка, игнорируя встроенные возможности Word). Однако, это не совсем правильный подход, так как «ученье — свет» :-).

Кто к этому так подходит, имеет и неплохие плюшки: совсем недавно на хабре вышла статья «как я с помощью VBA оплатил себе университет», которая наглядно показывает, что программирование на этом языке, в среде Office ещё рано списывать и может быть к этому стоит присмотреться повнимательней.

P.S. Вот мы тут гоняемся за интеллектуальными IDE, модными актуальными языками… А может вот оно, а? :-)

Будет очень интересно почитать в комментах, если кто то из читателей использовал неким интересным образом программирование под word в VBA и какие результаты это дало!

В двух словах изложу свой опыт: приходилось использовать достаточно продвинутые макросы для написания документации по компьютерному железу. Макросы позволяли «одним кликом» форматировать гигантскую таблицу с параметрами (регистры, поля регистров и их описание и т.д.). Форматировать хитро: первую строку выделить, первый столбец — искать в каждой строке диапазон битов регистра, вида [12:0], если найдено — применить стиль; такая же сложная логика форматирования по всей таблице (поиск определённых участков и их оформление. Скажем, таблица на 50 строк форматировалась… Секунд 15-20. Вручную — до бесконечности (в зависимости от лени и загруженности работой). Так что, макросы имеют право на жизнь!

title ms.prod ms.assetid ms.date ms.localizationpriority

Getting started with VBA in Office

office

7208a87a-a567-41d9-af5b-0df3884c58d9

08/14/2019

high

Are you facing a repetitive clean up of fifty tables in Word? Do you want a particular document to prompt the user for input when it opens? Are you having difficulty figuring out how to get your contacts from Microsoft Outlook into a Microsoft Excel spreadsheet efficiently?

You can perform these tasks and accomplish a great deal more by using Visual Basic for Applications (VBA) for Office—a simple, but powerful programming language that you can use to extend Office applications.

This article is for experienced Office users who want to learn about VBA and who want some insight into how programming can help them to customize Office.

The Office suite of applications has a rich set of features. There are many different ways to author, format, and manipulate documents, email, databases, forms, spreadsheets, and presentations. The great power of VBA programming in Office is that nearly every operation that you can perform with a mouse, keyboard, or a dialog box can also be done by using VBA. Further, if it can be done once with VBA, it can be done just as easily a hundred times. (In fact, the automation of repetitive tasks is one of the most common uses of VBA in Office.)

Beyond the power of scripting VBA to accelerate every-day tasks, you can use VBA to add new functionality to Office applications or to prompt and interact with the user of your documents in ways that are specific to your business needs. For example, you could write some VBA code that displays a pop up message that reminds users to save a document to a particular network drive the first time they try to save it.

This article explores some of the primary reasons to leverage the power of VBA programming. It explores the VBA language and the out-of-the-box tools that you can use to work with your solutions. Finally, it includes some tips and ways to avoid some common programming frustrations and missteps.

[!includeAdd-ins note]

When to use VBA and why

There are several principal reasons to consider VBA programming in Office.

Automation and repetition

VBA is effective and efficient when it comes to repetitive solutions to formatting or correction problems. For example, have you ever changed the style of the paragraph at the top of each page in Word? Have you ever had to reformat multiple tables that were pasted from Excel into a Word document or an Outlook email? Have you ever had to make the same change in multiple Outlook contacts?

If you have a change that you have to make more than ten or twenty times, it may be worth automating it with VBA. If it is a change that you have to do hundreds of times, it certainly is worth considering. Almost any formatting or editing change that you can do by hand, can be done in VBA.

Extensions to user interaction

There are times when you want to encourage or compel users to interact with the Office application or document in a particular way that is not part of the standard application. For example, you might want to prompt users to take some particular action when they open, save, or print a document.

Interaction between Office applications

Do you need to copy all of your contacts from Outlook to Word and then format them in some particular way? Or, do you need to move data from Excel to a set of PowerPoint slides? Sometimes simple copy and paste does not do what you want it to do, or it is too slow. Use VBA programming to interact with the details of two or more Office applications at the same time and then modify the content in one application based on the content in another.

Doing things another way

VBA programming is a powerful solution, but it is not always the optimal approach. Sometimes it makes sense to use other ways to achieve your aims.

The critical question to ask is whether there is an easier way. Before you begin a VBA project, consider the built-in tools and standard functionalities. For example, if you have a time-consuming editing or layout task, consider using styles or accelerator keys to solve the problem. Can you perform the task once and then use CTRL+Y (Redo) to repeat it? Can you create a new document with the correct format or template, and then copy the content into that new document?

Office applications are powerful; the solution that you need may already be there. Take some time to learn more about Office before you jump into programming.

Before you begin a VBA project, ensure that you have the time to work with VBA. Programming requires focus and can be unpredictable. Especially as a beginner, never turn to programming unless you have time to work carefully. Trying to write a «quick script» to solve a problem when a deadline looms can result in a very stressful situation. If you are in a rush, you might want to use conventional methods, even if they are monotonous and repetitive.

VBA Programming 101

Using code to make applications do things

You might think that writing code is mysterious or difficult, but the basic principles use every-day reasoning and are quite accessible. Microsoft Office applications are created in such a way that they expose things called objects that can receive instructions, in much the same way that a phone is designed with buttons that you use to interact with the phone. When you press a button, the phone recognizes the instruction and includes the corresponding number in the sequence that you are dialing. In programming, you interact with the application by sending instructions to various objects in the application. These objects are expansive, but they have their limits. They can only do what they are designed to do, and they will only do what you instruct them to do.

For example, consider the user who opens a document in Word, makes a few changes, saves the document, and then closes it. In the world of VBA programming, Word exposes a Document object. By using VBA code, you can instruct the Document object to do things such as Open, Save, or Close.

The following section discusses how objects are organized and described.

The Object Model

Developers organize programming objects in a hierarchy, and that hierarchy is called the object model of the application. Word, for example, has a top-level Application object that contains a Document object. The Document object contains Paragraph objects and so on. Object models roughly mirror what you see in the user interface. They are a conceptual map of the application and its capabilities.

The definition of an object is called a class, so you might see these two terms used interchangeably. Technically, a class is the description or template that is used to create, or instantiate, an object.

Once an object exists, you can manipulate it by setting its properties and calling its methods. If you think of the object as a noun, the properties are the adjectives that describe the noun and the methods are the verbs that animate the noun. Changing a property changes some quality of appearance or behavior of the object. Calling one of the object methods causes the object to perform some action.

The VBA code in this article runs against an open Office application where many of the objects that the code manipulates are already up and running; for example, the Application itself, the Worksheet in Excel, the Document in Word, the Presentation in PowerPoint, the Explorer and Folder objects in Outlook. Once you know the basic layout of the object model and some key properties of the Application that give access to its current state, you can start to extend and manipulate that Office application with VBA in Office.

Methods

In Word, for example, you can change the properties and invoke the methods of the current Word document by using the ActiveDocument property of the Application object. This ActiveDocument property returns a reference to the Document object that is currently active in the Word application. «Returns a reference to» means «gives you access to.»

The following code does exactly what it says; that is, it saves the active document in the application.

Application.ActiveDocument.Save

Read the code from left to right, «In this Application, with the Document referenced by ActiveDocument, invoke the Save method.» Be aware that Save is the simplest form of method; it does not require any detailed instructions from you. You instruct a Document object to Save and it does not require any more input from you.

If a method requires more information, those details are called parameters. The following code runs the SaveAs method, which requires a new name for the file.

Application.ActiveDocument.SaveAs ("New Document Name.docx")

Values listed in parentheses after a method name are the parameters. Here, the new name for the file is a parameter for the SaveAs method.

Properties

You use the same syntax to set a property that you use to read a property. The following code executes a method to select cell A1 in Excel and then to set a property to put something in that cell.

    Application.ActiveSheet.Range("A1").Select
    Application.Selection.Value = "Hello World"

The first challenge in VBA programming is to get a feeling for the object model of each Office application and to read the object, method, and property syntax. The object models are similar in all Office applications, but each is specific to the kind of documents and objects that it manipulates.

In the first line of the code snippet, there is the Application object, Excel this time, and then the ActiveSheet, which provides access to the active worksheet. After that is a term not as familiar, Range, which means «define a range of cells in this way.» The code instructs Range to create itself with just A1 as its defined set of cells. In other words, the first line of code defines an object, the Range, and runs a method against it to select it. The result is automatically stored in another property of the Application called Selection.

The second line of code sets the Value property of Selection to the text «Hello World», and that value appears in cell A1.

The simplest VBA code that you write might simply gain access to objects in the Office application that you are working with and set properties. For example, you could get access to the rows in a table in Word and change their formatting in your VBA script.

That sounds simple, but it can be incredibly useful; once you can write that code, you can harness all of the power of programming to make those same changes in several tables or documents, or make them according to some logic or condition. For a computer, making 1000 changes is no different from making 10, so there is an economy of scale here with larger documents and problems, and that is where VBA can really shine and save you time.

Macros and the Visual Basic Editor

Now that you know something about how Office applications expose their object models, you are probably eager to try calling object methods, setting object properties, and responding to object events. To do so, you must write your code in a place and in a way that Office can understand; typically, by using the Visual Basic Editor. Although it is installed by default, many users don’t know that it is even available until it is enabled on the ribbon.

All Office applications use the ribbon. One tab on the ribbon is the Developer tab, where you access the Visual Basic Editor and other developer tools. Because Office does not display the Developer tab by default, you must enable it by using the following procedure:

To enable the Developer tab

  1. On the File tab, choose Options to open the Options dialog box.

  2. Choose Customize Ribbon on the left side of the dialog box.

  3. Under Choose commands from on the left side of the dialog box, select Popular Commands.

  4. Under Customize the Ribbon on the right side of the dialog box, select Main Tabs in the drop down list box, and then select the Developer checkbox.

  5. Choose OK.

[!NOTE]
In Office 2007, you displayed the Developer tab by choosing the Office button, choosing Options, and then selecting the Show Developer tab in Ribbon check box in the Popular category of the Options dialog box.

After you enable the Developer tab, it is easy to find the Visual Basic and Macros buttons.

Figure 1. Buttons on the Developer tab

Buttons on the Developer tab

Security issues

To protect Office users against viruses and dangerous macro code, you cannot save macro code in a standard Office document that uses a standard file extension. Instead, you must save the code in a file with a special extension. For example you cannot save macros in a standard Word document with a .docx extension; instead, you must use a special Word Macro-Enabled Document with a .docm extension.

When you open a .docm file, Office security might still prevent the macros in the document from running, with or without telling you. Examine the settings and options in the Trust Center on all Office applications. The default setting disables macro from running, but warns you that macros have been disabled and gives you the option to turn them back on for that document.

You can designate specific folders where macros can run by creating Trusted Locations, Trusted Documents, or Trusted Publishers. The most portable option is to use Trusted Publishers, which works with digitally signed documents that you distribute. For more information about the security settings in a particular Office application, open the Options dialog box, choose Trust Center, and then choose Trust Center Settings.

[!NOTE]
Some Office applications, like Outlook, save macros by default in a master template on your local computer. Although that strategy reduces the local security issues on your own computer when you run your own macros, it requires a deployment strategy if you want to distribute your macro.

Recording a macro

When you choose the Macro button on the Developer tab, it opens the Macros dialog box, which gives you access to VBA subroutines or macros that you can access from a particular document or application. The Visual Basic button opens the Visual Basic Editor, where you create and edit VBA code.

Another button on the Developer tab in Word and Excel is the Record Macro button, which automatically generates VBA code that can reproduce the actions that you perform in the application. Record Macro is a terrific tool that you can use to learn more about VBA. Reading the generated code can give you insight into VBA and provide a stable bridge between your knowledge of Office as a user and your knowledge as a programmer. The only caveat is that the generated code can be confusing because the Macro editor must make some assumptions about your intentions, and those assumptions are not necessarily accurate.

To record a macro

  1. Open Excel to a new Workbook and choose the Developer tab in the ribbon. Choose Record Macro and accept all of the default settings in the Record Macro dialog box, including Macro1 as the name of the macro and This Workbook as the location.

  2. Choose OK to begin recording the macro. Note how the button text changes to Stop Recording. Choose that button the instant you complete the actions that you want to record.

  3. Choose cell B1 and type the programmer’s classic first string: Hello World. Stop typing and look at the Stop Recording button; it is grayed out because Excel is waiting for you to finish typing the value in the cell.

  4. Choose cell B2 to complete the action in cell B1, and then choose Stop Recording.

  5. Choose Macros on the Developer tab, select Macro1 if it is not selected, and then choose Edit to view the code from Macro1 in the Visual Basic Editor.

Figure 2. Macro code in Visual Basic Editor

Macro code in Visual Basic Editor

Looking at the code

The macro that you created should look similar to the following code.

Sub Macro1()
'
' Macro1 Macro
'
'
    Range("B1").Select
    ActiveCell.FormulaR1C1 = "Hello World"
    Range("B2").Select
End Sub

Be aware of the similarities to the earlier code snippet that selected text in cell A1, and the differences. In this code, cell B1 is selected, and then the string «Hello World» is applied to the cell that has been made active. The quotes around the text specify a string value as opposed to a numeric value.

Remember how you chose cell B2 to display the Stop Recording button again? That action shows up as a line of code as well. The macro recorder records every keystroke.

The lines of code that start with an apostrophe and colored green by the editor are comments that explain the code or remind you and other programmers the purpose of the code. VBA ignores any line, or portion of a line, that begins with a single quote. Writing clear and appropriate comments in your code is an important topic, but that discussion is out of the scope of this article. Subsequent references to this code in the article don’t include those four comment lines.

When the macro recorder generates the code, it uses a complex algorithm to determine the methods and the properties that you intended. If you don’t recognize a given property, there are many resources available to help you. For example, in the macro that you recorded, the macro recorder generated code that refers to the FormulaR1C1 property. Not sure what that means?

[!NOTE]
Be aware that Application object is implied in all VBA macros. The code that you recorded works with Application. at the beginning of each line.

Using Developer Help

Select FormulaR1C1 in the recorded macro and press F1. The Help system runs a quick search, determines that the appropriate subjects are in the Excel Developer section of the Excel Help, and lists the FormulaR1C1 property. You can choose the link to read more about the property, but before you do, be aware of the Excel Object Model Reference link near the bottom of the window. Choose the link to view a long list of objects that Excel uses in its object model to describe the Worksheets and their components.

Choose any one of those to see the properties and methods that apply to that particular object, along with cross references to different related options. Many Help entries also have brief code examples that can help you. For example, you can follow the links in the Borders object to see how to set a border in VBA.

Worksheets(1).Range("A1").Borders.LineStyle = xlDouble

Editing the code

The Borders code looks different from the recorded macro. One thing that can be confusing with an object model is that there is more than one way to address any given object, cell A1 in this example.

Sometimes the best way to learn programming is to make minor changes to some working code and see what happens as a result. Try it now. Open Macro1 in the Visual Basic Editor and change the code to the following.

Sub Macro1()
    Worksheets(1).Range("A1").Value = "Wow!"
    Worksheets(1).Range("A1").Borders.LineStyle = xlDouble
End Sub

[!TIP]
Use Copy and Paste as much as possible when working with code to avoid typing errors.

You don’t need to save the code to try it out, so return to the Excel document, choose Macros on the Developer tab, choose Macro1, and then choose Run. Cell A1 now contains the text Wow! and has a double-line border around it.

Figure 3. Results of your first macro

Results of your first macro

You just combined macro recording, reading the object model documentation, and simple programming to make a VBA program that does something. Congratulations!

Did not work? Read on for debugging suggestions in VBA.

Programming tips and tricks

Start with examples

The VBA community is very large; a search on the Web can almost always yield an example of VBA code that does something similar to what you want to do. If you cannot find a good example, try to break the task down into smaller units and search on each of those, or try to think of a more common, but similar problem. Starting with an example can save you hours of time.

That does not mean that free and well-thought-out code is on the Web waiting for you to come along. In fact, some of the code that you find might have bugs or mistakes. The idea is that the examples you find online or in VBA documentation give you a head start. Remember that learning programming requires time and thought. Before you get in a big rush to use another solution to solve your problem, ask yourself whether VBA is the right choice for this problem.

Make a simpler problem

Programming can get complex quickly. It’s critical, especially as a beginner, that you break the problem down to the smallest possible logical units, then write and test each piece in isolation. If you have too much code in front of you and you get confused or muddled, stop and set the problem aside. When you come back to the problem, copy out a small piece of the problem into a new module, solve that piece, get the code working, and test it to ensure that it works. Then move on to the next part.

Bugs and debugging

There are two main types of programming errors: syntax errors, which violate the grammatical rules of the programming language, and run-time errors, which look syntactically correct, but fail when VBA attempts to execute the code.

Although they can be frustrating to fix, syntax errors are easy to catch; the Visual Basic Editor beeps and flashes at you if you type a syntax error in your code.

For example, string values must be surrounded by double quotes in VBA. To find out what happens when you use single quotes instead, return to the Visual Basic Editor and replace the «Wow!» string in the code example with ‘Wow!’ (that is, the word Wow enclosed in single quotes). If you choose the next line, the Visual Basic Editor reacts. The error «Compile error: Expected: expression» is not that helpful, but the line that generates the error turns red to tell you that you have a syntax error in that line and as a result, this program will not run.

Choose OK and change the text back to»Wow!».

Runtime errors are harder to catch because the programming syntax looks correct, but the code fails when VBA tries to execute it.

For example, open the Visual Basic Editor and change the Value property name to ValueX in your Macro, deliberately introducing a runtime error since the Range object does not have a property called ValueX. Go back to the Excel document, open the Macros dialog box and run Macro1 again. You should see a Visual Basic message box that explains the run-time error with the text, «Object doesn’t support this property of method.» Although that text is clear, choose Debug to find out more.

When you return to the Visual Basic Editor, it is in a special debug mode that uses a yellow highlight to show you the line of code that failed. As expected, the line that includes the ValueX property is highlighted.

You can make changes to VBA code that is running, so change ValueX back to Value and choose the little green play button underneath the Debug menu. The program should run normally again.

It’s a good idea to learn how to use the debugger more deliberately for longer, more complex programs. At a minimum, learn a how to set break-points to stop execution at a point where you want to take a look at the code, how to add watches to see the values of different variables and properties as the code runs, and how to step through the code line by line. These options are all available in the Debug menu and serious debugger users typically memorize the accompanying keyboard shortcuts.

Using reference materials well

To open the Developer Reference that is built into Office Help, open the Help reference from any Office application by choosing the question mark in the ribbon or by pressing F1. Then, to the right of the Search button, choose the dropdown arrow to filter the contents. Choose Developer Reference. If you don’t see the table of contents in the left panel, choose the little book icon to open it, and then expand the Object Model Reference from there.

Figure 5. Filtering on developer Help applies to all Office applications

Filtering on developer Help applies to all Office applications

Time spent browsing the Object Model reference pays off. After you understand the basics of VBA syntax and the object model for the Office application that you are working with, you advance from guesswork to methodical programming.

Of course the Microsoft Office Developer Center is an excellent portal for articles, tips, and community information.

Searching forums and groups

All programmers get stuck sometimes, even after reading every reference article they can find and losing sleep at night thinking about different ways to solve a problem. Fortunately, the Internet has fostered a community of developers who help each other solve programming problems.

Any search on the Web for «office developer forum» reveals several discussion groups. You can search on «office development» or a description of your problem to discover forums, blog posts, and articles as well.

If you have done everything that you can to solve a problem, don’t be afraid to post your question to a developers forum. These forums welcome posts from newer programmers and many of the experienced developers are glad to help.

The following are a few points of etiquette to follow when you post to a developer forum:

  • Before you post, look on the site for an FAQ or for guidelines that members want you to follow. Ensure that you post content that is consistent with those guidelines and in the correct section of the forum.

  • Include a clear and complete code sample, and consider editing your code to clarify it for others if it is part of a longer section of code.

  • Describe your problem clearly and concisely, and summarize any steps that you have taken to solve the problem. Take the time to write your post as well as you can, especially if you are flustered or in a hurry. Present the situation in a way that will make sense to readers the first time that they read the problem statement.

  • Be polite and express your appreciation.

Going further with programming

Although this article is short and only scratches the surface of VBA and programming, it is hopefully enough to get you started.

This section briefly discusses a few more key topics.

Variables

In the simple examples in this article you manipulated objects that the application had already created. You might want to create your own objects to store values or references to other objects for temporary use in your application. These are called variables.

To use a variable in VBA, must tell VBA which type of object the variable represents by using the Dim statement. You then set its value and use it to set other variables or properties.

    Dim MyStringVariable As String
    MyStringVariable = "Wow!"
    Worksheets(1).Range("A1").Value = MyStringVariable

Branching and looping

The simple programs in this article execute one line at a time, from the top down. The real power in programming comes from the options that you have to determine which lines of code to execute, based on one or more conditions that you specify. You can extend those capabilities even further when you can repeat an operation many times. For example, the following code extends Macro1.

Sub Macro1()
    If Worksheets(1).Range("A1").Value = "Yes!" Then
        Dim i As Integer
        For i = 2 To 10
            Worksheets(1).Range("A" & i).Value = "OK! " & i
        Next i
    Else
        MsgBox "Put Yes! in cell A1"
    End If
End Sub

Type or paste the code into the Visual Basic Editor and then run it. Follow the directions in the message box that appears and change the text in cell A1 from Wow! to Yes! and run it again to see the power of looping. This code snippet demonstrates variables, branching and looping. Read it carefully after you see it in action and try to determine what happens as each line executes.

All of my Office applications: example code

Here are a few scripts to try; each solves a real-world Office problem.

Create an email in Outlook

Sub MakeMessage()
    Dim OutlookMessage As Outlook.MailItem
    Set OutlookMessage = Application.CreateItem(olMailItem)
    OutlookMessage.Subject = "Hello World!"
    OutlookMessage.Display
    Set OutlookMessage = Nothing
End Sub

Be aware that there are situations in which you might want to automate email in Outlook; you can use templates as well.

Delete empty rows in an Excel worksheet

Sub DeleteEmptyRows()
    SelectedRange = Selection.Rows.Count
    ActiveCell.Offset(0, 0).Select
    For i = 1 To SelectedRange
        If ActiveCell.Value = "" Then
            Selection.EntireRow.Delete
        Else
            ActiveCell.Offset(1, 0).Select
        End If
    Next i
End Sub

Be aware that you can select a column of cells and run this macro to delete all rows in the selected column that have a blank cell.

Delete empty text boxes in PowerPoint

Sub RemoveEmptyTextBoxes()
    Dim SlideObj As Slide
    Dim ShapeObj As Shape
    Dim ShapeIndex As Integer
    For Each SlideObj In ActivePresentation.Slides
        For ShapeIndex = SlideObj.Shapes.Count To 1 Step -1
            Set ShapeObj = SlideObj.Shapes(ShapeIndex)
            If ShapeObj.Type = msoTextBox Then
                If Trim(ShapeObj.TextFrame.TextRange.Text) = "" Then
                    ShapeObj.Delete
                End If
            End If
        Next ShapeIndex
    Next SlideObj
End Sub

Be aware that this code loops through all of the slides and deletes all text boxes that don’t have any text. The count variable decrements instead of increments because each time the code deletes an object, it removes that object from the collection, which reduces the count.

Copy a contact from Outlook to Word

Sub CopyCurrentContact()
   Dim OutlookObj As Object
   Dim InspectorObj As Object
   Dim ItemObj As Object
   Set OutlookObj = CreateObject("Outlook.Application")
   Set InspectorObj = OutlookObj.ActiveInspector
   Set ItemObj = InspectorObj.CurrentItem
   Application.ActiveDocument.Range.InsertAfter (ItemObj.FullName & " from " & ItemObj.CompanyName)
End Sub

Be aware that this code copies the currently open contact in Outlook into the open Word document. This code only works if there is a contact currently open for inspection in Outlook.

[!includeSupport and feedback]

Angry word helper

Возможно, у вас есть ощущение, что тема макросов в Ворде достаточно маргинальная. Кто ими может пользоваться-то вообще? Ну, малварь делают иногда… Да и пишутся они на давно забытом VBA (Visual Basic for Applications, он же несколько урезанный Visual Basic 6 в интерпретируемом виде), фу!

Но на самом деле у многих ведь возникает потребность то какой-нибудь отчётик в ворде написать, то курсовую оформить, то резюме перед отправкой в компанию вашей мечты подправить… А у некоторых работа напрямую связана с Word. Часто различные системы документации предлагают экспорт в форматы doc или docx, которые нужны вашим заказчикам. И бывает, что документы после экспорта выглядят фигово, приходится их исправлять.

Работа в ворде нередко подразумевает выполнение каких-то однообразных повторяющихся действий, которые иногда (но далеко не всегда!) решаются грамотной настройкой стилей и их применением, а также использованием шаблонов. Как же автоматизировать всё остальное? Тут-то нам на помощь приходят те самые макросы.

Что же в них такого хорошего? Ну, например, они автоматически и достаточно быстро выполняют за вас однообразные действия. Могут что-то подсчитать, переформатировать документ, пометить аннотациями подозрительные места, — словом, всё, что запрограммируете. Могут даже в режиме реального времени что-то исправлять и о чем-то предупреждать, пока вы пишете документ. VBA в Word позволяет автоматизировать практически все действия, которые вы можете выполнить с документом вручную.

Макросы можно прикрепить как к конкретному документу (в чём для нас мало пользы, а для писателей троянов это единственная опция), так и к самому ворду, что позволяет применять макросы к любому документу, с которым вы работаете.

Макросы работают в любой версии Word и требуют минимум правок при переносе с одной версии на другую (а чаще всего вообще не требуют). На макросах можно даже реализовать полноценный пользовательский интерфейс с формами!

Давайте же занырнём в Visual Basic и напишем что-нибудь полезное! В качестве первого примера я покажу, как сделать макрос, который заменит два и более последовательных перевода строки на единственный. Это часто требуется при исправлении документов после экспорта из систем документации, или если вы хотите удалить случайно проставленные лишние переводы строк в собственноручно написанном документе. Макрос сделаем добротный, с пользовательским интерфейсом и прогрессом выполнения операции.

Чтобы начать писать или использовать макросы, сначала требуется убедиться, что в Word’е отображается панель «Разработчик» («Developer»). Если она у вас не отображается, следует зайти после создания нового документа в меню «Файл» («File») -> «Параметры» («Options») -> «Настроить ленту» («Customize Ribbon»), после чего найти там и установить флажок «Разработчик» («Developer»).

Enable Word developer tab

После этого нужно зайти на вкладку «Разработчик» и выбрать меню «Visual Basic».

Word Visual Basic button

В открывшемся окне слева вы увидите два проекта: «Normal» и проект, относящийся к текущему открытому документу. Возможно, в проекте «Normal» у вас уже будет какой-то файл в каталоге «Modules». В любом случае, создайте новый модуль, кликнув правой кнопкой по проекту «Normal» и выбрав «Insert» -> «Module».

Word insert new module

Созданный модуль представляет из себя файл, куда мы и будем писать код макросов. Можно переименовать модуль (по умолчанию его имя будет «Module1») в окне «Properties» -> «Name». Я назову свой модуль «AllMacros». Теперь откроем код модуля, дважды кликнув по его имени, и приступим к созданию макроса. Напомню, что наша цель — заменить два и более последовательных перевода строки на единственный, произведя замены по всему документу. Очевидно, нам потребуется функция, которая осуществляет поиск по тексту, ведь мы хотим найти несколько последовательных переводов строки. В Word это эквивалентно началу нового параграфа. Вы могли бы осуществить поиск начала нового параграфа через обычное окно поиска, введя в поле поиска ^p, ^13 или ^013 (что соответствует ASCII-коду перевода строки). Функция поиска будет выглядеть так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

Private Function FindNextText(text As String, useWildcards As Boolean)

    Selection.Find.ClearFormatting

    Selection.Find.Replacement.ClearFormatting

    With Selection.Find

        .Text = text

        .Forward = True

        .Format = False

        .MatchCase = False

        .MatchWholeWord = False

        .MatchKashida = False

        .MatchDiacritics = False

        .MatchAlefHamza = False

        .MatchControl = False

        .MatchWildcards = useWildcards

        .MatchSoundsLike = False

        .MatchAllWordForms = False

        .Wrap = wdFindStop

    End With

    Selection.Find.Execute

    FindNextText = Selection.Find.Found

End Function

Давайте разберём, что тут происходит. Мы объявляем функцию с двумя параметрами. Первый имеет тип String — это текст для поиска, а второй Boolean говорит о том, нужно ли использовать символы подстановки (wildcards). Про них я поговорю позже. В следующих двух строках 2 и 3 мы очищаем форматирование для строки поиска и строки замены, если оно было задано пользователем. Word позволяет задать форматирование строки поиска/замены, а для нашей задачи это не требуется. Далее мы задаём набор параметров для объекта Selection.Find: выставляем неинтересные нам параметры в False, параметр Text — это текст, который мы хотим найти, а параметр MatchWildcards указывает на использование символов подстановки. Параметр Wrap говорит о том, следует ли продолжать поиск, когда мы дошли до той точки, с которой поиск начали, и у нас его значение установлено в wdFindStop, так как мы хотим остановиться, когда дойдём до конца документа, и не зацикливать поиск.

Вообще, всё это обилие свойств и объектов из объектной модели Word, Excel и PowerPoint (да, там тоже есть макросы) хорошо описано в MSDN. Например, вот тут перечислены свойства и методы объекта Find. Есть русская документация (скажем, эта страница), но она выполнена совершенно кринжовым машинным переводом, невозможно читать:

Есть совершенно смехотворные страницы:

В общем, лучше читайте на английском. :D

Кроме того, все доступные объекты, их свойства и методы можно посмотреть прямо в редакторе VBA в самом Word’е. Для этого нужно нажать F2 или выбрать меню «View» -> «Object browser», что приведет к открытию браузера объектов (Object browser), в котором можно пролистать или поискать то, что вам доступно.

Word object browser

Но вернёмся к нашей функции. На строке 19 мы непосредственно выполняем поиск заданного текста с указанными параметрами. Строка 20 — эта конструкция, аналогичная return в си-подобных языках, указывает возвращаемое значение функции. Мы возвращаем булевое значение Selection.Find.Found, которое говорит о том, было ли что-то найдено.

Хочу заметить, что использование объекта Selection.Find и изменение его свойств заменит их значения и для пользователя. Например, если вы в Word искали что-то хитроумное с конкретно заданными параметрами, то выполнение макроса заменит ваши параметры поиска на те, которые мы задали в макросе. В идеале, их можно запомнить, а потом вернуть, но мы не будем так сильно заморачиваться, а просто всё за собой подчистим. Сделаем функцию, которая сбрасывает параметры в значения по умолчанию:

Private Sub ClearFindAndReplaceParameters()

    With Selection.Find

       .ClearFormatting

       .Replacement.ClearFormatting

       .Text = «»

       .Replacement.Text = «»

       .Forward = True

       .Wrap = wdFindStop

       .Format = False

       .MatchCase = False

       .MatchWholeWord = False

       .MatchWildcards = False

       .MatchSoundsLike = False

       .MatchAllWordForms = False

    End With

End Sub

Обратите внимание, что это уже Sub, а не Function, потому что мы не хотим из этой процедуры возвращать никакое значение. Это аналог функции void в си-подобных языках.

Теперь нужно определить, как нам найти два или более последовательных перевода строки. Для этого нам и потребуются упомянутые ранее wildcards. Word поддерживает символы подстановки при поиске, и по своей функциональности они напоминают регулярные выражения. Кстати, вы можете ими пользоваться и без макросов из окна расширенного поиска:

Word wildcards

Хорошее описание символов подстановки я нашел здесь, правда, на английском языке. Составим регулярное выражение для поиска двух и более последовательных переводов строки: [^013]{2,}. Это очень похоже на классическое регулярное выражение Perl или PCRE, но в квадратных скобках в уникальном стиле Word мы задаем символ перевода строки. Фигурные скобки указывают, что символов перевода подряд должно быть два или более. Тут, кстати, есть нюанс: не во всех версиях/локализациях Word такая регулярка заработает. В некоторых случаях вместо запятой потребуется указать точку с запятой (да, в Microsoft иногда делают крайне странные вещи). Чтобы сделать наш макрос более универсальным, напишем функцию, которая вернёт регулярное выражение, пригодное для поиска в той версии Word, в которой эту функцию запустили:

Private Function GetLineBreakSearchRegExp()

    On Error GoTo Err

    FindNextText «[^013]{2,}», True

    GetLineBreakSearchRegExp = «[^013]{2,}»

    Exit Function

Err:

    GetLineBreakSearchRegExp = «[^013]{2;}»

End Function

Здесь мы сначала пытаемся осуществить поиск с помощью wildcard’а [^013]{2,}. Если всё окей, то вернём из функции этот самый wildcard как рабочий (строка 4). В противном случае произойдёт ошибка, но мы готовы её обработать: мы установили обработчик всех ошибок в строке 2. Нас перекинет на метку Err, и тут мы вернём wildcard, который пригоден для других ревизий Word (в котором запятая внутри фигурных скобок заменена на точку с запятой).

Далее напишем функцию, которая будет заменять несколько последовательных переводов строки на единственный:

Private Sub RemoveNextEnters()

    Selection.MoveStart wdWord, 1

    If Selection.Range.Start <> Selection.Range.End Then Selection.Delete

End Sub

Эта функция подразумевает, что вызывать её будут тогда, когда объект Selection указывает на найденные несколько переводов строки. В строке 2 перемещаем начало выделения (а в выделены у нас будут все найденные последовательные переводы строки) на один символ вперед, а затем в строке 3, если начало выделения не совпадает с его концом, удаляем его содержимое. Таким образом, если было выделено три перевода строки, мы отступаем вперед на 1 символ (оставляя один перевод строки нетронутым), а затем удаляем оставшиеся два.

Осталось написать последнюю функцию, которая будет всем управлять.

Sub RemoveExcessiveEnters()

    Dim lineBreakSearchRegExp As String

    lineBreakSearchRegExp = GetLineBreakSearchRegExp()

    Selection.HomeKey Unit:=wdStory

    While FindNextText(lineBreakSearchRegExp, True) = True

        RemoveNextEnters

    Wend

    ClearFindAndReplaceParameters

End Sub

Здесь мы оперируем ранее написанными функциями. Сначала получаем текст регулярного выражения (wildcard’а) для поиска нескольких переводов строки подряд, затем вызовом HomeKey в строке 5 переходим в самое начало документа (перемещаем туда курсор), а затем в цикле ищем все интересующие нас места и удаляем излишние переводы строки. В конце сбрасываем параметры поиска на значения по умолчанию.

Finished word macro

Вот и всё, макрос можно запускать! Обратите внимание, что все функции, кроме последней, мы пометили Private. Мы не хотим, чтобы их вызывали напрямую. Доступной для вызова снаружи будет только функция RemoveExcessiveEnters. Перед запуском макроса стоит убедиться, что макросы включены. Если вылазит такая панель, то нужно нажать «Включить содержимое» («Enable content»):

Word enable content

Если такой панели нет, то можно зайти в меню «Файл» («File») -> «Сведения» («Info») и включить макросы уже оттуда:

Word enable content from info menu

Вы можете включить макросы на время одного сеанса Word (это по умолчанию и происходит, если нажимаете «Включить содержимое»), так что после перезапуска Word макросы снова будут отключены. Для запуска макроса возвращаемся в Word на панель «Разработчик» и нажимаем кнопку «Макросы» («Macros»), выбираем наш макрос RemoveExcessiveEnters и нажимаем «Выполнить» («Run»). Разумеется, у вас должен быть открыт какой-нибудь подопытный документ, где имеются лишние переводы строк. В качестве бонуса наш макрос ещё и удалит пустые элементы списков, потому что они представляют из себя точно такие же несколько переводов строки подряд.

Word macro: before and after

Макрос выполняется достаточно быстро. Его действие можно отменить (каждый шаг независимо), открыв меню выполненных действий:

Undo Word macro

Макросы можно отлаживать через окно VBA, в котором мы писали макрос. Кликнув слева от строки кода, можно, как и в других средах разработки, поставить точку останова, а потом запустить макрос кнопкой «Run». Запустится та функция, на которой у вас находится курсор. Если вы поставите курсор на функцию с параметрами, то появится обычный запрос на выбор макроса для запуска, как при нажатии на кнопку «Макросы» в Word.

Debug Word macros

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

Код макроса можно скачать тут. Вы сможете его импортировать к себе в Word, кликнув правой кнопкой на «Normal» -> «Import file…» и выбрав загруженный файл.

P.S. Кстати, рекомендую создавать бэкапы своих макросов, экспортируя их куда-нибудь на диск. Даже лицензионный Word имеет свойство их иногда по какой-то причине удалять из шаблона Normal, в котором мы их создавали.

Like this post? Please share to your friends:
  • Vba excel цикл по датам
  • Vba excel цикл по всем строкам
  • Vba excel цикл до последней строки
  • Vba excel цикл в обратном порядке
  • Vba excel цикл with