При работе с управляемыми формами в 1С:Предприятии, особенно в таких конфигурациях, как 1С:Зарплата и Управление Персоналом (ЗУП 3.1), мы часто сталкиваемся с задачами по оптимизации пользовательского интерфейса. Одной из таких задач является программное управление свертываемыми группами и привлечение внимания пользователя к критически важным полям. В частности, речь идет о группе "Условия исчисления" в документе "Ответ на запрос в СФР" и необходимости убедиться, что код "45 - лицо, имеющее инвалидность" указан корректно.
Рассмотрим подробнее, почему возникают сложности с программным разворачиванием групп и как эффективно привлекать внимание пользователя к данным, которые могут быть пропущены.
Многие из нас сталкивались с ситуацией, когда мы пытаемся программно развернуть свертываемую группу на форме, используя метод Показать(), но группа упорно остается свернутой. Это вызывает недоумение, особенно когда отладчик показывает, что свойство Скрыта() равно Ложь.
Выясним причину, почему Элементы.Группа.Показать() может не работать так, как мы ожидаем.
Ключевая причина кроется в механизме сохранения пользовательских настроек форм. Система 1С:Предприятие запоминает состояние свертываемых групп для каждого пользователя. Если пользователь один раз развернул или свернул группу, а затем закрыл документ, при следующем открытии эта группа будет в том же состоянии, в каком ее оставил пользователь. Эти настройки хранятся в базе данных, часто в так называемом "хранилище значений", связанном с конкретной формой и пользователем.
Программный вызов Элементы.Группа.Показать() (доступный, кстати, начиная с версии платформы 8.3.12) пытается изменить текущее состояние группы. Однако, после выполнения нашего кода, система может применять сохраненные пользовательские настройки, которые имеют более высокий приоритет или срабатывают на более позднем этапе инициализации формы. В результате, наши программные изменения игнорируются или перекрываются.
Кроме того, если группа создается динамически или ее состав меняется (например, через "Изменить форму" пользователем), она может получить суффиксы типа "_1", что может затруднить программное обращение к ней по исходному имени.
Наш подход к принудительному разворачиванию группы
Хотя явное программное изменение пользовательских настроек для свертываемых групп (очистка или переопределение) является сложной задачей, мы можем предпринять следующие шаги, чтобы попытаться добиться желаемого поведения:
Размещение кода в ПриСозданииНаСервере: Это одно из самых ранних событий при инициализации формы. Разместите ваш код для разворачивания группы здесь. Это позволит вашему коду сработать до того, как форма будет полностью отображена пользователю и, возможно, до того, как будут применены все пользовательские настройки.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ... ваш существующий код ...
// Попытаемся развернуть группу
Если Элементы.УсловияИсчисленияГруппа <> Неопределено Тогда
Элементы.УсловияИсчисленияГруппа.Показать();
КонецЕсли;
// ... остальной код ...
КонецПроцедуры
Понимание приоритетов: Даже размещение кода в ПриСозданииНаСервере не гарантирует 100% успеха, если система применяет пользовательские настройки формы еще позже. В таких случаях, автор темы сам пришел к выводу, что проблема связана с "хранилищем значений" и прошлым состоянием группы. Это означает, что для полного контроля над состоянием группы, возможно, потребуется более глубокое вмешательство, связанное с очисткой или программным изменением этих сохраненных настроек, что обычно не рекомендуется и является весьма трудоемким.
Помните, что если цель - всегда видеть группу развернутой, самым простым решением, если это возможно, будет изменить ее свойство "Поведение" в конфигураторе с "Свертываемая" на "Обычное". Однако, это не всегда применимо, если группа должна быть свертываемой, но в определенных условиях принудительно разворачиваться.
Помимо разворачивания группы, часто возникает потребность привлечь внимание пользователя к конкретному полю, особенно если его заполнение критично. В нашем случае это поле с кодом "45" для инвалидов в документе "Ответ на запрос в СФР".
Выясним вызовы, связанные с условным оформлением.
Мы пытались использовать условное оформление для подсветки поля, но столкнулись с проблемой: программное изменение или даже отключение условного оформления не приводило к желаемому результату до интерактивного редактирования поля. Это указывает на сложную логику применения оформления в управляемых формах, где определенные правила могут быть перекрыты или срабатывать только при определенных событиях пользовательского интерфейса.
Поскольку прямое изменение цвета фона или текста через условное оформление не всегда дает мгновенный и надежный результат, рассмотрим более эффективные и прямые методы привлечения внимания.
Эффективные методы для привлечения внимания пользователя:
Вместо того чтобы бороться с тонкостями условного оформления, мы можем использовать более надежные механизмы:
Метод 1: Интерактивные сообщения с привязкой к полю (СообщениеПользователю)
Этот метод является одним из наиболее рекомендуемых для привлечения внимания к конкретному реквизиту формы. Объект СообщениеПользователю позволяет вывести не только текстовое сообщение, но и привязать его к определенному полю формы. При двойном щелчке по такому сообщению в окне сообщений, фокус автоматически перемещается на указанное поле.
Разберем по шагам использование СообщениеПользователю:
СообщениеПользователю:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Внимание! Сотрудник является инвалидом. Проверьте заполнение кода 45 в условиях исчисления.";
Сообщение.Поле = "Объект.УсловияИсчисления.КодИсчисления"; // Предполагаемый путь к реквизиту
Сообщение.ВидСообщения = ВидСообщенияПользователю.Предупреждение;
Сообщение.УстановитьИдентификаторФормы(ЭтаФорма.УникальныйИдентификатор);
Сообщение.Сообщить();
Пример кода для использования СообщениеПользователю в контексте проверки кода 45:
&НаКлиенте
Процедура ПослеЗагрузкиДанныхНаСервере()
// Предположим, что Объект.Сотрудник.ЯвляетсяИнвалидом - это флаг,
// который мы можем получить с сервера.
// И Объект.УсловияИсчисления - это коллекция или строка, которую нужно проверить.
Если ПроверитьНеобходимостьКода45НаСервере() Тогда // Вызов серверной функции для проверки
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Для данного сотрудника-инвалида необходимо указать код '45' в условиях исчисления!";
Сообщение.Поле = "Объект.УсловияИсчисления.КодИсчисления"; // Укажите корректный путь к реквизиту
Сообщение.ВидСообщения = ВидСообщенияПользователю.Предупреждение;
Сообщение.УстановитьИдентификаторФормы(ЭтаФорма.УникальныйИдентификатор);
Сообщение.Сообщить();
// Дополнительно можно попытаться установить фокус, хотя это не всегда гарантировано
// и может быть излишним, так как СообщениеПользователю уже направляет фокус.
Попытка
ЭтаФорма.ТекущийЭлемент = Элементы.УсловияИсчисленияКод45; // Пример имени элемента
Исключение
// Элемент не найден или недоступен
КонецПопытки;
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПроверитьНеобходимостьКода45НаСервере()
// Здесь должна быть логика проверки:
// 1. Является ли сотрудник инвалидом (из его карточки).
// 2. Присутствует ли код 45 среди условий исчисления в текущем документе.
// Вернуть Истина, если сотрудник инвалид, а код 45 отсутствует.
// Например:
Если Объект.Сотрудник.ПолучитьОбъект().ЯвляетсяИнвалидом ИЛИ Объект.Сотрудник.ПолучитьОбъект().Инвалидность.ВидИнвалидности <> Неопределено Тогда
// Проверяем, есть ли код 45 в условиях исчисления
Для Каждого УсловиеИз ДокументОбъект.УсловияИсчисления Цикл
Если УсловиеИз.КодИсчисления = 45 Тогда
Возврат Ложь; // Код 45 уже есть
КонецЕсли;
КонецЦикла;
Возврат Истина; // Сотрудник инвалид, а кода 45 нет
КонецЕсли;
Возврат Ложь;
КонецФункции
Этот подход обеспечивает высокую эффективность, так как пользователь получает недвусмысленное уведомление и может сразу перейти к нужному полю.
Метод 2: Установка фокуса на элемент (ЭтаФорма.ТекущийЭлемент)
Мы пытались использовать свойство ЭтаФорма.ТекущийЭлемент = Элементы.ИмяЭлемента для установки фокуса на нужный реквизит. Однако, как показал опыт, этот метод не всегда срабатывает надежно, особенно в расширениях или в определенных событиях формы (Сообщение 15). Он может требовать дополнительных действий, таких как обновление формы, или срабатывать только после некоторой задержки.
Пример использования:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// ... ваш код ...
Попытка
ЭтаФорма.ТекущийЭлемент = Элементы.УдостоверениеЛичностиВид; // Пример
Исключение
// Обработка ошибки, если элемент не найден или недоступен
КонецПопытки;
// ...
КонецПроцедуры
Рекомендуем использовать установку фокуса в сочетании с СообщениеПользователю, поскольку последнее обеспечивает более надежную индикацию.
Метод 3: Строгое предупреждение через ПоказатьОповещениеПользователя
Для критически важных случаев, когда необходимо *принудительно* обратить внимание пользователя, можно использовать функцию ПоказатьОповещениеПользователя(). Это более навязчивое всплывающее окно, которое может быть настроено по тексту, заголовку и иконке. Оно не привязано к конкретному полю, как СообщениеПользователю, но его сложнее проигнорировать.
Пример:
&НаКлиенте
Процедура ПроверитьКод45ИОповестить()
Если ПроверитьНеобходимостьКода45НаСервере() Тогда
ПоказатьОповещениеПользователя("Внимание! Ошибка в документе!",
"Для сотрудника-инвалида не указан код 45 в условиях исчисления.",
"Необходимо исправить данные для корректного расчета пособия.",
БиблиотекаКартинок.Предупреждение);
КонецЕсли;
КонецПроцедуры
Метод 4: Принуждение к корректности через блокировку проведения документа
Если речь идет о критически важных данных, отсутствие которых влечет за собой юридические или финансовые риски (как в случае с кодом 45 для инвалидов), самым действенным методом будет блокировка проведения документа до тех пор, пока данные не будут заполнены корректно.
Механизм блокировки:
Для этого мы используем событие формы ПередЗаписьюНаСервере или событие модуля объекта ПередЗаписью, устанавливая флаг Отказ = Истина. Это событие срабатывает непосредственно перед записью или проведением документа, позволяя нам выполнить все необходимые проверки.
Пример кода для блокировки проведения:
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ЗамещаемыеДанныеЗаписи)
// Получаем объект документа для проверки
ДокументОбъект = Объект;
// Проверяем, является ли сотрудник инвалидом (нужно адаптировать путь к данным)
// И если да, то проверяем наличие кода 45 в условиях исчисления
Если ДокументОбъект.Сотрудник.ПолучитьОбъект().ЯвляетсяИнвалидом ИЛИ ДокументОбъект.Сотрудник.ПолучитьОбъект().Инвалидность.ВидИнвалидности <> Неопределено Тогда
ЕстьКод45 = Ложь;
Для Каждого УсловиеИз ДокументОбъект.УсловияИсчисления Цикл
Если УсловиеИз.КодИсчисления = 45 Тогда
ЕстьКод45 = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЕстьКод45 Тогда
Отказ = Истина; // Блокируем проведение документа
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Необходимо указать код '45' (Лицо, имеющее инвалидность) в условиях исчисления для данного сотрудника! Проведение документа заблокировано.";
Сообщение.Поле = "Объект.УсловияИсчисления.КодИсчисления"; // Укажите корректный путь к реквизиту
Сообщение.ВидСообщения = ВидСообщенияПользователю.Ошибка;
Сообщение.УстановитьИдентификаторФормы(ЭтаФорма.УникальныйИдентификатор);
Сообщение.Сообщить();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Юридический аспект блокировки:
Важность правильного заполнения кода 45 для инвалидов подтверждается судебной практикой. Излишне выплаченные пособия по больничному листу, если не был указан код 45, могут быть взысканы с предприятия по суду. Например, Постановление Арбитражного суда Северо-Кавказского округа от 24.04.2024 N Ф08-2041/2024 по делу N А53-28956/2023 является прямым подтверждением этой проблемы. Демонстрация такой информации клиентам может помочь обосновать необходимость использования строгих методов контроля, таких как блокировка проведения, для предотвращения финансовых и юридических рисков.
Важный аспект, поднятый в обсуждении, касается того, почему вообще возникает проблема с незаполнением кода 45. В типовых решениях 1С:ЗУП 3.1 код "45 - лицо, имеющее инвалидность" в документе "Больничный лист" (и, соответственно, в "Ответе на запрос СФР") должен заполняться автоматически, если в карточке сотрудника на вкладке "Страхование" корректно заполнены сведения об инвалидности. Мы обнаружили, что эта процедура обычно работает при интерактивном вводе данных.
Однако, возникает предположение, что автоматическое заполнение может не срабатывать при создании больничного листа через обмен с СФР (СЭДО). Если документ "Больничный лист" или "Ответ на запрос СФР" создается не вручную, а загружается автоматически, например, на основании входящего ЭЛН из СФР, то стандартные процедуры интерактивного заполнения могут не вызываться. Это приводит к тому, что поле с кодом 45 остается пустым, даже если сотрудник является инвалидом.
Что нам делать в этом случае:
Если мы подозреваем, что проблема возникает при обмене с СЭДО, нам следует:
Проанализировать процедуры загрузки данных СЭДО: Внимательно изучите код, отвечающий за создание и заполнение документов на основе данных, полученных через СЭДО. Возможно, потребуется добавить дополнительные проверки и вызовы процедур, которые гарантируют корректное заполнение кода 45.
Расширить обработку создания документов: Если стандартные механизмы не срабатывают, мы можем использовать расширения для модификации процедур создания или обновления документов после их загрузки из СЭДО. Это позволит нам внедрить логику по проверке инвалидности сотрудника и автоматическому добавлению кода 45, если он отсутствует.
Таким образом, устранение первопричины, когда код не заполняется автоматически, является более эффективным подходом, чем простое привлечение внимания к ошибке.
Подводя итог нашим изысканиям, мы хотим предложить ряд общих рекомендаций, которые помогут нам в работе с 1С:Предприятием:
Использование расширений: Мы всегда должны стремиться использовать расширения для доработки типовых конфигураций. Это значительно упрощает процесс обновления конфигурации и снижает риски при переходе на новые версии.
Размещение кода в ПриСозданииНаСервере: Для всех программных изменений, которые должны быть применены при открытии формы, мы должны использовать событие ПриСозданииНаСервере. Это гарантирует, что наш код будет выполнен на раннем этапе инициализации формы.
Приоритет автоматизации над интерфейсными доработками: Если возможно, мы должны сосредоточиться на автоматизации заполнения данных, а не только на привлечении внимания к незаполненным полям. Если проблема возникает из-за того, что данные не заполняются автоматически, лучше исправить механизм автоматического заполнения. Например, дополнить логику загрузки документов из СЭДО, чтобы код 45 проставлялся сразу.
Выбор метода привлечения внимания:
СообщениеПользователю без блокировки.СообщениеПользователю с привязкой к полю и, возможно, ПоказатьОповещениеПользователя().Обоснование изменений: Мы всегда должны быть готовы обосновать свои доработки руководству и пользователям, особенно если они затрагивают пользовательский интерфейс или функционал проведения документов. Юридические прецеденты, подобные рассмотренному, могут стать сильным аргументом в пользу внедрения строгих проверок.
Применяя эти подходы, мы сможем эффективно управлять поведением форм, привлекать внимание пользователей к важной информации и обеспечивать корректность данных в системе 1С:ЗУП 3.1, минимизируя риски ошибок и их последствия.