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

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

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

Как программно записать документ в 1С: методы Записать(), режимы записи и проведения, обработка ошибок, транзакции и типичные ошибки разработчика с примерами кода.

Программная запись документа в 1С — базовая операция, которая встречается в обменах данными, обработках загрузки, автоматическом создании документов по расписанию и при интеграции с внешними системами. Несмотря на внешнюю простоту вызова метода Записать(), у этой операции есть важные нюансы: режимы записи, проведение, проверка заполнения, транзакционность и права доступа.

Ошибка в коде записи может привести к непроведённым документам, потерянным движениям по регистрам или даже к блокировкам базы при массовой загрузке. Поэтому важно понимать не только синтаксис, но и поведение платформы при разных сценариях записи.

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

Создание объекта документа и его заполнение

Любая программная запись начинается с получения объекта документа. Для нового документа используется метод СоздатьДокумент() менеджера документов, для существующего — получение объекта через ссылку методом ПолучитьОбъект().

После создания объекта заполняются реквизиты шапки и табличные части. Пока не вызван метод Записать(), все изменения существуют только в памяти и в базу данных не попадают.

НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

НовыйДокумент.Дата = ТекущаяДатаСеанса();

НовыйДокумент.Организация = Организация;

НовыйДокумент.Контрагент = Контрагент;

НовыйДокумент.Склад = Склад;

НоваяСтрока = НовыйДокумент.Товары.Добавить();

НоваяСтрока.Номенклатура = Номенклатура;

НоваяСтрока.Количество = 5;

НоваяСтрока.Цена = 1200;

НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;

НовыйДокумент.Записать();

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

Режимы записи: простая запись, проведение и отмена проведения

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

Режимы записи документа

РежимЗаписиДокумента.Запись

Документ сохраняется без проведения, движения по регистрам не формируются. Подходит для черновиков и загрузки без отражения в учёте.

РежимЗаписиДокумента.Проведение

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

РежимЗаписиДокумента.ОтменаПроведения

Снимает документ с проведения и удаляет его движения. Применяется при исправлении или удалении ранее проведённых документов.

Пример записи с проведением:

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

Если документ уже проведён и нужно просто перезаписать его реквизиты без повторного проведения, используйте РежимЗаписиДокумента.Запись — в противном случае платформа выполнит проведение повторно, что может вызвать ошибки контроля остатков.

Дополнительно метод принимает параметр РежимПроведенияДокумента — оперативный или неоперативный. Оперативное проведение доступно только для документов с текущей датой и выполняет контроль остатков в реальном времени.

Запись существующего документа и изменение реквизитов

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

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

ДокументОбъект.Комментарий = "Скорректировано программно";

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

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

Проверка заполнения и обработка ошибок

Перед записью с проведением желательно вызвать метод ПроверитьЗаполнение(). Он выполняет ту же проверку обязательных реквизитов, что и интерактивное проведение, и возвращает Ложь, если данные неполные.

Если Не ДокументОбъект.ПроверитьЗаполнение() Тогда

ВызватьИсключение "Документ не заполнен корректно";

КонецЕсли;

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

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

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

Запись в транзакции при массовой загрузке

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

НачатьТранзакцию();

Попытка

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

// запись связанных объектов

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ЗаписьЖурналаРегистрации("Загрузка документов",

УровеньЖурналаРегистрации.Ошибка, , ,

ОписаниеОшибки());

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

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

При массовой загрузке полезно записывать документы сначала в режиме Запись, а проведение выполнять отдельным проходом. Так проще локализовать ошибки: сначала проверяется корректность данных, затем — возможность проведения по остаткам и периодам.
ПЗ
Практическое замечание

Особенности: обмен данными, права и подписки на события

При записи из механизмов обмена данными установите ДокументОбъект.ОбменДанными.Загрузка = Истина. Это отключает бизнес-логику проверок и подписки на события, что ускоряет загрузку, но требует, чтобы данные были гарантированно корректны — платформа не выполнит контроль.

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

Подписки на события ПриЗаписи и ОбработкаПроведения выполняются при программной записи так же, как при интерактивной. Если в подписках есть обращения к интерактивным элементам (например, вопросы пользователю), фоновая запись завершится ошибкой — такие места нужно находить и дорабатывать заранее.

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

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

Документ появился в списке
Норма

Документ виден в журнале с нужной датой и номером

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

Документа нет — запись завершилась исключением или откатом транзакции

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

У документа установлен признак проведения, движения есть в регистрах

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

Документ записан, но не проведён — проверьте режим записи и ошибки проведения

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

Наборы записей регистров содержат строки этого документа

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

Движений нет — проведение не выполнялось или обработчик проведения не сработал

Журнал регистрации
Норма

Нет ошибок, связанных с сеансом записи

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

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

Порядок безопасной программной записи

Порядок действий
  1. 1
    Протестируйте код на копии рабочей базы и убедитесь в корректности создаваемых документов.
  2. 2
    Создайте объект документа через СоздатьДокумент() или получите существующий через ПолучитьОбъект().
  3. 3
    Заполните обязательные реквизиты шапки и табличные части, явно задайте дату.
  4. 4
    Вызовите ПроверитьЗаполнение() и обработайте отрицательный результат.
  5. 5
    Выполните Записать() с нужным режимом внутри транзакции с блоком Попытка...Исключение.
  6. 6
    Проверьте результат: наличие документа, признак проведения и движения по регистрам.
  7. 7
    Зафиксируйте ошибки в журнале регистрации для последующего анализа.

Соблюдение этой последовательности позволяет записывать документы программно предсказуемо и безопасно. Основные риски — отсутствие обработки ошибок и неверный выбор режима записи — полностью закрываются проверкой заполнения и транзакциями.

Итог

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

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

Частые вопросы о программной записи документов

Чем отличается Записать() от Провести()?

У объекта документа нет отдельного метода Провести() — проведение выполняется тем же методом Записать() с параметром РежимЗаписиДокумента.Проведение. Простой вызов Записать() без параметров сохраняет документ без проведения и без движений по регистрам.

Почему документ записывается, но не проводится, и ошибки нет?

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

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

Явно присвойте реквизиту Дата нужное значение после создания объекта и до вызова Записать(). Если дату не задать, платформа подставит текущую дату сеанса в момент записи.

Как отменить проведение документа программно?

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

Что делать при ошибке «Конфликт блокировок» при массовой записи?

Ошибка означает, что документ или связанные данные заняты другим сеансом. Уменьшите размер транзакций, добавьте повторные попытки записи с паузой и выполняйте загрузку в период минимальной активности пользователей.

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

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