Макросы Марка Розенберга

Домашняя страница > Обработка графики в VBA

Обработка графики в Microsoft Word средствами VBA


Предварительные сведения об объектах Shape и InlineShape

Расположение в документе

Преобразование InlineShapeShape

Встроенные и перемещаемые объекты

Преобразование встроенный — перемещаемый

Ограничения для средств пользовательского интерфейса

Перебор графических объектов в Microsoft Word средствами VBA

Применение свойства Shapes

Применение свойства ShapeRange

Применение свойства InlineShapes

Перебор объектов InlineShapes

Перебор объектов Shapes..

Перебор вложенных объектов Shapes и InlineShape

Обработка графики в программе EachShape

Краткое описание алгоритма программы Each Shape

Практические аспекты обработки графики

Загрузите документ

В файле GraphProc.rar (131 550 байт) сжат документ GraphProc02.doc (465 408 байт) с текстом этой страницы и VBA-модулями с приведенными здесь макросами.

Содержащимися на этой странице материалами можно свободно пользоваться, ссылаясь на нее.

В загружаемом документе GraphProc.rar помимо текста данной страницы содержатся макросы. Макросы к разделу Перебор графических объектов в Microsoft Word средствами VBA находятся в модуле Example, а к разделу Обработка графики в программе EachShape — в модуле Each_shape и в форме frmEachShape.

Предварительные сведения об объектах Shape и InlineShape

Графические объекты, используемые в документах Microsoft Word, в объектных библиотеках представлены классами Shape и InlineShape. Способ обработки графических объектов средствами VBA существенно зависит от того, к какому классу принадлежит объект. В этом разделе приведены основные особенности объектов, относящихся к каждому из этих классов.

Расположение в документе

Объекты Shape могут находиться только в основном тексте документа и в колонтитулах, а объекты InlineShape можно разместить также в сносках (включая продолжения сносок и уведомления о продолжении сносок), примечаниях и почти всегда в тексте, содержащемся в объектах Shape.

Любой объект Shape, кроме канвы (объекта типа msoCanvas), можно разместить также на канве, а любые объекты, кроме канвы и группы (объекта типа msoGroup), могут входить в состав группы.

Преобразование InlineShapeShape

Если объект InlineShape находится в таком месте, где могут находиться объекты Shapе, его можно обратимо преобразовать в соответствующий объект Shape. К объектам InlineShape относятся OLE-объекты (объекты, вставленные из других приложений), рисунки, горизонтальные линии, рисованные маркеры для маркированных списков, объекты WordArt и SmartArt. В то же время такие объекты Shape, как канва, группа, надпись и автофигура, преобразовать в объект InlineShape нельзя.

Встроенные и перемещаемые объекты

Все объекты InlineShape являются встроенными (in line), то есть расположенными в тексте аналогично символам и перемещаемыми вместе с текстом.

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

Преобразование встроенный — перемещаемый

Если перемещаемый объект Shape не находится на канве и не входит в группу, его можно преобразовать во встроенный объект. Если же он относится к тому типу объектов, которые могут быть преобразованы в объект InlineShape, то в ряде случаев при преобразовании перемещаемого объекта Shape во встроенный объект незаметно для пользователя автоматически происходит его преобразование в объект InlineShape (это зависит не только от типа объекта и его состояния, но и от версии Microsoft Word).

Ограничения для средств пользовательского интерфейса

При работе с графическими объектами средствами пользовательского интерфейса Microsoft Word нет никакой разницы между встроенным объектом Shape и полученным из него объектом InlineShape. Наверное, поэтому ни в пользовательском интерфейсе Microsoft Word, ни в справочной документации ничего не говорится о разделении на объекты Shape и InlineShape. Однако и тем пользователям, которые не прибегают к программированию, не помешало бы знать, что такой объект, как канва, группа, надпись или автофигура, можно разместить только в основном тексте документа и в колонтитулах, а в остальных частях документа можно размещать только встроенные объекты. Эти два условия ограничивают возможности преобразования встроенных объектов в перемещаемые и копирования перемещаемых объектов в другие части документа.

Перебор графических объектов в Microsoft Word средствами VBA

Графические объекты представляются в VBA с помощью двух классов: Shape и InlineShape.

Примечание. Есть еще класс объектов Frame, представляющих рамки. Рамки широко использовались в версиях, предшествовавших Microsoft Word 97, где еще не было надписей, а в последующих версиях их рекомендуется использовать вместо надписей для текста и объектов InlineShape, содержащих примечания, сноски или некоторые поля. Рамка выглядят почти также, как надпись, и выполняет похожие функции, но является элементом стилевого форматирования, а не графическим объектом. Текст рамки содержится в начале абзаца, к которому относится надпись. Создать рамку в современных версиях Microsoft Word можно только преобразованием из надписи. После этого ее можно скопировать в любое место документа, которое может быть оформлено стилем.

Для перебора объектов Shape и InlineShape можно использовать следующие содержащие их коллекции:

 

Объект

Коллекция

Shape

Shapes

ShapeRange

InlineShape

InlineShapes

 

Доступ к этим коллекциям можно получить с помощью свойств других объектов-контейнеров:

 

Объект

Коллекция

Объект-контейнер

Свойство объекта-контейнера

Shape

Shapes

Document

Shapes

 

HeaderFooter

ShapeRange

Range

ShapeRange

 

Selection

InlineShape

InlineShapes

Document

InlineShapes

 

Range

Selection

 

Применение свойства Shapes

Объекты Shape могут находиться в основном тексте и в колонтитулах документа.

Когда свойство Shapes применяется к объекту Document, оно возвращает все объекты Shapes, расположенные  в основном тексте документа. Объекты Shapes, содержащиеся в колонтитулах, пропускаются.

Когда свойство Shapes применяется к любому из объектов HeaderFooter, оно возвращает все объекты, находящиеся во всех колонтитулах документа. Описание для примера, приведенного в справке VBA, ошибочно.

 

The Shapes property, when applied to a document, returns all the Shapes objects in the main story of the document, excluding the headers and footers. When applied to a HeaderFooter object, the Shapes property returns all the Shapes objects found in all the headers and footers in the document

Example

This example displays a count of all the shapes in the primary all header and footer of the first section of the active document.

Visual Basic for Applications

MsgBox ActiveDocument.Sections(1). _

    Headers(wdHeaderFooterPrimary).Shapes.Count

В приведенном примере выводится количество объектов Shape, содержащихся во всех колонтитулах активного документа, а не только в основных колонтитулах первого раздела.

К моему удивлению, обнаружилось (в Microsoft Word 2003, в 2007 не проверял), что после обращения к свойству Shapes свойство Saved соответствующего документа принимает значение False. Это означает, что при закрытии документа последует запрос о его сохранении.

Применение свойства ShapeRange

к объекту Range

Returns a ShapeRange collection that represents all the Shape objects in the specified range

Когда свойство ShapeRange применяется к объекту Range, оно возвращает все объекты Shape, относящиеся к диапазону, представленному этим объектом Range.

К сожалению, в версии Microsoft Word 2003 при обращении к свойству ShapeRange, когда в диапазоне <range evaluation> объектов Shape нет, может появиться сообщение об ошибке "Requested object is not available".

Из-за этого использовать свойство ShapeRange в версии Microsoft Word 2003 не получается.

к объекту Selection

Returns a ShapeRange collection that represents all the Shape objects in the selection

Когда свойство ShapeRange применяется к объекту Selection, оно возвращает все выделенные объекты Shape, а не те объекты, которые относятся к выделенному диапазону, как можно было предположить по аналогии с применением этого свойства к объекту Range. Догадаться об этом из справки VBA невозможно.

К сожалению, в версии Microsoft Word 2003 цикл For Each по коллекции Selection.ShapeRange, когда нет выделенных объектов, приводит к ошибке "Out of memory". Прежде чем его применять, проверьте значение Selection.ShapeRange.Count.

Применение свойства InlineShapes

к объекту Selection

Returns an InlineShapes collection that represents all the InlineShape objects in a selection

Когда свойство InlineShapes применяется к объекту Selection, оно возвращает коллекцию InlineShapes, представляющую все объекты InlineShape, относящиеся к выделенному диапазону, представленному этим объектом Selection.

к объекту Range

Returns an InlineShapes collection that represents all the InlineShape objects in a range.

Когда свойство InlineShapes применяется к объекту Range, оно возвращает коллекцию InlineShapes, представляющую все объекты InlineShape, относящиеся к диапазону, представленному этим объектом Range.

к объекту Document

Returns an InlineShapes collection that represents all the InlineShape objects in a document.

Когда свойство InlineShapes применяется к объекту Document, оно возвращает коллекцию InlineShapes, представляющую все объекты InlineShape, находящиеся в основном тексте документа, представленного этим объектом Document.

Перебор объектов InlineShapes

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

Объекты InlineShapes могут находиться в любой цепочке (story) документа (в основном тексте, надписях, колонтитулах, примечаниях и сносках), а также в надписях, содержащихся в объектах Shapes, расположенных в колонтитулах.

Для перебора цепочек удобнее всего использовать двойной цикл, который я впервые увидел в программе Replace text on a batch of files на странице http://www.gmayor.com/batch_replace.htm сайта Graham Mayor.

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

 

Sub Example1()

'Пример: перебор цепочек в документе

'Вычисление количества цепочек

 

  Dim intStoryCount 'Счетчик цепочек

  Dim rngStory As Range 'range для цепочки в цикле

 

  intStoryCount = 0

   

  'Цикл по каждому типу цепочек активного документа

  For Each rngStory In ActiveDocument.StoryRanges

    'цикл по всем цепочкам одинакового типа

    Do 'в диапазоне цепочки rngStory на каждой итерации

       

      intStoryCount = intStoryCount + 1

     

      'переход к следующей цепочке rngStory того же типа

      Set rngStory = rngStory.NextStoryRange

    Loop Until rngStory Is Nothing

  Next rngStory

  MsgBox "Всего цепочек: " & intStoryCount, vbInformation _

          , "Перебор всех цепочек"

End Sub

 

Чтобы пересчитать все объекты InlineSpape в каждой цепочке, т. е. в диапазоне, представленном переменной rngStory, можно выполнить перебор по всем элементам коллекции rngStory.InlineSpapes:

Для этого в теле цикла заменим инструкцию счета цепочек циклом по коллекции InlineSpapes, в котором считается количество объектов InlineSpape:

 

Sub Example2()

'Пример: перебор объектов InlineShape в цепочках документа

'Вычисляется число объектов InlineShape в цепочках документа

'Объекты InlineShape в надписях, расположенных в колонтитулах,

'не учитываются, поскольку не содержатся в цепочках

 

  Dim intInlShpCount As Integer 'Счетчик InlineStory

  Dim rngStory As Range 'range для текущей цепочки в цикле

  Dim inlShape As InlineShape 'текущий объект InlineShape в цикле

 

  intInlShpCount = 0

   

  'Цикл по каждому типу цепочек активного документа

  For Each rngStory In ActiveDocument.StoryRanges

    'цикл по всем цепочкам одинакового типа

    Do

      'в диапазоне цепочки rngStory на каждой итерации

        For Each inlShape In rngStory.InlineShapes

          intInlShpCount = intInlShpCount + 1

        Next inlShape

     

      'переход к следующей цепочке rngStory того же типа

      Set rngStory = rngStory.NextStoryRange

    Loop Until rngStory Is Nothing

  Next rngStory

  MsgBox "Всего в цепочках объектов InlineShape: " & intInlShpCount, vbInformation _

          , "Перебор объектов InlineShape во всех цепочках"

End Sub

 

Обратите внимание, что объекты InlineShape, расположенные в тексте, находящемся в объектах Shape (в надписях и в автофигурах, к которым добавлены надписи), учитываются только в основном тексте документа. В колонтитулах объекты InlineShape внутри надписей не учитываются, поскольку надписи в колонтитулах не входят в число цепочек (в отличие от надписей, расположенных в основном тексте документа).

Это упущение мы ликвидируем  при обработке объектов Shape.

Перебор объектов Shapes

Объекты Shape могут находиться только в основном тексте документа и в колонтитулах. Поэтому можно обойтись без применения свойства ShapeRange, которое некорректно работает в версии Word 2003.

Начнем с макроса, в котором перебираются невложенные объекты Shape, т. е. объекты, не лежащие на полотне и не входящие в состав группы.

Сначала осуществляется перебор по объектам Shape, находящимся в основном тексте документа, а затем по всем колонтитулам. Как уже упоминалось, чтобы получить коллекцию Shapes, содержащую объекты Shape во всех колонтитулах, достаточно применить свойство Shapes к любому из объектов HeaderFooter. Здесь использован объект, представляющий основной верхний колонтитул первого раздела, существующий в любом документе.

Если не требуется выделять объекты в колонтитулах, то переносить курсор в колонтитул не обязательно.

 

Sub Example3()

'Пример: перебор по невложенным объектам Shapes в

'основном тексте и колонтитулах (не находящихся на канвах и в группах)

'Вычисляется число невложенных объектов Shapes

 

  Dim intShapeCount As Integer 'счетчик объектов Shape

  Dim shp As Shape 'shape для текущей цепочки в  rngStory

 

  intShapeCount = 0

 

  'Цикл по Shapes в Main Text

  For Each shp In ActiveDocument.Shapes

    intShapeCount = intShapeCount + 1

  Next shp

 

  'Цикл по всем Shapes во всех колонтитулах

  '(в первом разделе документа всегда существует основной верхний колонтитул)

  For Each shp In ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Shapes

    intShapeCount = intShapeCount + 1

  Next shp

  MsgBox "Невложенных объектов Shape: " & intShapeCount, vbInformation _

          , "Перебор по невложенным объектам shape"

End Sub

 

Перебор вложенных объектов Shapes и InlineShape

Для перебора объектов Shape и InlineShape, содержащихся в других объектах Shape, напишем отдельную подпрограмму:

Private Sub CountInShps(shp As Shape, intShpCount As Integer)

'Добавить в intShpCount число объектов Shape и InlineShapes, вложенных в shp

 

  Dim shpInShape As Shape 'переменная для цикла по CanvasItems или GroupItems

  Dim ils As InlineShape  'переменная для цикла по InlineShapes

 

  intShpCount = intShpCount + 1

 

  Select Case shp.Type

    Case 20 'msoCanvas

    'msoCanvas = 20 'не определено в Office pre-2000, поэтому используется число 20

      'Переход к элементам в канве

      If shp.CanvasItems.Count > 0 Then ' Для предотвращения ошибки Automatization Error

                                        ' в Word 2003

        For Each shpInShape In shp.CanvasItems

          'Рекурсия

          Call CountInShps(shpInShape, intShpCount)

        Next shpInShape

      End If

     

    Case 6 'msoGroup

      'Переход к элементам в группе

      For Each shpInShape In shp.GroupItems

        'Рекурсия

        Call CountInShps(shpInShape, intShpCount)

      Next shpInShape

     

    Case Else

      'Цикл по объектам InlineShapes в тексте, расположенном в Shape

      If shp.TextFrame.HasText Then

          For Each ils In shp.TextFrame.TextRange.InlineShapes

            intShpCount = intShpCount + 1

          Next ils

      End If

  End Select

End Sub

Если объект shp представляет канву или группу, то происходит перебор по всем объектам Shape, содержащимся в shp, и для каждого такого элемента выполняется рекурсивное обращение к подпрограмме CountInShps для дальнейшей обработки вложенных элементов. В противном случае, если объект shp содержит текст, вычисляется количество объектов InlineShape в этом тексте.

 

Подпрограмма CountInShps позволяет усовершенствовать подпрограмму Example3 и подсчитать общее число объектов Shapes и вложенных объектов InlineShapes в основном тексте документа и в колонтитулах.

 

Sub Example4()

'Пример: перебор по объектам Shapes и вложенным в надписи

'объектам InlineShapes в основном тексте и колонтитулах

'Вычисляется число объектов Shapes и вложенных объектов InlineShapes

 

  Dim intShpCount As Integer 'счетчик объектов Shape

  Dim shp As Shape 'shape для текущей цепочки в rngStory

 

  intShpCount = 0

 

  'Цикл по Shapes в Main Text

  For Each shp In ActiveDocument.Shapes

    Call CountInShps(shp, intShpCount)

  Next shp

 

  'Цикл по всем Shapes во всех колонтитулах

  '(в первом разделе документа всегда существует основной верхний колонтитул)

  For Each shp In ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Shapes

    Call CountInShps(shp, intShpCount)

  Next shp

 

  MsgBox "Объектов Shape и вложенных InlineShape: " & intShpCount, vbInformation _

          , "Перебор по объектам Shape по вложенным объектам InlineShape"

End Sub

 

Теперь можно объединить подпрограммы Example2 и Example4, чтобы посчитать общее число графических объектов в документе. Однако следует отметить, что объекты InlineShape в надписях, расположенных в основном тексте документа, учитываются в каждой из этих подпрограмм. Поэтому исключим их из обработки, выполняемой в программе Example2

Sub Example5()

'Пример: перебор по объектам Shapes и InlineShapes в активном документе

'Вычисляется число объектов Shapes и InlineShapes

 

  Dim intShpCount As Integer 'счетчик объектов Shape

  Dim shp As Shape 'shape для текущей цепочки в  rngStory

  Dim intInlShpCount As Integer 'счетчик InlineStory

  Dim rngStory As Range 'range для текущего объекта story в цикле

  Dim inlShape As InlineShape 'текущей объект InlineShape в цикле

 

  intShpCount = 0

 

  'Цикл по Shapes в основном тексте (Main Text)

  For Each shp In ActiveDocument.Shapes

    Call CountInShps(shp, intShpCount)

  Next shp

 

  'Цикл по всем Shapes во всех колонтитулах

  '(в первом разделе документа всегда существует основной верхний колонтитул)

  For Each shp In ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Shapes

    Call CountInShps(shp, intShpCount)

  Next shp

 

  'Цикл по каждому типу цепочек активного документа

  For Each rngStory In ActiveDocument.StoryRanges

    'Надписи (TextFrame) уже обработаны

    If rngStory.StoryType <> wdTextFrameStory Then

      'iterate thru each story the same type

      Do

        'в диапазоне цепочки rngStory на каждой итерации

          For Each inlShape In rngStory.InlineShapes

            intShpCount = intShpCount + 1

          Next inlShape

       

        'переход к следующей цепочке rngStory того же типа

        Set rngStory = rngStory.NextStoryRange

      Loop Until rngStory Is Nothing

    End If

  Next rngStory

 

  MsgBox "Объектов Shape и InlineShape: " & intShpCount, vbInformation _

          , "Перебор объектов Shape и InlineShape"

End Sub

 

Следует упомянуть, что в этой подпрограмме не учитываются рамки (Frames), о которых говорится в примечании 1.

Кроме того, здесь не учитываются встроенные фигуры, которые могут быть вставлены в узлы диаграмм в Microsoft Word 2003. Это можно было бы сделать, но эти диаграммы исключены из Microsoft Word 2007, поэтому я счел эту работу бесперспективной и не стал усложнять программу. Наконец, в Microsoft Word 2007 объекты InlineShape могут содержаться в объектах SmartArt (например, в качестве фона элемента), но в VBA я не смог найти средств доступа к компонентам объектов SmartArt.

Обработка графики в программе EachShape

Теперь, когда мы научились перебирать графические объекты, можно сделать что-нибудь более интересное, чем просто посчитать их количество. Для этого следует написать подпрограмму обработки одного графического объекта и вставить ее вместо оператора приращения счетчика в подпрограммы Example5 и CountInShps. Точнее, надо написать, как минимум, две подпрограммы: одну для обработки объектов Shape, а другую для объектов InlineShape (эти объекты обрабатываются по-разному). Кроме того, необходима программа для подготовки к перебору объектов (вместо обнуления счетчика) и программа вывода результатов.

В качестве примера рассмотрим программу Each Shape, в которой перебираются все графические объекты в активном документе и каждый из них по очереди выделяется. О каждом выделенном объекте сообщаются основные данные, а в конце выводится журнал — документ, в который копируются все графические объекты вместе с информацией о них, а также текст из надписей, содержащихся в этих объектах. Эта программа содержится в модуле Each_shape (она также оформлена в виде шаблона, который можно загрузить на странице http://markros.ru/eachshape).

Прошу прощения за англоязычный интерфейс пользователя. Я счел нецелесообразным по своему разумению переводить на русский язык многочисленные названия типов графических объектов. Это только запутало бы читателя. А делать смесь "французского с нижегородским" мне не хотелось.

Краткое описание алгоритма программы Each Shape

Программа выполняется в несколько этапов:

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

С помощью формы frmEachShape пользователь отбирает объекты для просмотра и способ их обработки и запускает обработку.

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

После просмотра графических объектов выводится файл с копией всех графических объектов, краткой информацией об этих объектах и текстом из надписей, содержащихся в объектах.

Таким образом, выполняется два шага перебора графических объектов: сбор статистики и собственно обработка объектов.

Глобальная переменная intProcessStepPbl— номер шага.

Для запуска программы используется кнопка Each Shape, расположенная на панели инструментов EachShape Инструментальная панель EachShape и вызывающая макрос EachShape:

 

Sub EachShape()

  'process step number

  'номер шага обработки

  intProcessStepPbl = 1

 

  Set docActivePbl = ActiveDocument

 

  'seroing statistic

  'обнуление статистических характеристик

  Call PblZeroing

 

  'save <saved> property to restore it (if it need)

  'запомнить свойство <saved>, чтобы при необходимости восстановить его

   boolDocSavedPbl = docActivePbl.Saved

 

  'first graphics iteration

  'первый перебор графики

  Call IterateGrapics

 

  'Fill And Show Form

  'Заполнение и отображение формы

  Call FillAndShowForm

End Sub

 

После завершения работы макроса EachShape отображается форма frmEachShape с собранной статистикой, флажками для выбора способа обработки, флажками для отбора объектов для просмотра и кнопками запуска и отмены обработки:

­

 

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

 

Private Sub btnStart_Click()

 

............

 

  'process step number

  'номер шага обработки

  intProcessStepPbl = 2

 

  'fill reference tables

  'заполнение справочных таблиц

  Call Init

 

  'Create log document and add statistics to it

  'создание журнала обрабоки и занесение в него статистики

  Call AddLogDoc

 

  'zeroing graphics counter

  'обнуление счетчика графики

  intGraphicsPbl = 0

 

  'second process step

  'второй шаг обработки

  Call IterateGrapics

 

  'finishing

  'завершение работы

  Call allDone

 

End Sub

 

На каждом шаге перебор графических объектов осуществляется подпрограммой IterateGrapics, содержащей обращение к подпрограмме NestShp. Эти две подпрограммы действуют аналогично описанным выше подпрограммам Example5 и CountInShps.

В подпрограммах IterateGrapics и NestShp в том месте, где в программах Example5 и CountInShps были инструкции приращения счетчика объектов, происходит вызов программ обработки графических объектов: подпрограммы ProcessShp для обработки объектов Shape и подпрограммы ProcessIls для обработки объектов InlineShape.

Дополнительно в подпрограммах IterateGrapics и NestShp предусмотрен учет расположения и вложенности графических объектов. С этой целью в них вычисляются и передаются в подпрограммы обработки графических объектов следующие параметры:

intNestLevel — уровень вложенности

strNesting — массив имен объектов, в которых находится текущий объект

lctn — признак местоположения (основной текст, колонтитулы, комментарии, сноски, концевые сноски)

В подпрограммах ProcessShp и ProcessIls в зависимости от выполняемого шага (сбор статистики или обработка объектов) вызываются различные подпрограммы обработки.

Практические аспекты обработки графики

Подробности алгоритма можно посмотреть в коде подпрограмм, поэтому я решил их не описывать, а обратить ваше внимание на наиболее интересные моменты обработки графики:

Восстанавливается свойство Saved

Как я уже упоминал, после обращения к свойству Shapes свойство Saved активного документа принимает значение False. Это означает, что при закрытии документа последует ненужный запрос о его сохранении.

Поэтому в макросе EachShape запоминается начальное значение этого свойства, а на выходе из программы в макросах AllDone свойство Saved активного документа восстанавливается.

В макросе boolCheckInPage учитывается, что в случае переноса на страницу объектов, лежащих вне ее, значением этого свойства должно быть False.

Проверяется, является ли объект InlineShape объектом WordArt

Для этой цели применяется макрос strInlineWordArtText.

Составлены громоздкие таблицы для текстового описания типов графических объектов

В макросе Init заполняются таблицы, по которым можно находить названия типов объектов Shape, InlineShape и AutoShape по числовым значениям встроенных констант (в справке Microsoft Word русские названия для них не упоминаются, и официального перевода для них нет).

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

Макрос boolCheckInPage проверяет, находится ли объект хотя бы частично в пределах страницы, и при необходимости может перенести его на страницу. Без средств VBA такую операцию выполнить сложно.

Определяются различные свойства и параметры графических объектов

Макросы strShpProperty и strIlsProperty и используемые в них подпрограммы помимо типа объекта определяют, является ли объект перемещаемым, выявляют наличие в объекте текста, выясняют, связаны ли надписи (перетекает ли текст), проверяют, является ли объект рисунком, определяют приложение — источник объекта, вычисляют размеры объекта и т. д.

Выводится сообщение о выделенном в колонтитуле объекте с отображением выделения

Макросы SelectShp и SelectIls позволяют вывести сообщение о выделенном объекте, находящемся в колонтитуле. Если не прибегать к искусственным приемам, то при выводе сообщения выделение таких объектов не отображается.

Копируется в другой документ текущий объект Shape без его выделения

Чтобы скопировать в другой документ текущий объект Shape, не выделяя его, в макросе LogShp копируется с форматированием соответствующий объект Anchor.


© Розенберг М. М., 2010

Последнее обновление страницы: 01.04.2010