Как программно провести документ в 1С без открытия формы и обойти ошибку расчета скидок?

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

При разработке интеграций, обменов данными или автоматических обработок в среде «1С:Предприятие 8» разработчики часто сталкиваются со следующей проблемой. При попытке программно провести документ (например, Реализация товаров и услуг, созданный на основании документа Заказ клиента), система выдает ошибку: «В документе не рассчитаны автоматические скидки (наценки). Проведение невозможно. Для расчёта автоматических скидок (наценок) проведите документ из формы документа». При этом интерактивно (через форму) документ проводится без каких-либо замечаний.

В этой статье мы подробно разберем, почему возникает эта разница между интерактивным и программным проведением в современных типовых конфигурациях (таких как УТ 11, КА 2, ERP 2), рассмотрим быстрые и методологически правильные способы обхода этой проверки, а также выясним, можно ли эмулировать действия пользователя на форме без ее фактического открытия. При настройке постоянной синхронизации между такими базами может потребоваться программа для автоматизации регулярного обмена данными по расписанию.

Почему возникает разница между интерактивным и программным проведением?

Для начала проанализируем архитектуру работы управляемых форм в 1С. Когда пользователь работает в интерфейсе программы и нажимает кнопку «Провести», система запускает целую цепочку клиент-серверных событий. В процессе интерактивной работы на форме выполняются специализированные обработчики ожидания, проверки заполнения экранных полей и, самое главное, процедуры расчета цен, скидок и наценок. Эти процедуры заполняют скрытые служебные таблицы документа и взводят специальный флаг-реквизит документа СкидкиРассчитаны в значение Истина.

Когда же мы вызываем проведение программно, напрямую обращаясь к объекту базы данных:

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

Код управляемой формы вообще не инициализируется и не выполняется. Платформа работает напрямую с данными. Однако в модуле объекта (в обработчике ПередЗаписью или ОбработкаПроверкиЗаполнения) стандартных конфигураций прописана жесткая проверка: если реквизит СкидкиРассчитаны равен Ложь, проведение прерывается с ошибкой. Это сделано для того, чтобы исключить проведение документов с некорректной (неактуальной) стоимостью товаров.

Рассмотрим подробнее три основных способа обхода и решения этой проблемы.

Способ 1. Быстрый обход проверки (установка флага «вручную»)

Если в вашем бизнес-процессе скидки уже были рассчитаны на этапе оформления Заказа клиента, и вы просто копируете данные один к одному в документ Реализация товаров и услуг, то повторный пересчет скидок вам не требуется. В этом случае самым быстрым и простым решением будет принудительная установка признака рассчитанных скидок перед записью объекта.

Разберем пример кода для реализации этого подхода:


// Создаем или получаем объект документа реализации
ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// ... здесь выполняется заполнение реквизитов и табличных частей ...

// Взводим флаг, сообщающий системе, что скидки актуальны
ДокументОбъект.СкидкиРассчитаны = Истина;

// Теперь документ запишется и проведется без ошибок
Попытка
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
    ЗаписьЖурналаРегистрации("ПрограммноеПроведение", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

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

Способ 2. Использование режима обмена данными (радикальный путь)

Если вам нужно провести документ «любой ценой», минуя вообще все проверки модуля объекта (включая не только проверку скидок, но и контроль остатков, проверку заполнения графиков оплаты и т.д.), можно задействовать встроенный механизм платформы 1С — режим загрузки данных.

Посмотрим на пример реализации данного метода:


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

Этот способ отключает выполнение практически всех стандартных проверок в процедурах ПередЗаписью и ПриЗаписи. Однако использовать его в реальных бизнес-сценариях крайне опасно. Вы рискуете записать некорректные данные, обойти важный оперативный контроль остатков на складах и нарушить логику партионного учета. Настоятельно рекомендуем избегать этого метода для регулярных операций.

Способ 3. Методологически правильный программный расчет автоматических скидок

Если документ создается с изменениями (например, вы оформляете частичную отгрузку по заказу, где из 10 позиций отгружается только 3), условия предоставления автоматических скидок могут полностью измениться (например, порог объема для оптовой скидки больше не достигается). В этом случае скидки необходимо пересчитать программно.

Для этого в типовых конфигурациях 1С предусмотрен специальный экспортный метод в общем модуле СкидкиНаценкиСервер. Нам не нужно открывать форму — мы можем вызвать этот серверный метод напрямую.

Давайте разберем по шагам, как правильно подготовить параметры и выполнить расчет:


// 1. Инициализируем и заполняем документ на основании заказа
ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
ДокументОбъект.Заполнить(ДокументОснование);

// 2. Подготавливаем структуру параметров, которую ожидает типовой механизм скидок
ПараметрыРасчета = Новый Структура;
ПараметрыРасчета.Вставить("ПрименятьКОбъекту", Истина);
ПараметрыРасчета.Вставить("ТолькоПредварительныйРасчет", Ложь);
ПараметрыРасчета.Вставить("ВосстанавливатьУправляемыеСкидки", Истина);
ПараметрыРасчета.Вставить("УправляемыеСкидки", Новый Соответствие); 

// 3. Вызываем расчет скидок через типовой серверный модуль
// Этот метод сам заполнит необходимые ТЧ скидок и установит флаг СкидкиРассчитаны в Истина
СкидкиНаценкиСервер.Рассчитать(ДокументОбъект, ПараметрыРасчета);

// 4. Безопасно проводим документ
Попытка
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
    Сообщить("Документ " + ДокументОбъект.Ссылка + " успешно проведен!");
Исключение
    Сообщить("Ошибка проведения: " + ОписаниеОшибки());
КонецПопытки;

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

Можно ли эмулировать интерактивные действия на форме без ее открытия?

В процессе обсуждения данной проблемы у многих начинающих разработчиков возникает закономерный вопрос: а можно ли вообще программно сымитировать нажатие кнопок на управляемой форме (например, кнопки «Рассчитать скидки» или «Провести»), вообще не открывая саму форму на экране компьютера?

Выясним техническую сторону этого вопроса:

  1. В рамках обычной работы сеанса пользователя: Нет, это невозможно. Если форма не создана и не открыта, ее контекст (клиентские переменные, элементы управления, привязанные обработчики) физически отсутствует в оперативной памяти компьютера. Обратиться к экспортным процедурам модуля формы, не инициализировав саму форму, платформа 1С не позволяет. Для имитации действий человека в интерфейсе без изменения программного кода может использоваться платформа для создания программных роботов с визуальным конструктором сценариев.
  2. Сценарное тестирование: В платформе 1С существует специализированный механизм автоматизированного тестирования (запуск системы с ключом /TestClient). Специальный сценарий может запускать программу, открывать формы документов, вводить текстовые данные в поля и эмулировать клики по кнопкам. Однако этот инструмент предназначен строго для автоматического тестирования качества кода (QA) разработчиками. Он работает крайне медленно, требует запущенного графического сеанса Windows и абсолютно непригоден для фонового проведения документов в реальной рабочей базе.
  3. Правильный архитектурный подход (MVC): Если вам приходится задумываться о вызове кода из формы без ее открытия, это первый признак архитектурной ошибки проектирования конфигурации. Вся ключевая бизнес-логика (расчеты, заполнения, проверки) должна быть вынесена в модуль объекта или в серверные общие модули. Клиентская управляемая форма должна служить исключительно интерфейсным «пультом управления», который просто собирает команды пользователя и передает их на выполнение серверным механизмам.

Таким образом, если вы сталкиваетесь с ситуацией, когда важная логика «заперта» внутри модуля формы сторонней доработки, правильным решением будет перенос этой логики в общий модуль (например, через механизм расширений конфигурации), а не попытка эмулировать интерактивное нажатие клавиш.

← На главную