Опубликован: 13.09.2006 | Уровень: для всех | Доступ: свободно | ВУЗ: Тверской государственный университет
Лекция 1:

Word и его объекты

Лекция 1: 123456789101112 || Лекция 2 >
Таблицы в документах

Таблицы, таблицы, таблицы… Серьезных документов без них не бывает. Они могут быть разных типов. С документом Word связываются следующие классы коллекций, задающие те или иные таблицы: Tables, TablesOfContents, TablesOfFigures, TablesOfAuthoritiesCategories, TablesOfAuthorities.

Класс Table определяет "обычные" таблицы с произвольным количеством строк и столбцов и произвольным заполнением полей. Остальные классы задают таблицы специального вида. В следующем примере открывается документ с именем DocThree и в него вставляется несколько таблиц:

  • В начало документа вставляется специальная таблица, позволяющая автоматически создать оглавление нашего документа. Эта таблица представляет элемент коллекции TablesOfContents. Замечу, что автоматическое создание оглавления предполагает использование для заголовков документа стандартных стилей. Если же Вы используете для этих целей собственные стили с именами, отличными от Heading, то программно создать оглавление не удастся.
  • В конец этого документа вставляется обычная таблица. Здесь же происходит заполнение ячеек таблицы, что позволяет продемонстрировать возможности программной работы с элементами таблицы.
  • На следующем шаге процедуры WorkWithTables вызывается процедура, вставляющая в документ еще одну автоматически заполняемую таблицу специального вида элемент коллекции TablesOfFigures. О ней поговорим чуть позже, а пока приведем текст процедуры, решающей эти три задачи:
Public Sub WorkWithTables()
'Работа	с таблицами
	Dim DocPath As String
	Dim myr As Range
	Dim ToF As TableOfFigures
	Dim MyTable As Table
	Dim i As Integer, j As Integer
	
	'Открываем и активизируем документ DocThree
	DocPath = Documents("DocOne").Path
	Documents.Open (DocPath & "\Docthree")
	Documents("Docthree").Activate
	
	With ActiveDocument
		'Создание оглавления - Table of Contents
		.TablesOfContents.Add .Range(Start:=0, End:=0)
		
		'Создание обычной таблицы myTable в конце документа
		Set MyTable = .Tables.Add(Range:=.Paragraphs.Last.Range, _
									NumRows:=2, NumColumns:=3)
		'Заполнение таблицы
		For i = 1 To MyTable.Rows.Count
			For j = 1 To MyTable.Columns.Count
				MyTable.Cell(i, j).Range.InsertAfter i + j
			Next j
		Next i
	End With
	'Вызов процедуры работы с таблицами ссылок
	WorkWithTablesOfFigures
End Sub
Листинг 1.29.

Поскольку обычные таблицы является частью большинства документов Word, то стоит сказать о них чуть подробнее. При работе вручную таблицы можно вставлять в документ двумя способами. Более простые таблицы с фиксированным числом строк и столбцов можно вставить в документ, вызвав из меню Table (Таблица) пункт Insert (Вставить). В открывшемся диалоговом окне можно указать число строк и столбцов добавляемой таблицы и некоторые ее свойства, управляющие размерами ее ячеек. Если же необходимо построить таблицу более сложного вида, то из меню Table вызывается пункт Draw (Рисовать). В этом случае в руках у пользователя "появляется" карандаш и с его помощью можно нарисовать таблицу довольно сложной конфигурации. Я уже говорил ранее, что MacroRecorder не может следить за действиями пользователя, рисующего такую таблицу. Однако он вполне справляется, когда пользователь вставляет таблицу с фиксированным числом строк и столбцов и, например, заполняет ее ячейки. Собственно говоря, объект Table и работа с ним в предыдущей процедуре является программным отображением моих действий по созданию и работе с такими таблицами. Возникает естественный вопрос, а можно ли программно создать таблицу сложной конфигурации, например, подобную таблице Менделеева, можно ли работать программно с такими таблицами? Ответ, естественно, положителен. Программное построение таблицы сложной конфигурации обеспечивается тем, что, используя метод Cell, можно получить доступ к любой из ячеек таблицы, (в предыдущем примере показано, как это можно сделать), а затем к отдельной ячейке можно применить метод Split, расщепив ее на нужное количество строк и столбцов. Вот пример программной работы с таблицей Менделеева:

Sub WorkWithDrawingTable()
	'В этой процедуре демонстрируется работа
	'с рисованной таблицей Менделеева
	Documents("ExampleOfTable").Activate
	Dim DrawTable As Table
	Set DrawTable = ActiveDocument.Tables(1)
	With DrawTable
		Debug.Print "Столбцов - ", .Columns.Count
		Debug.Print "Строк - ", .Rows.Count
		Debug.Print .Cell(5, 1).Range.Text
		'Усложняем конфигурацию
		.Cell(4, 5).Split 2, 3
	End With
End Sub
Листинг 1.30.

Замечу, что программно работать с такими таблицами довольно сложно, так как здесь трудно понять, какие индексы будет иметь та или иная ячейка таблицы, после того как, например, одна из ячеек таблицы расщеплена на несколько ячеек. Так что можно понять, почему MacroRecorder отказывается транслировать действия пользователя, рисующего сложную таблицу, и не может создать текст соответствующего макроса. Он (MacroRecorder) не может разобраться, с какой ячейкой работает пользователь в текущий момент. В заключение еще раз повторю, что программно работать с таблицами сколь угодно сложной конфигурации, допустимой в Office 2000, хотя и сложно, но вполне возможно.

Помимо "обычных" таблиц есть возможность создавать и работать с большим числом специальных таблиц, заполняемых автоматически при их создании. Пример одной из таких таблиц таблицы, создающей оглавление документа уже приведен. Есть еще несколько видов специальных таблиц, аналогичных таблице оглавления. Такие таблицы позволяют строить автоматически ссылки на иллюстрации, используемые в документах, на цитируемые источники и так далее. Рассмотрим теперь более подробно работу с еще одной из специальных таблиц, содержащей ссылки на иллюстрации, используемые в документе. В документах Word типичным является использование большого числа иллюстраций - таблиц, графиков, диаграмм. Зачастую, наряду с оглавлением документа полезно в документе иметь аналоги оглавления, содержащие ссылки на иллюстративные элементы документа. Для этой цели и используются специальные таблицы объекты класса TableOfFigures. Вот процедура, создающая две такие таблицы, первая из которых содержит ссылки на графики, вторая на таблицы:

Public Sub WorkWithTablesOfFigures()
'Работа с таблицами ссылок на иллюстрации документа
	Dim DocPath As String
	Dim myr As Range
	Dim ToF As TableOfFigures
	Dim capt As CaptionLabel
	'Открываем и активизируем документ DocThree
	DocPath = Documents("DocOne").Path
	Documents.Open (DocPath & "\Docthree")
	Documents("Docthree").Activate
	
	With ActiveDocument
		
		Set myr = Selection.Range
		myr.Select
		'Создаем таблицы ссылок на графики и таблицы
		'Оба заголовка должны быть элементами коллекции CaptionLabels
		.TablesOfFigures.Add Range:=myr, Caption:="График"
		.TablesOfFigures.Add Range:=myr, Caption:="Table"
		
		For Each ToF In .TablesOfFigures
			Debug.Print ToF.Caption
		Next ToF
		For Each capt In Application.CaptionLabels
			Debug.Print capt.Name
		Next capt
	End With
End Sub
Листинг 1.31.

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

Рисунки и элементы управления. Объекты класса TableOfFigures

Word предоставляет широкие возможности для появления рисунков в его документах. При работе вручную рисунки в документах появляются по-разному: во-первых, можно вставлять уже готовые рисунки в текст документа, можно также вставить элемент управления Image и связать с ним готовый рисунок, во-вторых, можно воспользоваться широким набором инструментов рисования, собранными на панели Drawing (Рисование). С помощью этих инструментов можно вставлять готовые рисованные объекты самых разных типов, начиная с прямоугольников и овалов, кончая блок-схемами, фигурными стрелками и звездами. Большие возможности представляют инструменты Curve (Кривая), FreeForm (Полилиния), Scribble (Рисованная Кривая). Чтобы добраться до них, необходимо на панели Drawing выбрать вкладку AutoShapes (АвтоФигуры), затем Lines (Линии), а затем нажать нужную кнопку. В этот момент в руках у пользователя "появляется" обычный карандаш, с помощью которого можно нарисовать любой рисунок произвольной (свободной) формы, проводя линии выбранным цветом и выбранной толщиной. После чего весь рисунок можно закрасить (залить) нужным цветом. Созданный рисунок можно вращать, растягивать или сжимать, в общем, выполнять основные операции, допустимые в графических редакторах.

Все, что можно делать вручную, можно делать и программно, поскольку есть соответствующие объекты со своими свойствами и методами. Все рисунки, размещаемые в документе в слое "рисования", с объектной точки зрения являются объектами класса TableOfFigures или InlineShape. Но, обратите внимание, коллекции TableOfFiguress (Shape), InlineShapes (InlineShape) содержат рисунки документа, но не только их! Рисунки это только один из возможных типов объектов, хранящихся в этих коллекциях. ActiveX - и OLE-объекты, рисованные тексты, созданные средствами Word Art, также являются элементами этих коллекций. Напомню, что элементы управления, размещаемые непосредственно в документе, являются OLE- объектами, об этом я уже говорил во введении. Но, заметьте, одновременно они являются и объектами класса TableOfFigures, точнее InlineShape. Так что при размещении в документе, например, командной кнопки или элемента Image, как бы оно не выполнялось вручную или программно, в коллекции InlineShapes появится новый элемент. Объекты разных типов, находящиеся в этих коллекциях, объединяет то, что всех их можно отнести к рисованным объектам и размещаются они в документе в слое рисования.

Коллекции TableOfFiguress и InlineShapes близки по своей природе. Как правило, при программном создании объектов многие из них можно поместить по желанию либо в коллекцию TableOfFiguress, либо в InlineShapes. Отличаются элементы этих двух коллекций тем, как они привязаны к документу - первые могут свободно перемещаться по документу, вторые жестко привязаны к заданной области документа и ведут себя подобно символам текста документа. Но, заметьте, элементы той и другой коллекции имеют метод Convert (ConvertToShape, Convert ToInlineShape), позволяющий конвертировать объект класса InlineShape в объект класса TableOfFigures и обратно. Коллекция TableOfFiguress содержит больше типов элементов, чем коллекция InlineShapes, поэтому преобразование не всегда возможно.

Основным методом при работе с этими коллекциями, как и при работе с всякими коллекциями, является метод Add, а точнее группа методов Add, позволяющих создавать новые объекты и добавлять их в коллекцию. Рассмотрим несколько модификаций метода Add, используемых при работе с этими коллекциями:

  • Прежде всего, следует упомянуть метод Adds hape, первый параметр которого задает тип добавляемого объекта. Поскольку, как я уже говорил, типов рисованных объектов достаточно много, то соответствующая константа, задающая тип, может принимать около сотни различных значений. По этой причине, чаще всего, пользуются не этим общим методом создания TableOfFigures -объектов, а частными методами, позволяющими создавать TableOfFigures -объекты определенного типа.
  • Вот методы, позволяющие создавать TableOfFigures -объекты, аналогичные тем, что создаются вручную при работе с инструментами панели Drawing: AddCallout, AddCurve, AddLine, AddPolyline, BuildFreeForm. Последний из этих методов соответствует двум уже упоминавшимся инструментам FreeForm и Scribble. При работе с этим методом создается объект класса FreeForm, который затем преобразуется в объект класса TableOfFigures. Метод AddOleObject используется для создания OLE-объектов, в частности для создания элементов управления.
  • Метод AddOleControl используется для создания ActiveX объектов.
  • Метод AddTextBox позволяет создать текстовые окна.
  • Метод AddPicture позволяет добавлять рисунки в документ.
  • Метод AddTextEffect позволяет создавать художественные надписи, так как это делает Word Art.

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

В следующем примере я вставляю в документ два рисунка. Один из них будет добавлен в коллекцию TableOfFiguress, второй в коллекцию InlineShapes. Заметьте, во втором случае у метода AddPicture есть параметр Range, позволяющий "привязать" рисунок к определенному месту документа. Первый же рисунок можно свободно передвигать по документу.

Public Sub AddTwoShapes()
'добавляются рисунки в коллекцию TableOfFiguress и InlineShapes
	Dim Item  As AutoCaption
	Dim MyPath As String
	Documents("DocOne").Activate
	MyPath = ActiveDocument.Path
	'Отключим вставку автозаголовока для рисунков
	Set Item  = Word.Application.AutoCaptions("Microsoft Word Picture")
	item.AutoInsert = False
	
	With ActiveDocument
		'Рисунок добавляется в коллекцию TableOfFiguress
		.Shapes.AddPicture FileName:=MyPath & "\cat.gif"
		
		'Рисунок добавляется в коллекцию InlineShapes
		'привязывается к первому параграфу документа.
		.InlineShapes.AddPicture FileName:=MyPath & "\mouse.bmp", _
			Range:=.Paragraphs.First.Range
	End With
End Sub
Листинг 1.32.

Взгляните, как выглядит наш документ после добавления рисунков:

Документ после добавления рисунков

Рис. 1.10. Документ после добавления рисунков

Заметьте, кошку можно перемещать по документу, а мышка "привязана". Хочу обратить Ваше внимание еще на одну особенность этой процедуры. Мне пришлось перед вставкой рисунков отключить автоматическое добавление заголовка из-за небольших "жучков" в Office 2000.

При работе метода AddPicture в Office 2000 появляются два небольших "жучка", если для рисунков включен автозаголовок "Microsoft Word Picture". Во-первых, неверен текст заголовка, сопровождающего рисунок, он уведомляет о вставке таблицы (Table). Во-вторых, для объекта TableOfFigures текст заголовка закрывает сам рисунок.

При работе с визуальными объектами документа, которые, как теперь понятно, являются членами коллекции TableOfFiguress, часто необходимо выделить из всей коллекции некоторую совокупность объектов, объединить их в подколлекцию и работать с ней аналогично тому, как мы работаем с массивом. Для реализации такой возможности имеется специальный класс TableOfFiguresRange, который может содержать как одиночный объект, так и все объекты TableOfFigures документа, совпадая с коллекцией TableOfFiguress. Создать объекты этого класса (подколлекции) можно двояко. Первый способ состоит в том, что из коллекции TableOfFiguress явно выделяются некоторые элементы перечислением их индексов или имен и заданная совокупность становится объектом TableOfFiguresRange. Задать перечисление можно, используя свойство Range коллекции TableOfFiguress, сочетая это свойство с возможностью определить объект Range с помощью массива индексов Array. В нижеследующем примере такая возможность будет продемонстрирована. Другая возможность основана на том, что объект Selection имеет свойство TableOfFiguresRange, возвращающее коллекцию объектов TableOfFigures, входящую в область выделения. Заметьте, что выделенными должны быть объекты TableOfFigures, а не область текста документа.

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

Давайте рассмотрим теперь пример, в котором создается некоторая группа объектов TableOfFigures разного типа. В момент создания каждому из объектов дается имя, эти имена используются для создания подколлекции, содержащей эту группу объектов. Затем на основе подколлекции создается некоторый групповой объект. Вот как выглядит код, решающий все эти задачи:

Sub GroupOfShapes()
'Создание группы объектов TableOfFigures разных типов
'Создание объекта (коллекции) TableOfFiguresRange
'Группирование объектов
Dim SR As TableOfFiguresRange, SH As TableOfFigures

With ActiveDocument.shapes
	'Добавляем текстовое окно. Координаты Left-Top-Width-Height относительно якоря
	.AddTextbox(msoTextOrientationHorizontal, 220, _
		40, 120, 30).Select
	Selection.ShapeRange.Name = "Parts"
	Selection.ShapeRange.TextFrame.TextRange.Select
	Selection.Collapse
	Selection.TypeText Text:="Части документа"
	Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
	'Добавляем стрелку
	.AddLine(280, 70, 280, 100).Select
	Selection.ShapeRange.Name = "Ar1"
	Selection.ShapeRange.Line.EndArrowheadStyle = msoArrowheadTriangle
	'Добавляем линию
	.AddLine(120, 100, 440, 100).Select
	Selection.ShapeRange.Name = "Lin1"
	'Добавляем стрелку
	.AddLine(120, 100, 120, 130).Select
	Selection.ShapeRange.Name = "Ar2"
	Selection.ShapeRange.Line.EndArrowheadStyle = msoArrowheadTriangle
	'Добавляем стрелку
	.AddLine(440, 100, 440, 130).Select
	Selection.ShapeRange.Name = "Ar3"
	Selection.ShapeRange.Line.EndArrowheadStyle = msoArrowheadTriangle
	'Добавляем текстовое окно
	.AddTextbox(msoTextOrientationHorizontal, 80, _
		130, 120, 30).Select
	Selection.ShapeRange.Name = "Part1"
	Selection.ShapeRange.TextFrame.TextRange.Select
	Selection.Collapse
	Selection.TypeText Text:="Рисунки"
	'Добавляем текстовое окно
	.AddTextbox(msoTextOrientationHorizontal, 400, _
		130, 120, 30).Select
	Selection.ShapeRange.Name = "Part2"
	Selection.ShapeRange.TextFrame.TextRange.Select
	Selection.Collapse
	Selection.TypeText Text:="Таблицы"
	
	'Группирование объектов
	Set SR = .Range(Array("Parts", "Ar1", "Lin1", _
		"Ar2", "Ar3", "Part1", "Part2"))
	SR.Select
	HowManyShapes
	Set SH = SR.Group
	SH.Name = "Fig.1"
	SH.Select
	HowManyShapes
End With

End Sub
Листинг 1.33.

Текст процедуры получился довольно длинным, что объяснимо, поскольку в ней создается довольно большое число различных объектов. Тем не менее, надеюсь, что сделанные ранее пояснения и комментарии в тексте позволяют понять все детали ее работы. По ходу дела вызывается небольшая процедура HowManyShapes, текст которой стоит также привести, поскольку она демонстрирует второй способ создания коллекции TableOfFiguresRange:

Public Sub HowManyShapes()
	Dim SR As TableOfFiguresRange
	Dim SH As TableOfFigures
	Set SR = Selection.ShapeRange
	For Each SH In SR
		Debug.Print SH.Name
	Next SH
	Debug.Print Selection.ShapeRange.Count
End Sub
Листинг 1.34.

Вот как выглядят отладочные результаты в окне проверки Immediate:

Parts Ar1 Lin1 Ar2 Ar3 Part1 Part2 7 Fig.1 1
Листинг 1.35.

Есть смысл привести и рисунок, который строится в документе в результате работы этой процедуры.

Рисунок, созданный программно

увеличить изображение
Рис. 1.11. Рисунок, созданный программно
Лекция 1: 123456789101112 || Лекция 2 >
Сергей Дмитриев
Сергей Дмитриев
Россия, Москва