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

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке внешних интеграций на языке C# часто возникает задача программного создания документов в 1С. Одной из самых популярных операций является создание «на основании», когда один документ (например, Реализация товаров и услуг) должен быть заполнен данными другого документа (например, Заказа покупателя). Однако при использовании технологии COM-соединения начинающие разработчики часто сталкиваются с ситуацией, когда новый документ создается, но остается абсолютно пустым. Разберем по шагам, почему это происходит и как правильно написать код для автоматизации этого процесса.

Анализ проблемы: почему метод Заполнить() не отрабатывает

Рассмотрим ситуацию, с которой столкнулся автор темы. Он успешно подключается к базе 1С через V82.COMConnector, находит нужный заказ, проводит его, а затем пытается создать реализацию. Проблема скрыта в следующей строке кода:

refer1.Заполнить(order);

В данном контексте переменная order является объектом типа ДокументОбъект (так как она была получена методом ПолучитьОбъект()). Метод Заполнить() в платформе 1С инициирует системное событие ОбработкаЗаполнения, которое прописано в модуле объекта создаваемого документа. Нюанс заключается в том, что стандартные механизмы 1С ожидают в качестве параметра ссылку на документ-основание (тип ДокументСсылка), а не сам объект документа, находящийся в оперативной памяти.

Когда вы передаете в 1С через COM-обертку весь объект целиком, внутренняя проверка типов в процедуре ОбработкаЗаполнения часто не может распознать переданные данные или считает их некорректными. В результате код внутри 1С просто не выполняется, и документ остается незаполненным. При этом 1С не всегда выбрасывает исключение во внешнюю среду, и программа на C# продолжает работу, создавая «пустышку».

Правильное решение и исправление кода

Для того чтобы 1С корректно отработала заполнение, необходимо явно указать свойство Ссылка. Проанализируем исправленный вариант ключевого участка кода:


// Получаем ссылку на заказ (refer) и сам объект (order)
dynamic refer = connection1с.Документы.ЗаказПокупателя.НайтиПоНомеру(New_Order_Number, New_Order_Style_Ok_Data);
dynamic order = refer.ПолучитьОбъект();

// Проводим заказ (если это необходимо)
order.Записать(connection1с.РежимЗаписиДокумента.Проведение);

// Создаем реализацию
dynamic refer1 = connection1с.Документы.РеализацияТоваровУслуг.СоздатьДокумент();
refer1.Дата = New_Order_Style_Ok_Data;

// ВАЖНО: передаем именно Ссылку, а не Объект
refer1.Заполнить(order.Ссылка); 

// Либо можно передать переменную refer, которая уже является ссылкой
// refer1.Заполнить(refer);

refer1.Записать(connection1с.РежимЗаписиДокумента.Запись);

В этом случае 1С получает типизированную ссылку ДокументСсылка.ЗаказПокупателя, успешно находит ее в базе данных внутри обработчика заполнения и переносит все товары, услуги и контрагентов в новый документ реализации.

Разбор нюансов работы с COM-соединением

Работа с 1С через COM имеет свои архитектурные особенности, которые важно учитывать для обеспечения стабильности приложения. Рассмотрим дополнительные рекомендации, которые помогут избежать ошибок в будущем.

  1. Синхронность операций: В исходном коде автора использовалась задержка Task.Delay(10000). Выясним причину, почему это лишнее. Метод 1С Записать(РежимЗаписиДокумента.Проведение) является синхронным. Это значит, что управление не вернется в ваш C#-код до тех пор, пока 1С полностью не завершит запись и проведение документа со всеми движениями по регистрам. Использование искусственных пауз только замедляет работу системы.
  2. Проверка на пустую ссылку: Перед тем как вызывать ПолучитьОбъект(), всегда полезно проверить, был ли вообще найден документ. В 1С метод НайтиПоНомеру в случае неудачи возвращает пустую ссылку, а не null.
    
    if (refer.Пустая()) {
        throw new Exception("Заказ с таким номером не найден!");
    }
    
  3. Управление памятью: COM-объекты 1С не всегда корректно очищаются сборщиком мусора .NET (Garbage Collector). Если ваше приложение создает много соединений, это приведет к утечке памяти и зависшим процессам 1cv8.exe на сервере. Рекомендуется использовать метод Marshal.ReleaseComObject для каждой переменной, содержащей COM-объект 1С, после завершения работы.

Альтернативные методы интеграции

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

Если ваша конфигурация 1С позволяет, рассмотрите следующие современные подходы:

Заключение

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

← На главную