1

Тема: Идентификатор (ID) документа

Здравствуйте.

Кто пробовал организовать идентификацию документов? В частности, разных версий одного документа. Пишу код для самопроверки: тот ли это документ, или его уже подправили. Что-то типа контрольной суммы, но попроще и побыстрее. Никакого кода, внедряющего в документ всякие ID, быть не должно. Только код проверки. Word и сам автосохраняет в документе кучу всего.

Пока, думаю привязаться к BuiltInDocumentProperties, к какой-либо комбинации свойств wdPropertyBytes, wdPropertyTimeLastSaved, wdPropertyRevision. Может есть другие идеи?

Макросы под заказ и готовый пакет - mtdmacro.ru

2

Re: Идентификатор (ID) документа

Вождь пишет:

Пишу код для самопроверки: тот ли это документ, или его уже подправили. Что-то типа контрольной суммы, но попроще и побыстрее.

Вот пример подпрограммы, вычисляющей контрольную сумму (четыре 16-ричных символа). Источник - внешняя ссылка.
Использовать можно так: при закрытии файла (через событие Document_Close) вызывать подпрограмму подсчета контрольной суммы и результат записывать в подходящее свойство документа (одно из вами перечисленных), затем сохранять документ. При открытии документа (Document_Open) можно снова вычислять контрольную сумму и сравнивать с тем, что было сохранено ранее: если есть расхождение - то файл был изменен (и реагировать, как вам нужно, напр., сообщать об этом).  Разумеется, VBA-код закрытия и открытия должен срабатывать только у вас.
При желании можно найти аналогичный алгоритм и для 32-х, 64-х и т.д. вычисления контрольной суммы.
Вот VBA-код макроса (CRC16) и пример подпрограммы его использования (это упрощенный подход, правильнее, конечно, было бы обойти текст всех Story; кроме того, очевидно, что смена любой картинки в документе не отразится на его контрольной сумме) :

Sub test_crc16()
Dim scrc As String
scrc = CRC16(ActiveDocument.Range.Text)
End Sub

Function CRC16(txt As String)
Dim x As Long
Dim mask, i, j, nC, Crc As Integer
Dim c As String
Crc = &HFFFF
For nC = 1 To Len(txt)
    j = Val("&H" + Mid(txt, nC, 2))
    Crc = Crc Xor j
    For j = 1 To 8
        mask = 0
        If Crc / 2 <> Int(Crc / 2) Then mask = &HA001
        Crc = Int(Crc / 2) And &H7FFF: Crc = Crc Xor mask
    Next j
Next nC
CRC16 = Hex$(Crc)
End Function

3

Re: Идентификатор (ID) документа

Гм, странный подход. Не додумался бы считать CRC внутренностей документа smile Проще же CRC файла посчитать. Этот метод и медленный, и охватывает документ лишь частично.

Как я писал - главное скорость. Она должна быть почти нулевая. Не заметная глазу. Самопроверка будет идти при открытии документа. Планирую внедрить этот код в надстройку, чтобы сбрасывать ее опции. Как бы проверка версии проекта. Только за версией надо следить и где-то ее прописывать. А так, если правил документ (макросы, текст, переменные...), то этот код засечет изменения и сбросит настройки. Такая защита от забывчивости.

Макросы под заказ и готовый пакет - mtdmacro.ru

4

Re: Идентификатор (ID) документа

Вождь пишет:

Как я писал - главное скорость. Она должна быть почти нулевая. Не заметная глазу.

Можно найти в Интернете много утилит командной строки для снятия контрольной суммы файла, и они работают достаточно быстро. Напр., утилита HashMyFiles (внешняя ссылка). Такую утилиту можно вызывать из VBA-кода как утилиту командной строки с записью результата в файл с последующим чтением результата. А общий принцип применения - тот же )).

5

Re: Идентификатор (ID) документа

yshindin пишет:

...Можно найти в Интернете много утилит...

Можно, но зачем, если сам пишешь код smile

Надеялся найти какую-то встроенную опцию / параметр Word. Что-то вроде случайных чисел, что Word генерирует, когда активна опция Application.Options.StoreRSIDOnSave. Но все это можно очистить, сбросить, отключить.

Макросы под заказ и готовый пакет - mtdmacro.ru