Рассмотрим, как перенести в документ Microsoft Word таблицы с полями и свойствами полей из Microsoft Access. Точнее, мы будем переносить не сами данные, а именно характеристики таблиц. Иногда бывает нужно сделать несколько работ с отчетами или работу с большой базой данных. В этом случае изложенный метод поможет сэкономить время при написании отчета.
Предлагаю один из вариантов решения поставленной задачи. Его можно отредактировать под свои нужды и стандарты, например, оформление и разные свойства полей.
Как пользоваться (для тех, кто мало использует VBA) – скопируйте выделенный шрифтом текст функции (дальше по тексту поста). Откройте базу данных, перейдите на вкладку «Создание». Найдите крайний справа пункт «Макрос» и нажмите на раскрывающую стрелку вниз, выберите пункт «Модуль»:
Откроется редактор Visual Basic. У вас автоматически создается первый модуль под именем Module1. Вставляйте ранее скопированный текст функции в этот модуль.
Если у вас уже есть там какой-то модуль, можете создать новый или вставить функцию в имеющийся.
Сейчас нужно проверить подключенные библиотеки. В редакторе VB идем в меню Tools->References и смотрим, что там у нас подключено. Вот какие пункты должны быть отмечены галочками:
Если какого-то пункта нет (как правило, нет библиотеки Microsoft Word 12.0 Object Library) то ищем его в списке и ставим галочку. Если у вас офис ранних версий, то версия будет не 12.0, а меньше.
Устанавливаем курсор на текст функции PrintTablesWord() и запускаем ее на выполнение с панели, нажав на значок зеленого треугольника, из меню – Run->Run Sub или нажав F5.
Откроется новый документ Word, заполнится таблицами с данными и останется открытым. Если все устраивает, то закрываем редактор Visual Basic, не сохраняя изменения (для работы новая функция не нужна, только для отчета). Далее работаем с документом Word – копируем таблицы в отчет, исправляем и так далее.
Если что-то не устраивает, то правим текст функции и снова запускаем.
Сейчас подробнее по тексту.
Сначала объявляем переменные:
db As dao.Database – база данных
tdf As TableDef - таблица
fld As Field – поле таблицы
prop As Property – свойство поля
wd As Word.Application – приложение Word
tableNumber As Integer – номер таблицы (нужен для заголовка)
fldCount As Integer - количество полей в таблице (для создания таблицы)
str As String, strDimens As String – вспомогательные строки
Обязательно пишем - On Error Resume Next
Дело в том, что у разных типов полей разные свойства. Если программа не найдет какого-либо свойства, то выдаст ошибку и остановится. Если же написано «On Error Resume Next», то программа без выдачи предупреждений об ошибках проследует дальше.
Далее инициализируем наши переменные, подключаемся к базе данных программно, создаем и открываем новый документ Word.
Затем считаем количество полей таблицы
fldCount = tdf.Fields.Count
и начинаем оформлять документ. Сначала заголовок таблицы и слово «Таблицы « с номером, затем вставляем таблицу с нужным количеством строк, равным числу полей плюс 1 (для шапки).
Несколько операторов из текста:
wd.Selection.TypeParagraph – новый абзац.
wd.Selection.Font.Italic = False – устанавливаем НЕкурсивный шрифт.
wd.Selection.TypeText Text:="Таблица " текст абзаца.
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphRight – выравнивание абзаца
Все выполняем через объект Selection.
В заголовке таблицы выделим название таблицы курсивом. Сделаем, например, так (взято из записи макроса):
wd.Selection.TypeText Text:="Характеристики полей таблицы " + tdf.Name – выводим заголовок
wd.Selection.MoveLeft Unit:=wdCharacter, Count:=Len(tdf.Name), Extend:=wdExtend – выделяем название таблицы, то есть двигаемся влево на количество букв (тип единиц – буква wdCharacter) названия.
wd.Selection.Font.Italic = True – устанавливаем курсивный шрифт.
wd.Selection.MoveRight Unit:=wdCharacter, Count:=Len(tdf.Name) – возвращаемся обратно.
Можно передвигаться по-другому, используя Move, end, start. Способы описаны в справке по VBA.
wd.ActiveDocument.Tables.Add Range:=wd.Selection.Range, NumRows:=fldCount + 1, NumColumns:= _3, … - вставляем таблицу из трех столбцов.
Передвигаться по ячейкам таблицы можно также с помощью MoveLeft, MoveRight и т.д., но единица передвижения будет ячейка – wdCell.
wd.Selection.MoveRight Unit:=wdCell – переходим в ячейку правее. Если она крайняя, то курсор переходит на следующую строку. Если строки нет, то она создается по шаблону верхней строки.
For Each fld In tdf.Fields – в цикле перебираем все поля таблицы.
В первом и втором столбце нужно установить выравнивание по вертикали по центру. Это делается на в параметрах абзаца (как выравнивание по горизонтали), а в параметрах ячейки. Сначала нужно выделить ячейку, затем установить нужный вариант выравнивания:
wd.Selection.SelectCell
wd.Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
Во втором столбце нужно указать тип данных. Каждому типу соответствует своя константа. Поскольку значение константы числовое, а в отчет нужно вывести текстовое значение, то в операторе Select Case выбираем нужное значение, соответствующее константе. Если мы перечислили не все значения, и подходящего соотношения не нашлось, то ищем его значение в справке и добавляем в текст функции или просто выведем числовое значение и исправим вручную в тексте документа.
Кроме типа данных запомним еще размер поля strDimens. Можно вывести и само значение Size, но оно показательно только для текстовых полей.
Сначала выводим, является ли поле обязательным. Недостаток – у ключевых полей всегда выводится «Нет»., а свойство “Primary” требует ADO.
Затем выведем размер поля, если он записан в strDimens. Иногда размер поля не имеет значения (например, у OLE, MEMO), в таких случаях его не выводим:
If Len(strDimens) > 0 Then
‘… здесь выводим размер поля
Затем в цикле For Each перебираем все поля и выбираем нужные. Из нужных запоминаем в переменную str название. Затем смотрим, если длина str больше нуля, то есть свойство найдено, то выводим его и его значение (prop.value). Значение затем выделяем курсивом.
После каждой таблицы сдвигаемся вниз:
wd.Selection.MoveDown Unit:=wdLine, Count:=1
Вот что примерно получается:
Список свойств в этом примере неполный, можете посмотреть в справке и добавить свои. Вот адрес страницы справки всех свойств: http://msdn.microsoft.com/en-us/library/aa294141%28v=office.10%29.aspx
Кажется, все важное описал. Пример проверен для Microsoft Access 2007.
Предлагаю один из вариантов решения поставленной задачи. Его можно отредактировать под свои нужды и стандарты, например, оформление и разные свойства полей.
Как пользоваться (для тех, кто мало использует VBA) – скопируйте выделенный шрифтом текст функции (дальше по тексту поста). Откройте базу данных, перейдите на вкладку «Создание». Найдите крайний справа пункт «Макрос» и нажмите на раскрывающую стрелку вниз, выберите пункт «Модуль»:
Откроется редактор Visual Basic. У вас автоматически создается первый модуль под именем Module1. Вставляйте ранее скопированный текст функции в этот модуль.
Если у вас уже есть там какой-то модуль, можете создать новый или вставить функцию в имеющийся.
Сейчас нужно проверить подключенные библиотеки. В редакторе VB идем в меню Tools->References и смотрим, что там у нас подключено. Вот какие пункты должны быть отмечены галочками:
Если какого-то пункта нет (как правило, нет библиотеки Microsoft Word 12.0 Object Library) то ищем его в списке и ставим галочку. Если у вас офис ранних версий, то версия будет не 12.0, а меньше.
Устанавливаем курсор на текст функции PrintTablesWord() и запускаем ее на выполнение с панели, нажав на значок зеленого треугольника, из меню – Run->Run Sub или нажав F5.
Откроется новый документ Word, заполнится таблицами с данными и останется открытым. Если все устраивает, то закрываем редактор Visual Basic, не сохраняя изменения (для работы новая функция не нужна, только для отчета). Далее работаем с документом Word – копируем таблицы в отчет, исправляем и так далее.
Если что-то не устраивает, то правим текст функции и снова запускаем.
Сейчас подробнее по тексту.
Sub PrintTablesWord()Функция получилась длинная, но разбивать ее на несколько нет смысла, все равно копировать одним куском, а потом удалять.
Dim db As dao.Database
Dim tdf As TableDef, fld As Field, prop As Property
Dim wd As Word.Application
Dim tableNumber As Integer, fldCount As Integer
Dim str As String, strDimens As String
On Error Resume Next
tableNumber = 1
fldCount = 0
str = ""
strDimens = ""
Set db = CurrentDb
Set wd = CreateObject("Word.Application")
wd.Visible = True
'создаем новый документ Word
wd.Documents.Add
'выборка всех таблиц из базы данных
For Each tdf In db.TableDefs
'исключаем системные таблицы
If Left(tdf.Name, 4) <> "MSys" Then
fldCount = tdf.Fields.Count
'пишем таблицу и ее номер
wd.Selection.TypeParagraph
wd.Selection.Font.Italic = False
wd.Selection.TypeText Text:="Таблица " + CStr(tableNumber)
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphRight
'название таблицы
wd.Selection.TypeParagraph
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
wd.Selection.TypeText Text:="Характеристики полей таблицы " + tdf.Name
wd.Selection.MoveLeft Unit:=wdCharacter, Count:=Len(tdf.Name), Extend:=wdExtend
wd.Selection.Font.Italic = True
wd.Selection.MoveRight Unit:=wdCharacter, Count:=Len(tdf.Name)
'вставляем таблицу с нужным количеством строк
wd.ActiveDocument.Tables.Add Range:=wd.Selection.Range, NumRows:=fldCount + 1, NumColumns:= _
3, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
wdAutoFitFixed
With wd.Selection.Tables(1)
If .Style <> "Сетка таблицы" Then
.Style = "Сетка таблицы"
End If
.ApplyStyleHeadingRows = True
.ApplyStyleLastRow = False
.ApplyStyleFirstColumn = True
.ApplyStyleLastColumn = False
.ApplyStyleRowBands = True
.ApplyStyleColumnBands = False
End With
'первая строка - шапка таблицы
wd.Selection.TypeText Text:="Имя поля"
wd.Selection.MoveRight Unit:=wdCell
wd.Selection.TypeText Text:="Тип данных"
wd.Selection.MoveRight Unit:=wdCell
wd.Selection.TypeText Text:="Свойства поля"
'перебор полей
For Each fld In tdf.Fields
str = ""
strDimens = ""
'название поля
wd.Selection.MoveRight Unit:=wdCell
wd.Selection.TypeText Text:=fld.Name
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphLeft
wd.Selection.SelectCell
wd.Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
wd.Selection.MoveRight Unit:=wdCell
'тип данных (и размер)
Select Case fld.Type
Case dbBoolean
wd.Selection.TypeText Text:="Логический"
Case dbByte
wd.Selection.TypeText Text:="Байт"
strDimens = "Байт"
Case dbCurrency
wd.Selection.TypeText Text:="Денежный"
Case dbDate
wd.Selection.TypeText Text:="Дата/время"
Case dbDouble
wd.Selection.TypeText Text:="Числовой"
strDimens = "С плавающей точкой 8 байт"
Case dbGUID
wd.Selection.TypeText Text:="Счетчик"
strDimens = "Длинное целое"
Case dbInteger
wd.Selection.TypeText Text:="Числовой"
strDimens = "Целое"
Case dbLong
wd.Selection.TypeText Text:="Числовой"
strDimens = "Длинное целое"
Case dbLongBinary
wd.Selection.TypeText Text:="Объект OLE"
Case dbMemo
wd.Selection.TypeText Text:="Поле MEMO"
Case dbSingle
wd.Selection.TypeText Text:="Числовой"
strDimens = "С плавающей точкой 4 байт"
Case dbText
wd.Selection.TypeText Text:="Текстовый"
strDimens = CStr(fld.Size)
Case Else
wd.Selection.TypeText Text:=CStr(fld.Type)
strDimens = CStr(fld.Size)
End Select
wd.Selection.SelectCell
wd.Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
'свойства поля
wd.Selection.MoveRight Unit:=wdCell
wd.Selection.Font.Italic = False
wd.Selection.TypeText Text:="Обязательное поле: " + IIf(fld.Required, "Да", "Нет")
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphLeft
wd.Selection.MoveLeft Unit:=wdCharacter, Count:=3, Extend:=wdExtend
wd.Selection.Font.Italic = True
wd.Selection.MoveRight Unit:=wdCharacter, Count:=1
If Len(strDimens) > 0 Then
wd.Selection.TypeParagraph
wd.Selection.Font.Italic = False
wd.Selection.TypeText Text:="Размер поля: " + strDimens
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphLeft
wd.Selection.MoveLeft Unit:=wdCharacter, Count:=Len(strDimens), Extend:=wdExtend
wd.Selection.Font.Italic = True
wd.Selection.MoveRight Unit:=wdCharacter, Count:=1
End If
'перебор всех свойств и выбор нужного
For Each prop In fld.Properties
str = ""
If prop.Name Like "Description" Then
str = "Описание: "
End If
If prop.Name Like "inputmask" Then
str = "Маска ввода: "
End If
If prop.Name Like "Format" Then
str = "Формат поля: "
End If
If prop.Name Like "rowsource" Then
str = "Источник строк: "
End If
'вывод свойства в таблицу
If Len(str) > 0 Then
wd.Selection.TypeParagraph
wd.Selection.Font.Italic = False
wd.Selection.TypeText Text:=str + prop.Value
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphLeft
wd.Selection.MoveLeft Unit:=wdCharacter, Count:=Len(prop.Value), Extend:=wdExtend
wd.Selection.Font.Italic = True
wd.Selection.MoveRight Unit:=wdCharacter, Count:=1
End If
Next prop
Next fld
tableNumber = tableNumber + 1
wd.Selection.MoveDown Unit:=wdLine, Count:=1
End If
Next tdf
Set db = Nothing
End Sub
Сначала объявляем переменные:
db As dao.Database – база данных
tdf As TableDef - таблица
fld As Field – поле таблицы
prop As Property – свойство поля
wd As Word.Application – приложение Word
tableNumber As Integer – номер таблицы (нужен для заголовка)
fldCount As Integer - количество полей в таблице (для создания таблицы)
str As String, strDimens As String – вспомогательные строки
Обязательно пишем - On Error Resume Next
Дело в том, что у разных типов полей разные свойства. Если программа не найдет какого-либо свойства, то выдаст ошибку и остановится. Если же написано «On Error Resume Next», то программа без выдачи предупреждений об ошибках проследует дальше.
Далее инициализируем наши переменные, подключаемся к базе данных программно, создаем и открываем новый документ Word.
For Each tdf In db.TableDefsВ этом цикле выбираем все таблицы. Но не все таблицы нам нужны. В базе содержится куча системных таблицы, которые скрыты. В отчете их не нужно указывать. Названия системных таблиц начинаются с MSys, поэтому их исключаем:
Next tdf
If Left(tdf.Name, 4) <> "MSys" ThenЕсли же есть еще скрытые таблицы, например, начинающиеся с USys, можно добавить новое условие.
Затем считаем количество полей таблицы
fldCount = tdf.Fields.Count
и начинаем оформлять документ. Сначала заголовок таблицы и слово «Таблицы « с номером, затем вставляем таблицу с нужным количеством строк, равным числу полей плюс 1 (для шапки).
Несколько операторов из текста:
wd.Selection.TypeParagraph – новый абзац.
wd.Selection.Font.Italic = False – устанавливаем НЕкурсивный шрифт.
wd.Selection.TypeText Text:="Таблица " текст абзаца.
wd.Selection.ParagraphFormat.Alignment = wdAlignParagraphRight – выравнивание абзаца
Все выполняем через объект Selection.
В заголовке таблицы выделим название таблицы курсивом. Сделаем, например, так (взято из записи макроса):
wd.Selection.TypeText Text:="Характеристики полей таблицы " + tdf.Name – выводим заголовок
wd.Selection.MoveLeft Unit:=wdCharacter, Count:=Len(tdf.Name), Extend:=wdExtend – выделяем название таблицы, то есть двигаемся влево на количество букв (тип единиц – буква wdCharacter) названия.
wd.Selection.Font.Italic = True – устанавливаем курсивный шрифт.
wd.Selection.MoveRight Unit:=wdCharacter, Count:=Len(tdf.Name) – возвращаемся обратно.
Можно передвигаться по-другому, используя Move, end, start. Способы описаны в справке по VBA.
wd.ActiveDocument.Tables.Add Range:=wd.Selection.Range, NumRows:=fldCount + 1, NumColumns:= _3, … - вставляем таблицу из трех столбцов.
Передвигаться по ячейкам таблицы можно также с помощью MoveLeft, MoveRight и т.д., но единица передвижения будет ячейка – wdCell.
wd.Selection.MoveRight Unit:=wdCell – переходим в ячейку правее. Если она крайняя, то курсор переходит на следующую строку. Если строки нет, то она создается по шаблону верхней строки.
For Each fld In tdf.Fields – в цикле перебираем все поля таблицы.
В первом и втором столбце нужно установить выравнивание по вертикали по центру. Это делается на в параметрах абзаца (как выравнивание по горизонтали), а в параметрах ячейки. Сначала нужно выделить ячейку, затем установить нужный вариант выравнивания:
wd.Selection.SelectCell
wd.Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
Во втором столбце нужно указать тип данных. Каждому типу соответствует своя константа. Поскольку значение константы числовое, а в отчет нужно вывести текстовое значение, то в операторе Select Case выбираем нужное значение, соответствующее константе. Если мы перечислили не все значения, и подходящего соотношения не нашлось, то ищем его значение в справке и добавляем в текст функции или просто выведем числовое значение и исправим вручную в тексте документа.
Кроме типа данных запомним еще размер поля strDimens. Можно вывести и само значение Size, но оно показательно только для текстовых полей.
Case dbTextВ третьем столбце выводим свойства полей. Значение свойства выделяем курсивом, как уже описано выше. Отличие – возвращаемся вправо на одну единицу, потому что в таблицах движение идет по ячейкам.
wd.Selection.TypeText Text:="Текстовый"
strDimens = CStr(fld.Size)
Сначала выводим, является ли поле обязательным. Недостаток – у ключевых полей всегда выводится «Нет»., а свойство “Primary” требует ADO.
Затем выведем размер поля, если он записан в strDimens. Иногда размер поля не имеет значения (например, у OLE, MEMO), в таких случаях его не выводим:
If Len(strDimens) > 0 Then
‘… здесь выводим размер поля
Затем в цикле For Each перебираем все поля и выбираем нужные. Из нужных запоминаем в переменную str название. Затем смотрим, если длина str больше нуля, то есть свойство найдено, то выводим его и его значение (prop.value). Значение затем выделяем курсивом.
После каждой таблицы сдвигаемся вниз:
wd.Selection.MoveDown Unit:=wdLine, Count:=1
Вот что примерно получается:
Список свойств в этом примере неполный, можете посмотреть в справке и добавить свои. Вот адрес страницы справки всех свойств: http://msdn.microsoft.com/en-us/library/aa294141%28v=office.10%29.aspx
Кажется, все важное описал. Пример проверен для Microsoft Access 2007.
