В практике программирования на платформе 1С:Предприятие часто возникает задача автоматического создания документов. Это может потребоваться при загрузке данных из сторонних систем (Excel, XML, JSON), при создании связанных документов (например, на основании заказа) или при пакетной обработке данных. Рассмотрим подробно, как правильно создать документ, заполнить его реквизиты и табличную часть, а затем провести его в базе данных.
Процесс создания документа можно разделить на несколько ключевых этапов, которые мы разберем последовательно:
Проанализируем каждый шаг детально, обращая внимание на важные нюансы работы с объектной моделью 1С.
Для начала работы нам необходимо создать новый экземпляр объекта документа в оперативной памяти. Для этого используется менеджер документа и метод СоздатьДокумент(). Этот метод возвращает объект, доступный для записи и изменения. Важно понимать, что в этот момент в базе данных запись еще не появляется.
Разберем пример создания документа "Поступление товаров и услуг". Обратите внимание, что имя объекта в конфигураторе (в данном примере ПоступлениеТоваровУслуг) должно точно совпадать с тем, что мы пишем в коде.
// Создаем новый объект документа
НовыйДокумент = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
// Устанавливаем дату и время документа
НовыйДокумент.Дата = ТекущаяДата();
// Можно использовать метод Заполнить() для установки значений по умолчанию,
// если логика заполнения прописана в модуле документа
// НовыйДокумент.Заполнить(ПараметрыЗаполнения);
Важный момент: Если вы создаете документ "задним числом", обязательно явно указывайте время, иначе система установит начало дня (00:00:00), что может нарушить последовательность проведения документов.
После создания объекта необходимо заполнить его обязательные реквизиты. Обычно это Организация, Контрагент, Договор, Склад и Валюта. Посмотрим, как это делается. Предположим, что ссылки на нужные справочники мы уже нашли или получили ранее.
// Заполняем основные реквизиты
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Основная фирма");
НовыйДокумент.Контрагент = Справочники.Контрагенты.НайтиПоКоду("00000123");
НовыйДокумент.Склад = Справочники.Склады.НайтиПоНаименованию("Главный склад");
// Если в документе есть комментарий, заполним и его
НовыйДокумент.Комментарий = "Создано программно обработкой загрузки";
Рекомендуем всегда проверять заполнение обязательных полей. Если, например, Контрагент не будет найден и поле останется пустым, при попытке проведения система выдаст ошибку.
Самый ответственный этап — заполнение списка товаров. Рассмотрим метод Добавить(), который создает новую строку в табличной части. В нашем примере табличная часть называется Товары.
В цикле перебора данных (например, из массива структур или выборки запроса) мы будем добавлять новые строки и заполнять их свойства.
// Предположим, у нас есть массив данных для загрузки - МассивТоваров
Для Каждого СтрокаДанных Из МассивТоваров Цикл
// Добавляем новую строку в табличную часть "Товары"
НоваяСтрокаТЧ = НовыйДокумент.Товары.Добавить();
// Заполняем реквизиты строки
НоваяСтрокаТЧ.Номенклатура = СтрокаДанных.Номенклатура;
НоваяСтрокаТЧ.Количество = СтрокаДанных.Количество;
НоваяСтрокаТЧ.Цена = СтрокаДанных.Цена;
// Рассчитываем сумму
НоваяСтрокаТЧ.Сумма = НоваяСтрокаТЧ.Количество * НоваяСтрокаТЧ.Цена;
// Если есть учет НДС, нужно заполнить ставку и сумму НДС
НоваяСтрокаТЧ.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
НоваяСтрокаТЧ.СуммаНДС = НоваяСтрокаТЧ.Сумма * 0.2; // Упрощенный расчет
КонецЦикла;
Также существует альтернативный метод Загрузить(). Он позволяет заполнить табличную часть целиком из Таблицы Значений, если имена колонок совпадают. Это работает быстрее, чем добавление строк в цикле.
// Пример быстрой загрузки, если у вас уже подготовлена ТаблицаЗначений (ТЗ)
// Колонки ТЗ должны совпадать с именами реквизитов табличной части
НовыйДокумент.Товары.Загрузить(ТЗТовары);
Финальный этап — сохранение документа в базе данных. Здесь есть два варианта:
Используем метод Записать(), принимающий в качестве параметра режим записи. Крайне важно обернуть этот процесс в конструкцию Попытка ... Исключение, так как при проведении могут возникнуть ошибки (нехватка товара, незаполненные реквизиты, блокировки).
Попытка
// РежимЗаписиДокумента.Проведение - документ будет проведен
// РежимЗаписиДокумента.Запись - просто записан (черновик)
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ успешно создан и проведен: " + НовыйДокумент.Ссылка);
Исключение
// Выводим информацию об ошибке, если что-то пошло не так
Сообщить("Не удалось провести документ. Ошибка: " + ОписаниеОшибки());
// Можно попробовать записать без проведения, чтобы не потерять данные
Попытка
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ сохранен как черновик.");
Исключение
Сообщить("Критическая ошибка сохранения.");
КонецПопытки;
КонецПопытки;
Рассмотрим несколько нюансов, которые помогут сделать ваш код надежнее и быстрее:
1. Отключение проверки заполнения
Иногда при программном создании нужно записать документ, даже если не все обязательные поля заполнены (например, для последующей ручной доработки). Для этого используйте свойство ОбменДанными.Загрузка = Истина. Это отключает стандартные проверки платформы при записи.
НовыйДокумент.ОбменДанными.Загрузка = Истина;
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
2. Использование транзакций
Если вы создаете сразу много документов (пакетная обработка), обязательно используйте транзакции. Это ускорит работу и обеспечит целостность данных: либо запишутся все документы, либо ни одного.
НачатьТранзакцию();
Попытка
// ... цикл создания документов ...
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Сообщить("Ошибка при пакетном создании: " + ОписаниеОшибки());
КонецПопытки;
3. Поиск дублей
Перед созданием нового документа хорошей практикой является проверка: а не существует ли он уже? Обычно поиск выполняют по внешнему номеру (номеру из файла источника) и дате. Для этого используйте запросы к базе данных перед вызовом СоздатьДокумент().
Следуя этим инструкциям, вы сможете корректно автоматизировать процесс ввода документов, избежав распространенных ошибок формата потока данных и нарушения ссылочной целостности.