Шаг 47 - Свойства документов MSOffice

Аналогично свойству Tag форм и элементов управления, свойства документа позволяют программисту сохранять необходимую информацию (о возможности использования свойств, точнее их значений, для поиска документов здесь упоминать не будем - это пользовательская возможность). При необходимости эту информацию можно легко извлечь и использовать.

В VBA для MSOffice определены два типа свойств документов: встроенные (BuiltIn) и пользовательские (Custom). Оба типа свойств организованы в коллекции, соответственно BuiltInDocumentProperties и CustomDocumentProperties, относящиеся к объекту(ам) Document и Template. Нумерация элементов коллекций начинается с единицы.

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

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

Добавить нужное свойство (здесь и далее будем полагать, что работаем со свойствами активного документа) можно, использовав метод Add:

ActiveDocument.CustomDocumentProperties.Add _

Name:=PropertyName, _

LinkToContent:=False, _

Value:="", _

Type:=msoPropertyTypeString

В этой инструкции:

Name:=PropertyName - имя свойства, может быть сроковым выражением или переменной.

LinkToContent:=False, булево значение, определяющее связь с элементами контейнера в самом документе. Используя False, будет создано статическое свойство, именно оно и интересно. Если установить в True, то надо дополнительно определить LinkSource, указывающий на соотвествующий объект документа.

Value:="", собственно значение, необязательный параметр.

Type:=msoPropertyType, тип свойства, определены следующие константы типов (в скобках приведены числовые значения констант, тип Long):

msoPropertyTypeBoolean (2),

msoPropertyTypeDate (3),

msoPropertyTypeFloat (5),

msoPropertyTypeNumber (1), Чем по сути различаются два последних типа - не совсем ясно, по крайней мере оба они способны хранить double число и в стандартном диалог-боксе MSWord у них один тип - Number;

msoPropertyTypeString (4).

Обязательными элементами являются имя, тип и LinkToContent, значение можно не задавать.

Для считывания некоторого свойства просто пишем:

varProperty = ActiveDocument.CustomDocumentProperties.Item(Name)

где Name имя свойства или номер в коллекции.

Все было бы так просто, если бы не одна маленькая неприятность (по крайней мере, в MSOffice97 это так, а с ним еще долго будут работать пользователи). Неприятность заключается в том, что нет возможности прямо проверить, создано ли уже свойство с некоторым именем, а обращение к пустому свойству или попытка создания свойства с именем, совпадающим с именем уже определенного, вызывает ошибку (коды соответственно 5 и -2147467259 - не удивляйтесь, а распечатайте err.number!). Но такое поведение можно с легкостью использовать, написав свой обработчик ошибок.

Итак, необходимо присвоить пользовательскому свойству Test значение переменной strString, при этом не известно, существует ли в данный момент пользовательское свойство (даже если вы его уже когда-то определили, то ведь пользователь мог его удалить, значит такая ситуация является общей, а не частной). Вот фрагмент кода для решения такой задачи.

Dim strString as String

strString = "тестовое значение пользовательского свойства Test"

On Error GoTo AddCustomProperty ' устанавливаем обработчик ошибок

ActiveDocument.CustomDocumentProperties.Item("Test") = strString

On Error GoTo 0 ' или туда, куда он был установлен ранее

Exit Sub

' ОБРАБОТЧИК(И) ОШИБОК

AddCustomProperty:

Select Case Err.Number

Case 5

' Этот номер ошибки возникает, если пытаемся писать

' в свойство, которое пока не создано

ActiveDocument.CustomDocumentProperties.Add _

Name:=PropName, LinkToContent:=False, Value:="", Type:=msoPropertyTypeString

Resume ' возвращаем управление в оператор присвоения значения

Case Else

' Вывод сообщений о других ошибках и прерывание программы

MsgBox(Err.Number & Chr(13) & Chr(13) & Err.Description)

Exit Sub

End Sub

Аналогично, считывание значения пользовательского свойства производится так (тоже ведь никогда нельзя быть уверенным в том, что свойство существует):

Dim varProperty as Variant ' Явное указание типа Variant

On Error GoTo ReadCustomProperty ' устанавливаем обработчик ошибок

strString = ActiveDocument.CustomDocumentProperties.Item("Test")

On Error GoTo 0 ' или туда, куда он был установлен ранее

......

Exit Sub

' ОБРАБОТЧИК(И) ОШИБОК

ReadCustomProperty:

Select Case Err.Number

Case 5

' Этот номер ошибки возникает, если пытаемся читать

' свойство, которое пока не создано

varProperty = "" ' или "Null" или "NoProperty" - как нравится

Resume Next ' возвращаем управление следующему оператору

' кстати, вместо возврата строки можно и свойство создать...

Case Else

' Вывод сообщений о других ошибках и прерывание программы

MsgBox(Err.Number & Chr(13) & Chr(13) & Err.Description)

Exit Sub

End Sub

Существенно, что при считывании значения свойства производится автоматическое приведение типа (если оно возможно), и считывание, например, числа в стоковую переменную не приводит к ошибке.

Если задан номер пользовательского свойства, то легко можно узнать все его свойства (извините за каламбур), для этого достаточно написать (пример цикла для всех свойств):

For Each prop In ActiveDocument.CustomDocumentProperties

With prop

MsgBox.Name & "= " &.Value & Chr(13) & _

"Application" & " = " &.Application & _

"Creator" & " = " &.Creator & _

"Parent" & "= " &.Parent

End With

Next

Для всей коллекции пользовательских свойств легко получить число определенных свойств:

ActiveDocument.CustomDocumentProperties.Count

Очевидно, что индекс в цикле перебора всех свойств может пробегать от 1 до этого значения.

Для ситуации, когда надо создать свойство, можно тоже написать обработчик ошибок, но логика его работы уже будет сильно зависеть от функциональности программы, в которой он используется. Поэтому он здесь не приводится, однако информации для его написания достаточно. Повторим, что код ошибки для ситуации повторного определения свойства с некоторым именем, равен -2147467259 (знак минус!, впрочем, "правильный" код 440).

Написал и прислал шаг Dmitri Drozdov.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: