VBA в MS Office 2007

Практические примеры программирования для MS Word

Показывать лекцию целиком

12.1. Групповая обработка файлов

12-01-Групповая обработка файлов.docm - пример к п. 12.1.

12.1.1. Условие

Предположим, у вас есть несколько сотен файлов в формате .docx и . docm. Например, с ними вы работали дома. Очевидно, что дома у вас установлен Office 2007. И вот, приходит время перенести эти материалы на рабочий компьютер. Вы обнаруживаете, что MS Office на рабочем месте так и не обновили, а на вопросы об обновлении отвечают неопределенно. К тому же, некоторые из ваших документов предназначаются для других пользователей с устаревшими версиями Office - поэтому локальная самостоятельная установка конвертера на вашем ПК проблему не решает. А раз так - у вас есть два пути. Первый - заниматься конверсией файлов в формат .doc вручную, и второй - поручить это дело Microsoft Word.

12.1.2. Решение

Добавим в Microsoft Word кнопку, обработчик нажатия которой содержит следующий код (листинг 12.1)

'Переменная для имени очередного файла
    Dim var_Doc As Variant
    'Для хранения ссылки на открытый файл
    Dim obj_File As Document
    'Для формирования нового имени файла
    Dim str_FileName As String
    'Для подсчета количества обработанных файлов
    Dim var_FileCount
    'Для хранения пути к папке с исходными файлами
    Dim str_In As String
    'Папка с выходными файлами
    Dim str_Out As String
    'Инициализируем переменные
    str_In = "C:\Документы"
    str_Out = "C:\Документы\Обработано"
    'Изменяем текущую директорию на заданную
    ChDir (str_In)
    'Ищем первый файл в директории
    var_Doc = Dir("*.doc?")
    Do While var_Doc <> "" 'До тех пор, пока есть файлы
        'Открываем найденный файл в невидимом окне
        Set obj_File = _
        Documents.Open( _
        FileName:=str_In + "\" + var_Doc, _
        Visible:=False)
        'Формируем имя нового файла
        str_FileName = str_Out + "\" + _
        Mid(var_Doc, 1, Len(var_Doc) - 4) + _
        "doc"
        'Сохраняем файл в формате Word 97-2003
        obj_File.SaveAs FileName:=str_FileName, _
        FileFormat:=wdFormatDocument97
        'Закрываем файл
        obj_File.Close
        'Увеличиваем на 1 счетчик файлов
        var_FileCount = var_FileCount + 1
        'Находим следующий подходящий файл в папке
        var_Doc = Dir()
    Loop
    MsgBox ("Обработано" + Str(var_FileCount) + " файлов")

Как видите, алгоритм работы программы выглядит так:

  • Найти файл
  • Открыть его
  • Сохранить в новом формате
  • Закрыть
  • Эти шаги повторяются для каждого из файлов. Конструкции, использованные при решении этой задачи, мы рассматривали выше, поэтому у вас не должно возникнуть сложностей при разборе кода. Обратите внимание на то, что директории, пути к которым использованы в программе, должны быть созданы до ее запуска.

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

    12.2. Копирование материалов нескольких документов в один

    12-02-Копирование текстов.docm - пример к п. 12.2.

    12.2.1. Условие

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

    12.2.2. Решение

    Для решения этой задачи напишем макрос, который должен храниться в глобальном шаблоне. При запуске макроса будет создаваться новый документ, в который будут скопированы материалы всех остальных открытых документов. Эту операцию можно реализовать множеством способов, мы избрали копирование материалов через буфер обмена Windows (листинг 12.2.)

    'Переменная для хранения ссылки на
        'целевой документ
        Dim obj_TargetD As Document
        'Для хранения ссылки на очередной
        'обрабатываемый документ
        Dim obj_CurDoc As Document
        Set obj_TargetD = Documents.Add
        For Each obj_CurDoc In Documents
            If obj_CurDoc.Name <> _
            obj_TargetD.Name Then
                'Выделяем содержимое очередного документа
                obj_CurDoc.Content.Select
                'Копируем в буфер обмена
                Selection.Copy
                'Активируем целевой документ
                obj_TargetD.Activate
                'Вставляем в текущую позицию курсора
                'материалы из буфера обмена
                Selection.Paste
            End If
        Next

    Здесь мы создаем новый документ, в который копируем содержимое остальных открытых документов. Цикл обхода всех объектов коллекции Documents, то есть открытых документов, позволяет получить доступ к каждому открытому документу. Однако, здесь не обойтись без проверки - мы должны обработать все открытые документы кроме того, в который копируем данные. Для этого прежде чем начать обработку, сравниваем имя целевого и текущего документа.

    12.3. Разбиение одного документа на несколько

    12-03-Разбиение документа.docm - пример к п. 12.3.

    12.3.1. Условие

    Задача, противоположная предыдущей. Один открытый документ нужно разбить на несколько, руководствуясь каким-либо признаком, после чего сохранить все документы, дав им соответствующие имена, в папку, заданную пользователем.

    Разобъем активный документ на части, по 10 абзацев каждая, и сохраним каждую из частей в отдельном документе с именем такого вида:

    Имя исходного документа+ "часть №"+номер части.docx

    12.3.2. Решение

    Напишем макрос (листинг 12.3.), который имеет смысл хранить в глобальном шаблоне. Этот макрос будет работать с активным документом.

    'Переменная для хранения ссылки на
        'активный документ
        Dim obj_Doc As Document
        'Для ссылки на новый документ
        Dim obj_NewDoc As Document
        'Ссылка на абзац документа
        Dim obj_Par As Paragraph
        'Строка для хранения пути сохранения
        'файлов
        Dim var_Path As String
        'Счетчик для подсчета обработанных
        'абзацев
        Dim var_Counter
        'Переменная для сборки имен
        'новых файлов
        Dim var_FileName As String
        'Переменная для хранения номера
        'очередного файла, который используется
        'при создании имени файла
        Dim var_Part
        'Записываем 0 в счетчики количества
        'абзацев и файлов и инициализируем
        'другие переменные
        var_Counter = 0
        var_Part = 0
        Set obj_Doc = ActiveDocument
        var_Path = "C:\Документы"
        'Цикл для каждого абзаца в документе
        For Each obj_Par In obj_Doc.Paragraphs
            'Если в предыдущем сеансе обработано
            '10 абзацев - создается новый файл
            'для записи в него очередных 10
            If var_Counter = 0 Then
                Set obj_NewDoc = Documents.Add
                'Это - номер файла, который будет
                'отражен в его имени
                var_Part = var_Part + 1
            End If
            'Увеличиваем на 1 счетчик обработанных
            'абзацев
            var_Counter = var_Counter + 1
            'Активируем новый документ
            obj_NewDoc.Activate
            'Добавляем в него текст текущего абзаца
            'из исходного документа
            Selection.TypeText (obj_Par.Range.Text)
            'Если обработано 10 абзацев
            If var_Counter = 10 Then
                'Сбрасываем счетчик обработанных абзацев
                var_Counter = 0
                'Собираем имя нового файла
                var_FileName = var_Path + "\" + _
                obj_Doc.Name + _
                " часть № " + Str(var_Part) + ".docx"
                'Сохраняем новый файл
                obj_NewDoc.SaveAs FileName:=var_FileName
                'Закрываем его
                obj_NewDoc.Close
                'Очищаем объектную переменную
                Set obj_NewDoc = Nothing
            End If
        Next
        'Если в объектной переменной, представляющей
        'новый файл, хранится ссылка
        'это значит, что исходный файл имеет
        'количество абзацев, не кратное 10,
        'то есть он не будет сохранен в основном цикле
        'сохраняем этот файл
        If obj_NewDoc Is Nothing = False Then
            var_FileName = var_Path + "\" + _
            obj_Doc.Name + _
            " часть № " + Str(var_Part) + ".docx"
            obj_NewDoc.SaveAs FileName:=var_FileName
            obj_NewDoc.Close
            Set obj_NewDoc = Nothing
        End If
        'Выводим сообщение об окончании работы
        MsgBox ("Файл " + obj_Doc.Name + _
        " обработан, получено " + _
        Str(var_Part) + " файлов, которые" + _
        " хранятся в: " + var_Path)

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

    12.4. Точная замена

    12-04-Точная замена.docm - пример к п. 12.4.

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

    12.4.1. Условие

    Написать программу на VBA, которая позволяла бы автоматизировать процесс замены одних комбинаций символов другими. В частности, предусмотреть выбор среди следующих объектов замены: заменить букву е на ё, удалить двойные пробелы, заменить обычное тире на длинное. Предусмотреть возможность задавать один из объектов пользователем.

    12.4.2. Решение

    Создадим пользовательскую форму (рис. 12.1.).

    (рис 12.1) Форма для настройки замены символов

    Основные элементы управления, которые мы используем, это следующие флажки (табл. 12.1.).

    Основные элементы управления
    Имя элемента управления Подпись
    chk_Space Заменить двойные пробелы на одинарные
    chk_Yo Заменить букву е на ё
    chk_LongDash Заменить обычные тире на длинные
    chk_User Пользовательская замена
    cmd_OK ОК

    Если выбран флажок chk_User - активируются два текстовых поля ( txt_One и txt_Two ). Их свойства Enabled первоначально установлены в False, при выборе флажка оно устанавливается в True, при снятии - обратно в False. В поле txt_One пользователь может записать последовательность символов, которую нужно заменить на последовательность, которую он может ввести в txt_Two.

    Ниже приведен код пользовательских процедур и обработчиков событий элементов управления, которые реализуют вышеописанную функциональность. Листинг 12.4. содержит код обработки события Change для chk_User.Листинг 12.5. представляет собой код, который выполняется при нажатии на кнопку ОК, которая запускает процесс замен. Листинг 12.6. содержит код процедуры, которая вызывает стандартное средство для замены.

    Private Sub chk_User_Change()
    'Выполняется при изменении состояния
    'флажка chk_User
        If chk_User = True Then
        'Если флажок установлен     'активировать поля
            txt_One.Enabled = True
            txt_Two.Enabled = True
        Else
        'Если флажок снят     'заблокировать поля
            txt_One.Enabled = False
            txt_Two.Enabled = False
        End If
    End Sub
    Private Sub cmd_Ok_Click()
    'Обработчик нажатия кнопки
    'Проверяем, установлен ли каждый
    'из флажков и в зависимости от этого
    'выполняем вызов пользовательской процедуры
    'которая содержит код вызова средства
    'Найти и заменить
        If chk_Space = True Then
            Call ReplaceThis("  ", " ")
        End If
        If chk_Yo = True Then
            Call ReplaceThis("е", "е")
        End If
        If chk_LongDash = True Then
            Call ReplaceThis("-", "-")
        End If
        If chk_User = True Then
            Call ReplaceThis(txt_One, txt_Two)
        End If
    End Sub
    Public Sub ReplaceThis(str_1, str_2 As String)
    'Пользовательская процедура
    'Принимает два параметра
    'str_1 - это символ, который надо заменить
    'str_2 - символ, на который надо заменить
        'Поиск и замена во всем документе
        ActiveDocument.Content. _
        Find.Execute _
        FindText:=str_1, ReplaceWith:=str_2, _
        Replace:=wdReplaceAll
    End Sub

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

    12.5. Проверка правильности создания документа

    12-05-Проверка правильности.docm - пример к п. 12.5.

    Этот пример будет посвящен использованию стилей при программной обработке документов. Стиль - это набор правил форматирования документа, имеющий имя.

    12.5.1. Условие

    Предположим, что в нашем документе используется стиль с именем PicLink для форматирования ссылки на изображение в тексте, и стиль PicName - для самого имени изображения. Изображение должно следовать в документе сразу после его упоминания в тексте. Нужно написать программу, которая проверяет номера изображений, упомянутых в тексте и номера иллюстраций и составляет после проверки отчет о соответствии ссылок на иллюстрации их реальным номерам. Для нумерования иллюстраций используется конструкция такого вида: "Рис. X".

    12.5.2. Решение

    Для начала создадим два стиля. Один назовем PicLink, второй - PicName. Для создания стиля отформатируйте какой-нибудь участок документа так, как нужно, после чего выделите его, щелкните по выделению правой кнопкой мыши и выберите в появившемся меню пункт Стили o Сохранить выделенный фрагмент как новый экспресс-стиль. Появится окно для настройки свойств стиля, разверните его кнопкой Изменить (рис. 12.2.). Задайте имя стиля, место сохранения, в поле Стиль выберите Знака, и нажмите кнопку OK.

    (рис 12.2) Создание стиля

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

    'Для хранения ссылки на символ
        Dim obj_Char As Range
        'Для хранения текста ссылки на
        'изображение
        Dim str_PicLink As String
        'Для хранения текста названия
        'изображения
        Dim str_PicName As String
        'Для хранения текста отчета
        Dim str_ResultText
        'Счетчик иллюстраций
        Dim num_Counter
        'Ссылка на документ с отчетом
        Dim obj_Doc As Document
        'Для каждого символа в документе
        For Each obj_Char In ActiveDocument.Characters
            'Если стиль символа - PicLink
            'и символ является цифрой, точкой или
            'косой чертой - добавляем символ
            'в переменную
            If obj_Char.Style = "PicLink" Then
                If Asc(obj_Char.Text) >= 46 And _
                    Asc(obj_Char.Text) <= 57 Then
                        str_PicLink = str_PicLink + _
                        obj_Char.Text
                End If
            End If
            'Аналогично - для стиля PicName
            If obj_Char.Style = "PicName" Then
                If Asc(obj_Char.Text) >= 46 And _
                    Asc(obj_Char.Text) <= 57 Then
                        str_PicName = str_PicName + _
                        obj_Char.Text
                End If
            End If
            'Если стиль - не PicLink и не PicName
            'и переменные, хранящие симолы, взятые
            'из ссылки на рисунок и названия, не
            'пусты - проверяем, одинаковы ли эти
            'символы и формируем строку для
            'последующего вывода в файл отчета
            If obj_Char.Style <> "PicLink" And _
                obj_Char.Style <> "PicName" And _
                Len(str_PicLink) > 0 And _
                Len(str_PicName) > 0 Then
                    'Увеличим на 1 счетчик изображений
                    num_Counter = num_Counter + 1
                    If str_PicLink = str_PicName Then
                        str_ResultText = str_ResultText + _
                        "Иллюстрация №" + Str(num_Counter) + _
                        " " + str_PicLink + " верно" + _
                        " пронумерована" + Chr(13)
                    Else
                        str_ResultText = str_ResultText + _
                        "Внимание! Иллюстрация №" + _
                        Str(num_Counter) + _
                        " " + str_PicLink + " неверно" + _
                        " пронумерована" + Chr(13)
                    End If
                    'Сбросим переменные для хранения
                    'новой информации
                    str_PicLink = ""
                    str_PicName = ""
            End If
        Next
        'сформируем файл отчета
        Set obj_Doc = Documents.Add
        obj_Doc.Activate
        Selection.TypeText str_ResultText

    12.6. Заключение

    Мы рассмотрели множество вопросов программирования для Microsoft Word. Теперь вы сможете сделать с помощью этого редактора много полезного.

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

    Вернуться к учебному плану