При разработке на платформе 1С:Предприятие 8.3 часто возникает задача: при входе пользователя в программу проверить определенное состояние данных (например, настройки учетной политики или наличие незаполненных реквизитов) и, если условие выполняется, вывести информационное окно. Реализация такой задачи в расширении требует понимания контекстных ограничений клиент-серверной архитектуры.
Рассмотрим ситуацию, когда необходимо проверить, является ли организация плательщиком НДС, и если нет — предупредить пользователя при начале работы. Разберем основные ошибки, с которыми сталкиваются разработчики, и найдем оптимальное решение.
Основная сложность заключается в том, что Модуль управляемого приложения (и его расширение) выполняется исключительно на стороне клиента. В этом модуле нельзя использовать директиву &НаСервере. Попытка написать запрос к базе данных или обратиться к регистру сведений напрямую внутри этого модуля приведет к ошибке компиляции: "Процедура или функция с указанным именем не определена".
Для решения этой задачи нам необходимо разделить логику на два этапа:
ПриНачалеРаботыСистемы.Поскольку в модуле приложения серверный код недоступен, мы должны вынести логику проверки в Общий модуль. Рассмотрим, как правильно настроить этот модуль:
Во-первых, в свойствах общего модуля обязательно должны быть установлены флаги Сервер и Вызов сервера. Без флага "Вызов сервера" клиентский код модуля приложения не сможет "дотянуться" до функции.
Напишем функцию, которая проверяет статус плательщика НДС. Проанализируем пример кода:
// В общем модуле (например, ОбщегоНазначенияСервер)
// Свойства модуля: Сервер = Истина, Вызов сервера = Истина
Функция ПроверитьСтатусПлательщикаНДС() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| УчетнаяПолитика.ОрганизацияЯвляетсяПлательщикомНДС КАК Плательщик
|ИЗ
| РегистрСведений.УчетнаяПолитикаНалоговыйУчет.СрезПоследних(&Период, ) КАК УчетнаяПолитика";
Запрос.УстановитьПараметр("Период", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Ложь;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Возврат Выборка.Плательщик;
КонецФункции
Обратите внимание: мы используем метод СрезПоследних. Это наиболее эффективный способ получить актуальное состояние учетной политики на текущую дату.
Теперь перейдем к расширению модуля управляемого приложения. Мы будем использовать аннотацию &После для процедуры ПриНачалеРаботыСистемы. Это гарантирует, что наш код выполнится после того, как система инициализирует основные параметры сеанса.
Проанализируем ситуацию с выводом окна. В современных версиях платформы рекомендуется отказываться от модальных окон (функция Предупреждение) в пользу асинхронных методов. Рассмотрим правильный вариант реализации:
&После("ПриНачалеРаботыСистемы")
Процедура Расш1_ПриНачалеРаботыСистемы()
// Вызываем нашу серверную функцию из общего модуля
ЯвляетсяПлательщиком = ОбщегоНазначенияСервер.ПроверитьСтатусПлательщикаНДС();
// Если организация НЕ является плательщиком НДС, выводим сообщение
Если Не ЯвляетсяПлательщиком Тогда
ТекстСообщения = "Внимание! В учетной политике организации не установлен признак плательщика НДС.";
ЗаголовокОкна = "Проверка учетной политики";
// Используем асинхронный метод для корректной работы в веб-клиенте
ПоказатьПредупреждение(, ТекстСообщения, , ЗаголовокОкна);
КонецЕсли;
КонецПроцедуры
Выясним причину, почему прямой запрос при каждом запуске может быть не лучшим решением. Если база данных большая, а пользователей много, постоянные запросы к регистру при логине создают лишнюю нагрузку. Для оптимизации мы можем использовать Параметры сеанса.
Разберем этот метод подробнее:
Расш1_ЭтоПлательщикНДС (тип Булево).УстановкаПараметровСеанса, инициализируем это значение один раз на сервере.ПриНачалеРаботыСистемы на клиенте просто считываем значение: Если Не ПараметрыСеанса.Расш1_ЭтоПлательщикНДС Тогда....Это работает мгновенно, так как значение параметра сеанса кэшируется в памяти текущего сеанса пользователя.
Если в вашей базе ведется учет по нескольким организациям, запрос без фильтрации может вернуть некорректные данные. Рассмотрим, как доработать логику: необходимо сначала определить "Основную организацию" текущего пользователя. Обычно она хранится в настройках пользователя или также в параметрах сеанса.
Добавим условие в запрос для точности:
// Пример уточненного запроса
Запрос.Текст =
"ВЫБРАТЬ
| СрезПоследних.ОрганизацияЯвляетсяПлательщикомНДС
|ИЗ
| РегистрСведений.УчетнаяПолитикаНалоговыйУчет.СрезПоследних(&Период, Организация = &Организация) КАК СрезПоследних";
Запрос.УстановитьПараметр("Организация", ОсновнаяОрганизация);
Для успешного вывода сообщения при запуске программы на основе данных из БД необходимо:
&После("ПриНачалеРаботыСистемы").ПоказатьПредупреждение() вместо устаревшего Предупреждение(), чтобы избежать проблем с модальностью в браузере или тонком клиенте.Использование этих подходов позволит вам создавать надежные и быстрые механизмы уведомления пользователей, соблюдая архитектурные стандарты платформы 1С.