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