Как сделать отладку внешней скидки в управляемых формах 1С?

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

Разработка и отладка внешних скидок (наценок) и условий их предоставления в современных конфигурациях 1С (таких как «Управление торговлей 11», «ERP Управление предприятием» или «Комплексная автоматизация») часто вызывает трудности у разработчиков. Это связано с тем, что механизмы Библиотеки Стандартных Подсистем (БСП) подключают внешние обработки в безопасном режиме и используют объектную модель работы через временное хранилище, минуя создание физических файлов на диске. В результате стандартные точки останова в конфигураторе просто не срабатывают.

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

Анализ архитектурной проблемы: почему не работает обычная отладка?

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

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

Кроме того, если внешняя обработка запущена в безопасном режиме, платформа накладывает жесткие ограничения на выполнение кода, что также блокирует механизмы отладки.

Разбор типичной ошибки в коде условия предоставления скидки

Давайте проанализируем реальный пример кода, представленный в обсуждении темы. Разработчик пытается реализовать условие скидки по конкретному партнеру (контрагенту) и сталкивается с тем, что скидка не срабатывает. Посмотрим на этот фрагмент кода:


Для Каждого СтрокаТовара Из СтрокаДереваСкидок Цикл
    Если ПартнерДокумента = ПараметрыВнешнейОбработки.Контрагент Тогда
        СтрокаТовара.УсловиеПоСтрокеВыполнено = Истина;
        ТекущееУсловиеВыполнено = Истина;
    КонецЕсли;
КонецЦикла;

В данном фрагменте содержатся сразу две критические ошибки:

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

Давайте исправим эту логику и напишем корректный шаблон функции ПроверитьУсловие, который будет устойчив к ошибкам и пригоден для дальнейшей отладки:


Функция ПроверитьУсловие(Условие, СтрокаДереваСкидок, ПараметрыВнешнейОбработки, ПараметрыРасчета) Экспорт
    
    РезультатПроверки = Новый Структура;
    ТекущееУсловиеВыполнено = Ложь;
    
    // Проверяем наличие параметров расчета и самого партнера
    Если ПараметрыРасчета = Неопределено Или Не ПараметрыРасчета.Свойство("Партнер") Тогда
        РезультатПроверки.Вставить("ТекущееУсловиеВыполнено", Ложь);
        Возврат РезультатПроверки;
    КонецЕсли;
    
    ПартнерДокумента = ПараметрыРасчета.Partner;
    ЦелевойКонтрагент = ПараметрыВнешнейОбработки.Контрагент;
    
    // Если партнер документа совпадает с настроенным в скидке контрагентом
    Если ЗначениеЗаполнено(ПартнерДокумента) И ПартнерДокумента = ЦелевойКонтрагент Тогда
        
        // Пытаемся получить таблицу товаров для установки признака выполнения по строкам
        ТаблицаТоваров = Неопределено;
        Если СтрокаДереваСкидок.Свойство("СтруктураДополнительныхДанных") Тогда
            СтрокаДереваСкидок.СтруктураДополнительныхДанных.Свойство("ТаблицаТоваровПоСегментам", ТаблицаТоваров);
        КонецЕсли;
        
        Если ТаблицаТоваров <> Неопределено Тогда
            Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
                СтрокаТовара.УсловиеПоСтрокеВыполнено = Истина;
            КонецЦикла;
        КонецЕсли;
        
        ТекущееУсловиеВыполнено = Истина;
        
    КонецЕсли;
    
    РезультатПроверки.Вставить("ТекущееУсловиеВыполнено", ТекущееУсловиеВыполнено);
    Возврат РезультатПроверки;
    
КонецФункции

Теперь, когда код исправлен и структурирован, разберем по шагам, какими способами мы можем его отладить.

Способ №1: Отладка через «Файл — Открыть» с отключением безопасного режима

Это наиболее простой и популярный метод, который позволяет использовать стандартный механизм отладки без изменения кода конфигурации. Суть метода заключается в том, чтобы «заставить» платформу ассоциировать выполняемый код с файлом обработки на вашем диске.

Выполним следующие шаги:

  1. Откройте базу данных в режиме Конфигуратора.
  2. В меню Файл -> Открыть выберите файл вашей внешней обработки (например, УсловиеСкидкиПоКонтрагенту.epf), лежащий на локальном диске.
  3. Перейдите в модуль объекта этой обработки и установите точку останова (клавиша F9) внутри интересующей вас функции (например, на первой строке функции ПроверитьУсловие).
  4. Запустите сеанс «1С:Предприятие» в режиме отладки (клавиша F5).
  5. Перейдите в справочник Дополнительные отчеты и обработки, найдите вашу внешнюю скидку и откройте ее карточку.
  6. Важно: В настройках публикации обработки обязательно установите параметр Безопасный режим в значение Ложь (снимите соответствующий флажок). Если этого не сделать, платформа заблокирует возможность сопоставления исходного кода с внешним файлом.
  7. Сохраните изменения в справочнике.
  8. Откройте документ (например, «Заказ клиента»), в котором должна сработать данная скидка, и попробуйте рассчитать скидки. В момент обращения системы к коду условия платформа сопоставит выполняемый объект с открытым в конфигураторе файлом, и произойдет остановка на вашей точке останова.

Способ №2: Отладка через точку останова в общем модуле БСП

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

Рассмотрим этот процесс пошагово:

  1. В конфигураторе откройте глобальный поиск (сочетание клавиш Ctrl + Shift + F) и найдите общий модуль, отвечающий за расчет скидок. Обычно он называется СкидкиНаценкиСервер.
  2. Найдите в этом модуле процедуру, которая инициирует проверку внешних условий. Чаще всего это метод с именем ВыполнитьПроверкуУсловийПредоставления или ПроверитьУсловиеВнешнейОбработки.
  3. Внутри этого метода найдите строку, где происходит динамический вызов внешней обработки. Выглядит это примерно так: Результат = ВнешнийОбъект.ПроверитьУсловие(Параметры...);.
  4. Поставьте точку останова на эту строку кода.
  5. Запустите расчет скидок в документе. Когда отладчик остановится на этой строке, нажмите клавишу F11 (Шагнуть внутрь). Если на сервере включена отладка, конфигуратор автоматически откроет модуль вашей внешней обработки и перейдет к первой исполняемой строке функции ПроверитьУсловие.

Способ №3: Использование тестового стенда (внешней обработки-стартера)

Этот способ является наиболее профессиональным и безопасным, так как он полностью исключает необходимость интерактивной работы с реальными документами в интерфейсе и позволяет тестировать код изолированно. Мы создаем небольшую вспомогательную внешнюю обработку, которая будет программно вызывать наше условие скидки.

Давайте разберем, как устроен этот тестовый стенд. Создадим новую внешнюю обработку и назовем ее ТестированиеСкидки.epf. На форму обработки вынесем реквизит ДокументСсылка с типом, например, ДокументСсылка.ЗаказКлиента и кнопку «Запустить тест».

В модуле формы обработки-стартера напишем следующий код:


&НаСервере
Процедура ЗапуститьТестНаСервере()
    
    // 1. Подключаем тестируемую обработку напрямую с диска
    ПутьКОбработке = "C:\Debug\УсловиеСкидкиПоКонтрагенту.epf";
    ОбработкаОбъект = ВнешниеОбработки.Создать(ПутьКОбработке, Ложь);
    
    // 2. Инициализируем структуру параметров расчета, имитируя поведение БСП
    ПараметрыРасчета = Новый Структура;
    ПараметрыРасчета.Вставить("Партнер", ДокументСсылка.Партнер);
    ПараметрыРасчета.Вставить("Контрагент", ДокументСсылка.Контрагент);
    
    // 3. Создаем тестовую структуру строки дерева скидок
    СтрокаДереваСкидок = Новый Структура;
    СтруктураДополнительныхДанных = Новый Структура;
    
    // Создаем пустую таблицу товаров для теста обхода строк
    ТаблицаТоваров = Новый ТаблицаЗначений;
    ТаблицаТоваров.Колонки.Добавить("Номенклатура");
    ТаблицаТоваров.Колонки.Добавить("УсловиеПоСтрокеВыполнено", Новый ОписаниеТипов("Булево"));
    
    // Заполняем тестовую строку товара
    НоваяСтрока = ТаблицаТоваров.Добавить();
    НоваяСтрока.Номенклатура = Справочники.Номенклатура.ПустаяСсылка();
    НоваяСтрока.УсловиеПоСтрокеВыполнено = Ложь;
    
    СтруктураДополнительныхДанных.Вставить("ТаблицаТоваровПоСегментам", ТаблицаТоваров);
    СтрокаДереваСкидок.Вставить("СтруктураДополнительныхДанных", СтруктураДополнительныхДанных);
    
    // 4. Задаем настройки внешней обработки (имитация заполненных реквизитов)
    ПараметрыВнешнейОбработки = Новый Структура;
    ПараметрыВнешнейОбработки.Вставить("Контрагент", ДокументСсылка.Контрагент);
    
    // 5. Вызываем функцию проверки условия
    Результат = ОбработкаОбъект.ПроверитьУсловие(
        Неопределено, 
        СтрокаДереваСкидок, 
        ПараметрыВнешнейОбработки, 
        ПараметрыРасчета
    );
    
    // Выводим результат в окно сообщений
    Сообщить("Результат проверки условия: " + Результат.ТекущееУсловиеВыполнено);
    
КонецПроцедуры

&НаКлиенте
Процедура ЗапуститьТест(Команда)
    ЗапуститьТестНаСервере();
КонецПроцедуры

Теперь мы можем открыть эту обработку-стартер через меню Файл -> Открыть в режиме Предприятия, выбрать нужный документ и нажать кнопку. Любые точки останова, установленные в файле УсловиеСкидкиПоКонтрагенту.epf, будут гарантированно и стабильно срабатывать, так как обработка создается непосредственно из файла на диске с отключенным безопасным режимом.

Обязательный чеклист для успешной серверной отладки

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

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

← На главную