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