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