Разработка и Конфигурация · 9 мин
ВерсияДанных в запросе 1С: что это и как использовать
Что такое ВерсияДанных в запросе 1С, зачем нужен этот реквизит, как получить его через запрос и применить для контроля конкурентного доступа к данным.
Реквизит ВерсияДанных есть у каждого объекта базы 1С, который хранится в виде сущности с ссылкой: справочника, документа, плана видов характеристик, плана счетов и других. Это служебное системное поле, которое платформа заполняет автоматически при каждой записи объекта. Разработчик не управляет его значением напрямую, но может прочитать его через запрос и использовать в своей логике.
По сути, ВерсияДанных — это метка состояния объекта. Пока объект не изменялся, версия остаётся одной и той же. Любая запись объекта (в том числе программная, без изменения видимых реквизитов) генерирует новую версию. Благодаря этому поле применяется для контроля конкурентного доступа: можно проверить, не успел ли кто-то изменить объект, пока пользователь редактировал его в форме или пока выполнялся длительный обмен данными.
В тексте запроса 1С поле доступно как обычный реквизит таблицы: Документ.РеализацияТоваровУслуг.ВерсияДанных. Тип значения — строка, представляющая собой закодированное внутреннее значение. Сравнивать версии между собой операциями «больше/меньше» бессмысленно — корректна только проверка на равенство или неравенство.
Что такое ВерсияДанных и как платформа её формирует
Каждый объект с ссылкой (элемент справочника, документ, элемент плана обмена и т.п.) хранит в таблице базы данных скрытое служебное поле версии. При первой записи объекта платформа присваивает ему начальную версию, а при каждой последующей записи — новую. Значение генерируется самой платформой, и разработчик не может задать его вручную или предсказать.
Важно понимать: версия меняется при любом вызове записи объекта, даже если ни один видимый реквизит фактически не изменился. Например, обработчик, который читает документ и сразу вызывает Записать(), создаст новую версию. Поэтому по смене версии нельзя судить, какие именно данные изменились, — можно лишь констатировать факт записи.
Как получить ВерсияДанных в запросе
В языке запросов поле доступно по имени ВерсияДанных у таблиц объектных сущностей. Запрос выглядит так же, как запрос любого другого реквизита:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка,
| Реализация.ВерсияДанных
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Тот же реквизит доступен и без запроса — у объекта встроенного языка: Объект.ВерсияДанных. Запрос нужен там, где требуется получить версии сразу множества объектов пакетно, не создавая объекты в памяти, — например, при выгрузке изменённых записей или при проверке группы документов перед обработкой.
Зачем нужна версия: контроль конкурентного доступа
Классический сценарий — оптимистичная блокировка. Пользователь открыл форму документа, система запомнила текущую версию. Пока пользователь редактировал данные, другой пользователь или фоновое задание записали тот же документ. При попытке записи платформа сравнивает запомненную версию с актуальной: если они различаются, возникает конфликт блокировок, и пользователь получает сообщение, что данные были изменены другим сеансом.
Тот же приём применяется вручную в прикладном коде: перед длительной обработкой объекта читают версию, после завершения расчётов — читают повторно. Если версии различаются, объект за время работы изменился, и результат обработки может быть неактуален.
- 1Получите ВерсияДанных запросом или из объекта до начала обработки
- 2Выполните необходимые расчёты или ожидание действий пользователя
- 3Повторно прочитайте ВерсияДанных по той же ссылке
- 4Сравните значения: равны — объект не менялся, различаются — объект перезаписывался
- 5При расхождении перечитайте данные объекта и повторите обработку либо сообщите о конфликте
Применение в обменах данными и интеграциях
В сценариях интеграции ВерсияДанных часто используют как критерий «что изменилось с прошлой выгрузки». Если механизм регистрации изменений (планы обмена) по каким-то причинам не подходит, разработчик может хранить последнюю известную версию каждой выгруженной ссылки и выгружать только те объекты, у которых версия изменилась.
Такой подход проще планов обмена, но у него есть ограничения: нужно хранить соответствие ссылок и версий во внешнем хранилище, а при потере этого соответствия придётся выполнять полную выгрузку. Также версия не подскажет, какие именно реквизиты изменились, — если внешняя система ждёт только изменения конкретных полей, потребуется дополнительное сравнение содержимого.
Способы отслеживания изменений
Простая проверка факта записи объекта. Подходит для ручного контроля и несложных интеграций. Не показывает, что именно изменилось, и требует хранить версии снаружи.
Штатная регистрация изменений на уровне платформы. Подходит для регулярных обменов между узлами. Требует настройки узлов и ведёт учёт по составу плана.
Позволяет хранить и просматривать содержимое версий объекта. Подходит для аудита, но требует включения и настройки механизма и расходует место в базе.
Ограничения и особенности работы с полем
Значение ВерсияДанных — внутренний формат платформы. Его нельзя интерпретировать как число или дату: нельзя сортировать объекты по версии, чтобы получить порядок изменений, и нельзя вычислить «возраст» изменения. Единственная допустимая операция — сравнение на равенство двух значений, полученных для одной и той же ссылки.
Также не стоит сравнивать версии разных объектов между собой или переносить логику сравнения между разными информационными базами — значения не имеют сквозного смысла. При выгрузке и загрузке данных через механизмы конвертации версия загруженного объекта будет сформирована заново в базе-приёмнике.
Как проверить поведение на практике
Быстрый способ убедиться в механике поля — выполнить в консоли запросов выборку версии конкретного документа, затем открыть этот документ, записать его без изменений и повторить запрос. Значение ВерсияДанных изменится, что наглядно демонстрирует: версия фиксирует факт записи, а не изменение содержимого.
При отладке интеграций полезно логировать версию вместе со ссылкой в момент выгрузки и в момент повторной проверки. Расхождение версий в журнале однозначно указывает, что объект записывался между двумя точками чтения, и помогает локализовать, какой сеанс или фоновое задание выполнил запись.
Как проверить результат
В выборке есть непустое строковое значение у каждой ссылки
Ошибка «Поле не найдено» — проверьте, что таблица запроса является ссылочным объектом, а не регистром
Значение совпадает с ранее полученным
Версия отличается — объект был записан другим сеансом или обработчиком
Версия изменилась — это нормальное поведение платформы
Версия осталась прежней — вероятно, запись фактически не выполнялась
Частые вопросы
Можно ли изменить ВерсияДанных вручную?
Нет. Поле полностью управляется платформой и доступно только для чтения как в запросах, так и во встроенном языке. Попытка присвоить значение этому свойству объекта не поддерживается.
Меняется ли версия при проведении документа?
Да. Проведение — это запись документа в режиме проведения, поэтому платформа формирует новую версию. То же относится к отмене проведения и пометке удаления.
Почему версия изменилась, хотя никто не редактировал объект?
Запись могла быть выполнена программно: фоновым заданием, обменом данными, обработчиком подписки на событие или кодом, который вызывает Записать() без изменения реквизитов. По смене версии виден сам факт записи, а не его источник.
Подходит ли ВерсияДанных для определения порядка изменений объектов?
Нет. Формат значения внутренний, и сравнение версий разных объектов или сортировка по этому полю не дают хронологии. Для отслеживания последовательности изменений используют дату документа, момент времени или механизмы регистрации изменений.
Как получить версии сразу для списка ссылок?
Одним запросом с условием «Ссылка В (&СписокСсылок)», передав массив или список значений параметром. Это эффективнее, чем создавать объект каждой ссылки в цикле и читать свойство ВерсияДанных по отдельности.
Сохраняется ли версия при выгрузке базы в dt и загрузке обратно?
Значения служебных полей при полной выгрузке-загрузке информационной базы переносятся, но полагаться на это в прикладной логике не стоит: любая последующая запись объекта сформирует новую версию. Для интеграций версии всегда следует перечитывать в актуальной базе.
Что важно запомнить
ВерсияДанных — системный реквизит ссылочных объектов 1С, автоматически меняющийся при каждой записи. В запросе его получают как обычное поле и используют только для сравнения на равенство: совпадение версий означает, что объект не перезаписывался, расхождение — что была запись. Для полноценного учёта изменений в обменах используют планы обмена, а для аудита содержимого — историю данных.