К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как программно перезаписать документ в 1С

Как программно перезаписать документ в 1С: ПолучитьОбъект, Записать, режимы проведения, обход блокировок, массовая перезапись и типичные ошибки разработчика.

Программная перезапись документа — одна из самых частых задач при доработке конфигураций 1С: она нужна для обновления движений, пересчёта итогов, исправления данных после обмена и массовой обработки документов. В отличие от интерактивной записи, программная требует явного управления режимом записи, проверкой прав и обработкой блокировок.

Базовый сценарий одинаков в любой конфигурации: получить объект документа по ссылке, при необходимости изменить реквизиты и вызвать метод Записать() с нужным режимом. Однако детали — режим проведения, загрузка, транзакционность, блокировки — определяют, будет ли результат корректным и безопасным для данных.

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

Как работает программная запись документа

В 1С различают ссылку на документ и объект документа. Ссылка — это лёгкий идентификатор, через который доступны только реквизиты для чтения. Чтобы изменить и записать документ, нужно получить его объектную представление методом ПолучитьОбъект(). Именно объект загружает данные в память и поддерживает метод Записать().

Метод Записать() принимает параметр режима записи. Для документов доступны три основных варианта: РежимЗаписиДокумента.Запись (простое сохранение без проведения), РежимЗаписиДокумента.Проведение (запись с формированием движений) и РежимЗаписиДокумента.ОтменаПроведения. Выбор режима определяет, что произойдёт с движениями по регистрам.

Важно понимать: перезапись проведённого документа в режиме «Запись» не пересоздаёт движения — они остаются прежними. Если цель — обновить движения по изменённым данным, используйте режим «Проведение».

Базовый пример: перезаписать один документ

Минимальный код для перезаписи документа без изменения данных выглядит так:

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

Если нужно изменить реквизит и перепровести документ:

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ДокументОбъект.Комментарий = "Перезаписан обработкой";

ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

Если документ не проведён, вызов с режимом «Проведение» вызовет ошибку. Поэтому перед записью полезно проверять свойство Проведен и выбирать режим динамически:

Если ДокументОбъект.Проведен Тогда

ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

Иначе

ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

КонецЕсли;

Массовая перезапись документов за период

Типовая задача — перепровести все документы определённого вида за период. Для этого выборка выполняется запросом, а запись идёт в цикле с обработкой ошибок:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка КАК Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &КонецПериода

| И РеализацияТоваровУслуг.Проведен";

Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);

Запрос.УстановитьПараметр("КонецПериода", КонецПериода);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Попытка

ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();

ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

Исключение

Сообщить("Ошибка: " + Выборка.Ссылка + " — " + ОписаниеОшибки());

КонецПопытки;

КонецЦикла;

Обёртка в Попытка...Исключение критична: один проблемный документ (незаполненный реквизит, отрицательные остатки, блокировка) не должен прерывать всю обработку. Ошибки собирайте в журнал или таблицу значений для последующего разбора.

При больших объёмах учитывайте, что перепроведение меняет последовательности и границы итогов. В конфигурациях с механизмом последовательностей массовое перепроведение корректнее выполнять штатной обработкой «Проведение документов» или методом восстановления последовательностей, а не простым циклом.

Порядок массовой перезаписи
  1. 1
    Сделайте резервную копию базы или протестируйте на копии
  2. 2
    Сформируйте запросом список документов за нужный период
  3. 3
    В цикле получайте объект и записывайте с нужным режимом внутри Попытка/Исключение
  4. 4
    Фиксируйте ошибки по каждому документу в журнал
  5. 5
    После завершения проверьте движения и итоги по контрольным документам

Режимы записи и их влияние на движения

Выбор режима — главный источник различий в поведении. Сопоставление в таблице помогает выбрать правильный вариант под задачу.

РежимЧто происходитКогда применять
ЗаписьСохраняет реквизиты, движения не пересоздаютсяИсправление комментария, ответственного, реквизитов, не влияющих на проведение
ПроведениеЗапись и полное пересоздание движений по регистрамОбновление движений после изменения данных или исправления ошибок
ОтменаПроведенияДокумент остаётся в базе, движения удаляютсяВременное отключение документа из учёта без пометки удаления

Дополнительно метод Записать() принимает второй параметр — режим проведения: РежимПроведенияДокумента.Оперативный или Неоперативный. Оперативное проведение контролирует остатки на текущий момент и доступно только для документов с текущей датой; при массовом перепроведении прошлых периодов используется неоперативный режим.

Маршрут решения

Как выбрать режим

Нужно только исправить реквизит, не трогая движенияИспользуйте РежимЗаписиДокумента.Запись
Изменились данные, влияющие на учёт, и нужно обновить движенияИспользуйте РежимЗаписиДокумента.Проведение
Документ прошлым периодом и контроль остатков мешаетПерепроводите в неоперативном режиме
Перезапись идёт при загрузке данных из обменаУстановите ОбменДанными.Загрузка = Истина перед записью

Запись в режиме загрузки и обход проверок

При переносе данных или массовых технических обработках часто нужно записать документ, минуя бизнес-проверки и обработчики. Для этого перед записью устанавливается признак загрузки:

ДокументОбъект.ОбменДанными.Загрузка = Истина;

ДокументОбъект.Записать();

В режиме загрузки не выполняются обработчики ОбработкаПроверкиЗаполнения, ПриЗаписи и ряд других событий. Это ускоряет запись и позволяет сохранить документ с неполными данными, но перекладывает ответственность за корректность на разработчика.

Использовать режим загрузки для обычного перепроведения нельзя: движения в этом режиме не формируются штатной логикой проведения, и учётные данные могут разойтись с реальностью. Режим предназначен именно для загрузки данных при обменах и первоначальном заполнении.

Блокировки, права и транзакции

При вызове ПолучитьОбъект() платформа автоматически устанавливает управляемую блокировку на документ. Если другой пользователь или сеанс уже редактирует этот документ, попытка записи завершится ошибкой «Конфликт блокировок». В массовых обработках такие ситуации нужно перехватывать и повторять позже или пропускать с записью в журнал.

Права проверяются автоматически: если у пользователя, под которым выполняется код, нет права на изменение или проведение документа, запись завершится ошибкой. В привилегированном модуле (УстановитьПривилегированныйРежим(Истина)) проверка прав отключается — это удобно для регламентных заданий, но требует контроля со стороны разработчика.

Для групповой записи, где недопустимо частичное выполнение, используйте явную транзакцию: НачатьТранзакцию(), запись всех объектов, ЗафиксироватьТранзакцию() либо ОтменитьТранзакцию() при ошибке. Учтите, что длинные транзакции держат блокировки и могут мешать работе пользователей.

Типичные ошибки
01
Вызов Записать() у ссылки вместо объекта — метод недоступен, возникает ошибка исполнения
02
Перепроведение непроведённого документа режимом Проведение без проверки свойства Проведен
03
Игнорирование ошибок блокировок в цикле — обработка падает на первом занятом документе
04
Использование ОбменДанными.Загрузка для перепроведения — движения не формируются, учёт расходится
05
Массовая обработка без Попытка/Исключение и журнала — невозможно понять, какие документы не записались

Как проверить результат перезаписи

После одиночной перезаписи откройте документ в пользовательском режиме и проверьте изменённые реквизиты. Для перепроведения дополнительно откройте движения документа (кнопка «Дт/кт» или отчёт по движениям) и убедитесь, что записи по регистрам соответствуют ожиданиям.

После массовой обработки сверьте итоги: сравните обороты по ключевым регистрам (остатки товаров, взаиморасчёты) до и после перепроведения. Расхождения должны объясняться реальными изменениями данных, а не сбоями обработки.

Для программной проверки можно перечитать объект после записи и сравнить значения контрольных реквизитов, а также проверить количество записей в наборах движений через ДокументОбъект.Движения.

Контрольные точки

Как проверить результат

Статус проведения документа
Норма

Свойство Проведен соответствует ожидаемому после записи

Тревожный признак

Документ остался непроведённым или распровёлся неожиданно

Движения по регистрам
Норма

Наборы записей сформированы и совпадают с данными документа

Тревожный признак

Движения пусты или содержат устаревшие суммы

Журнал ошибок обработки
Норма

Все документы из выборки записаны без исключений

Тревожный признак

Есть документы с ошибками блокировки или проверки заполнения

Итоги по регистрам за период
Норма

Обороты и остатки объяснимы изменёнными данными

Тревожный признак

Необъяснимые скачки сумм после перепроведения

Частые вопросы

Чем перезапись отличается от перепроведения?

Перезапись — это вызов Записать() в режиме «Запись»: сохраняются только реквизиты документа, движения не трогаются. Перепроведение — запись в режиме «Проведение»: движения по всем регистрам удаляются и создаются заново по текущим данным документа.

Можно ли перезаписать документ, не открывая транзакцию явно?

Да, метод Записать() сам выполняется в неявной транзакции — документ либо запишется целиком, либо не запишется вовсе. Явная транзакция нужна только когда требуется атомарно записать несколько объектов.

Как перезаписать помеченный на удаление документ?

Получите объект и снимите пометку методом УстановитьПометкуУдаления(Ложь), после чего записывайте в нужном режиме. Провести документ с установленной пометкой удаления нельзя — платформа выдаст ошибку.

Почему возникает ошибка «Конфликт блокировок при выполнении транзакции»?

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

Что быстрее для массовой обработки: ПолучитьОбъект или запрос к движениям?

Для полноценной перезаписи с перепроведением без ПолучитьОбъект() не обойтись. Если же нужно только обновить отдельный реквизит без перепроведения, всё равно требуется объект — но можно сократить время, отключив проверки через ОбменДанными.Загрузка, если это допустимо по логике задачи.

Можно ли перезаписать документ из внешней обработки без изменения конфигурации?

Да. Внешняя обработка с кодом на встроенном языке может получать объекты документов и записывать их — для этого достаточно прав на изменение соответствующих документов у пользователя, запускающего обработку.

Итог

Что важно запомнить

Программная перезапись сводится к трём шагам: ПолучитьОбъект(), изменение данных, Записать() с правильным режимом. Режим «Запись» сохраняет реквизиты без движений, «Проведение» пересоздаёт движения. При массовой обработке обязательны обработка ошибок, журнал и тест на копии базы.