Как задать вопрос пользователю в 1С:ЗУП при формировании отчета или расчетного листка

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

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью спросить у пользователя подтверждение перед выполнением какого-либо тяжелого или важного действия. Типичный пример — вопрос «Печатать расчетный листок с расшифровкой?» при формировании отчета в программе 1С:Зарплата и управление персоналом (ЗУП). Однако попытка написать простой и привычный код диалога часто приводит к ошибкам компиляции или к тому, что система просто игнорирует вызов. Выясним причины такого поведения платформы, детально разберем клиент-серверную архитектуру 1С и рассмотрим наиболее эффективные современные способы решения этой задачи.

Анализ исходной проблемы и ошибок разработчика

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

Главная причина кроется в клиент-серверной архитектуре платформы и жестком разделении контекстов выполнения кода:

  1. Контекст модуля объекта: Модуль любого объекта (будь то справочник, документ или отчет на СКД) всегда компилируется и выполняется строго на сервере. На сервере физически отсутствует интерфейс пользователя (экран, мышь, диалоговые окна). Сервер занимается исключительно обработкой данных и отправкой их на клиент. Соответственно, любые попытки вызвать интерактивные методы (такие как Вопрос, Предупреждение, ОткрытьФорму) на сервере вызовут критическую ошибку.
  2. Ошибочное использование директив препроцессора: Инструкция препроцессора #Если НаКлиенте Тогда внутри модуля объекта не решает проблему. Препроцессор просто исключает данный блок кода при компиляции на сервере. Поскольку модуль объекта на клиенте вообще не выполняется, этот код превращается в «мертвый» — он никогда не вызовется и не выполнится.
  3. Недопустимость директивы &НаКлиенте в модулях объектов: Директивы компиляции (такие как &НаКлиенте, &НаСервере) могут использоваться только в модулях управляемых форм или модулях команд. В модуле объекта они являются синтаксической ошибкой.

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

Эволюция интерактивных вызовов в 1С: от модальности к асинхронности

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

1. Синхронные (модальные) вызовы (Устаревший подход)

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


Режим = РежимДиалогаВопрос.ДаНет;
Ответ = Вопрос("Печатать расчетный листок?", Режим, 0);
Если Ответ = КодВозвратаДиалога.Да Тогда
    // Логика печати
КонецЕсли;

Этот подход признан устаревшим и небезопасным. Он не поддерживается в веб-клиенте (в браузерах), на мобильных платформах и блокирует работу веб-сервисов. В современных конфигурациях (включая ЗУП 3) в свойствах конфигурации по умолчанию включен режим «Режим использования модальности = Не использовать». При такой настройке вызов метода Вопрос() вызовет аварийное завершение работы программы.

2. Асинхронные вызовы через ОписаниеОповещения (Переходный подход)

Для отказа от модальности фирма «1С» внедрила неблокирующие методы, такие как ПоказатьВопрос(). Этот метод выводит окно на экран, но не останавливает выполнение кода. Вместо этого программа продолжает работу, а для обработки ответа пользователя используется специальный объект-колбэк — ОписаниеОповещения. Код при этом дробится на две отдельные процедуры:


&НаКлиенте
Процедура ЗадатьВопросПользователю()
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтотОбъект);
    ПоказатьВопрос(Оповещение, "Печатать расчетный листок?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        Сообщить("Пользователь согласился.");
    Иначе
        Сообщить("Пользователь отказался.");
    КонецЕсли;
КонецПроцедуры

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

3. Современные асинхронные вызовы через Обещания (Рекомендуемый подход)

Начиная с версии платформы 1С 8.3.18, появился великолепный механизм асинхронного программирования с использованием ключевых слов Асинх, Ждать и метода ВопросАсинх(). Он позволяет писать красивый, лаконичный и линейный код без разделения процедур, который при этом работает полностью асинхронно и не блокирует интерфейс:


&НаКлиенте
Асинх Процедура ВыполнитьПечатьСВопросом(Команда)
    
    Режим = РежимДиалогаВопрос.ДаНет;
    Ответ = Ждать ВопросАсинх("Печатать расчетный листок с расшифровкой?", Режим, 0, КодВозвратаДиалога.Нет, "Внимание");
    
    Если Ответ = КодВозвратаДиалога.Да Тогда
        Сообщить("Запущена печать с расшифровкой...");
        // Вызов серверного метода для формирования отчета с расшифровкой
    Иначе
        Сообщить("Запущена обычная печать...");
        // Вызов серверного метода для формирования обычного отчета
    КонецЕсли;
    
КонецПроцедуры

Важное правило: Любой из перечисленных выше интерактивных методов (включая асинхронные) может быть выполнен только в модуле управляемой формы на клиенте!


Как правильно решить задачу в контексте отчетов СКД (БСП)

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

Решение №1: Отказ от диалоговых окон в пользу параметров СКД (Рекомендуемый стандарт 1С)

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

Вместо диалогового окна правильнее использовать механизм параметров СКД, вынесенных на панель быстрых настроек отчета. Рассмотрим этот процесс по шагам:

  1. Откроем схему компоновки данных (СКД) нашего отчета.
  2. Перейдем на вкладку «Параметры» и добавим новый параметр:
    • Имя: ПечататьСРасшифровкой
    • Тип значения: Булево
    • Значение по умолчанию: Ложь
  3. В колонке настроек параметра нажмем кнопку свойств и установим флажок «Включать в пользовательские настройки», выбрав режим отображения «Быстрый доступ».
  4. Теперь прямо на форме отчета, рядом с кнопкой «Сформировать», появится аккуратный флажок (галочка) «Печатать с расшифровкой». Пользователь сможет взвести или снять его перед формированием отчета.
  5. В модуле объекта отчета в предопределенной процедуре ПриКомпоновкеРезультата мы можем легко прочитать значение этого параметра и изменить логику компоновки на сервере:

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

КонецПроцедуры

Этот способ является наиболее чистым, надежным и соответствующим стандартам юзабилити и разработки 1С.

Решение №2: Использование расширения для перехвата события формирования отчета

Если бизнес-требования заказчика категорически настаивают именно на выводе интерактивного вопроса при нажатии кнопки «Сформировать», нам придется вмешаться в работу общей формы отчета БСП. Чтобы не снимать типовую конфигурацию ЗУП с поддержки, реализуем эту задачу через механизм Расширений конфигурации.

Разберем алгоритм реализации:

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

&НаКлиенте
&Вместо("СформироватьОтчетКнопка")
Асинх Процедура Расш1_СформироватьОтчетКнопка(Команда)
    
    // Проверяем, что формируется именно наш целевой отчет
    Если ЭтотОбъект.ОтчетИмя = "АнализНачисленийИУдержаний" Тогда
        
        Режим = РежимДиалогаВопрос.ДаНет;
        Ответ = Ждать ВопросАсинх("Сформировать отчет с подробной расшифровкой?", Режим, 0, КодВозвратаДиалога.Да);
        
        Если Ответ = КодВозвратаДиалога.Нет Тогда
            // Если пользователь отказался, можем прервать формирование
            ПредупреждениеАсинх("Формирование отчета отменено пользователем.");
            Возврат;
        КонецЕсли;
        
    КонецЕсли;
    
    // Вызываем оригинальный метод формирования отчета БСП, если проверка пройдена
    ПродолжитьВызов(Команда);
    
КонецПроцедуры

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


Полезный кейс из практики ЗУП: Настройка двух тарифов взносов ФСС НС и ПЗ

В процессе обсуждения на форумах часто возникают смежные вопросы по ведению учета в ЗУП. Рассмотрим один из частых практических вопросов бухгалтеров (Сообщение 19): как настроить расчет страховых взносов на травматизм (ФСС НС и ПЗ) по двум разным ставкам (например, 0,2% и 0,4%) для одной организации? Такая потребность регулярно возникает в учреждениях, имеющих как бюджетное финансирование, так и доходы от приносящей доход деятельности (внебюджет).

В программе «1С:Зарплата и управление персоналом» данная возможность полностью автоматизирована и настраивается без изменения кода системы. Проанализируем пошаговый алгоритм настройки:

  1. Включение использования Самостоятельных Классификационных Единиц (СКЕ):
    • Перейдем в раздел Настройка — Организации (или Реквизиты организации).
    • Откроем вкладку Учетная политика и другие настройки, затем перейдем по ссылке Учетная политика.
    • На вкладке Страховые взносы найдем блок настроек взносов на травматизм. Установим флажок «Использовать самостоятельные классификационные единицы (СКЕ)» или аналогичную настройку разделения тарифов по источникам финансирования (для бюджетных учреждений).
  2. Настройка ставок для статей финансирования:
    • Перейдем в справочник Статьи финансирования (раздел Настройка — Статьи финансирования).
    • Для статьи финансирования, соответствующей бюджетным средствам, откроем карточку и укажем индивидуальную ставку взносов на травматизм (например, 0,2%).
    • Для статьи финансирования внебюджетной деятельности укажем в карточке ставку 0,4%.
  3. Расчет и распределение:
    • При начислении заработной платы сотрудникам программа будет автоматически анализировать, по какому источнику финансирования (статье финансирования) отражено начисление.
    • В документе Начисление зарплаты и взносов на вкладке Взносы расчет сумм НС и ПЗ произойдет раздельно по каждой строке дохода сотрудника с применением соответствующей ставки (0,2% или 0,4%).
    • Эти данные корректно распределятся в регламентированной отчетности (включая разделы формы ЕФС-1, заменяющей 4-ФСС).

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

← На главную