Аналогично свойству 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.