Как устранить долгий расчет скидок в РМК 1С:УТ 11.5?

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

Многие пользователи и администраторы систем на базе 1С:Управление торговлей 11.5 (а также ERP 2.5 и КА 2.5) сталкиваются с неприятной проблемой: при работе в Рабочем месте кассира (РМК) нажатие кнопки «Рассчитать скидки» или переход к оплате вызывает «замирание» системы на 10–20 секунд. В условиях розничного потока такие задержки критичны. Давайте подробно разберем, почему это происходит и как исправить ситуацию программными методами или внедрить редактирование цены в РМК по паролю.

Проводим диагностику: где именно «тормозит» расчет?

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

Рассмотрим результаты типичного замера. Мы увидим, что около 95% времени уходит на выполнение одной-единственной строки в общем модуле СкидкиНаценкиСервер:

ПакетЗапросов.РезультатЗапроса = ПакетЗапросов.Запрос.ВыполнитьПакет();

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

Способ 1. Оптимизация запроса в модуле СкидкиНаценкиСервер

Проанализируем программный код. Помимо редактирования цен в чеках ККМ, основное замедление часто происходит в функции, отвечающей за расчет накопленного объема продаж по партнеру. Система пытается проанализировать документы ЧекККМВозврат за определенный период, чтобы понять, имеет ли клиент право на дополнительную скидку.

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

Шаг 1. Найдем в общем модуле СкидкиНаценкиСервер фрагмент запроса, работающий с таблицей Документ.ЧекККМВозврат.Товары. Изначально он выглядит примерно так:


|ГДЕ
| ПроданныеТовары.Ссылка В (
| ВЫБРАТЬ
| Т.Ссылка
| ИЗ
| Документ.ЧекККМВозврат КАК Т
| ГДЕ
| Т.Дата МЕЖДУ &ДатаНачалаЧекККМ И &ДатаОкончанияЧекККМ
| И Т.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЧековККМ.Пробит)
| И Т.КассоваяСмена.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКассовойСмены.Открыта)
| И Т.Партнер = &Партнер
| И Т.Партнер <> ЗНАЧЕНИЕ(Справочник.Партнеры.РозничныйПокупатель)
| И ПроданныеТовары.КоличествоУпаковок <> 0
|)";

Шаг 2. Оптимизируем его. Проблема заключается в том, что условие ПроданныеТовары.КоличествоУпаковок <> 0 находится внутри вложенного фильтра по ссылкам. Нам необходимо вынести это условие на уровень выше, во внешний запрос. Посмотрим на исправленный вариант:


|ГДЕ
| // Выносим условие во внешний запрос для ускорения индексации
| ПроданныеТовары.КоличествоУпаковок <> 0 И 
| ПроданныеТовары.Ссылка В (
| ВЫБРАТЬ
| Т.Ссылка
| ИЗ
| Документ.ЧекККМВозврат КАК Т
| ГДЕ
| Т.Дата МЕЖДУ &ДатаНачалаЧекККМ И &ДатаОкончанияЧекККМ
| И Т.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЧековККМ.Пробит)
| И Т.КассоваяСмена.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКассовойСмены.Открыта)
| И Т.Партнер = &Партнер
| И Т.Партнер <> ЗНАЧЕНИЕ(Справочник.Партнеры.РозничныйПокупатель)
|)";

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

Способ 2. Проверка условий предоставления скидок

Если правка кода не принесла желаемого результата, проанализируем настройки самой системы. В УТ 11.5 механизм скидок может обращаться напрямую к таблицам документов вместо итоговых регистров, если заданы сложные условия.

  1. Перейдем в раздел CRM и маркетинг — Цены и скидки — Условия предоставления скидок.
  2. Найдем условия с типом «За накопленный объем продаж».
  3. Посмотрим на период анализа. Если система должна анализировать продажи за «весь период» по каждому розничному покупателю, это создает колоссальную нагрузку на дисковую подсистему при каждом расчете.
  4. Рекомендация: Попробуйте ограничить период анализа (например, последний год) или временно отключить такие условия для проверки скорости.

Способ 3. Установка официальных патчей (EF)

Компания «1С» регулярно выпускает исправления (патчи) для оптимизации производительности. Для релизов линейки 11.5 это особенно актуально, так как блок РМК постоянно дорабатывается. Проанализируем список установленных исправлений в разделе Обслуживание — Обновление программы — Установленные исправления.

Ищите патчи, в описании которых фигурируют СкидкиНаценкиСервер или РасчетСкидокРМК. Часто установка пакета исправлений или ускорение отчета «Валовая прибыль» решает проблемы без ручного вмешательства в код.

Способ 4. Оптимизация файлового режима и веб-сервер

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

  1. Публикация на веб-сервере: Опубликуйте базу через Apache или IIS. В этом случае часть тяжелых запросов будет обрабатываться веб-сервером локально, и в РМК по сети будут передаваться уже готовые результаты, что значительно быстрее.
  2. Регламентные задания: Убедитесь, что задания ОбслуживаниеИтогов и ОбновлениеИндексаПолнотекстовогоПоиска выполняются регулярно. Неактуальные итоги заставляют систему пересчитывать данные «на лету» при каждом нажатии кнопки в РМК.

Резюме

Подведем итог нашему исследованию. В большинстве случаев задержка вызвана неоптимальным запросом в типовом модуле СкидкиНаценкиСервер. Перенос условия КоличествоУпаковок <> 0 во внешний запрос позволяет сократить время ожидания с 15 секунд до долей секунды. Также не забываем проверять настройки условий лояльности и использовать механизм расширений для безопасного внесения изменений в логику программы.

← На главную