При сопровождении типовых конфигураций на обычных формах (например, «1С:Управление торговлей 10.3») разработчики нередко сталкиваются с необходимостью кастомизации интерфейса справочника Контрагенты. Одной из частых задач является скрытие незаполненных строк на вкладке «Контакты» в табличном поле КонтактнаяИнформация. Однако попытка динамической фильтрации этих строк через свойства элемента управления может приводить к аварийному закрытию толстого клиента платформы «1С:Предприятие 8.3».
Разберем детально, почему возникает критическая ошибка, какие архитектурные ограничения платформы к ней приводят и как правильно решить задачу фильтрации пустых строк на уровне прикладного кода.
Рассмотрим исходный код, который часто пытаются использовать для скрытия пустых контактных данных непосредственно в обработчике табличного поля:
ЭлементыФормы.КонтактнаяИнформация.ОтборСтрок.Представление.Значение = "";
ЭлементыФормы.КонтактнаяИнформация.ОтборСтрок.Представление.ВидСравнения = ВидСравнения.Содержит;
ЭлементыФормы.КонтактнаяИнформация.ОтборСтрок.Представление.Использование = Истина;
Выясним причину, по которой данная конструкция приводит к падению платформы в операционных системах Windows 10 и Windows Server при работе на платформе 8.3. Здесь действуют сразу два критических фактора:
ПриПолученииДанных предназначено исключительно для визуального оформления уже выбранных строк. Изменение свойства ОтборСтрок внутри этого события инициирует немедленное обновление состава отображаемых данных и повторный вызов графической подсистемы. Возникает бесконечная рекурсия, которая за доли секунды переполняет стек вызовов интерфейсного потока.Представление в типовой подсистеме контактной информации имеет тип «Строка неограниченной длины». Применение вида сравнения ВидСравнения.Содержит со значением пустой строки "" к строкам переменной структуры на уровне ядра платформы вызывает ошибку обращения к памяти (Access Violation), что мгновенно завершает рабочий процесс.Проанализируем типовой механизм заполнения контактной информации в конфигурациях на обычных формах. В типовой УТ 10.3 табличное поле заполняется данными из регистра сведений КонтактнаяИнформация с добавлением пустых шаблонов для всех доступных видов контактной информации из справочника ВидыКонтактнойИнформации. Это сделано для того, чтобы пользователь мог сразу ввести телефон или адрес без ручного добавления новой строки.
Если требуется полностью исключить показ незаполненных видов контактов, правильнее всего скорректировать процедуру выборки данных в общем модуле УправлениеКонтактнойИнформацией. Разберем по шагам, как это сделать:
УправлениеКонтактнойИнформацией.ПрочитатьКонтактнуюИнформацию.ЛОЖЬ И в секции ГДЕ этой ветки объединения.Посмотрим на итоговый пример сформированного текста запроса:
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ВложенныйЗапрос.Вид КАК Вид,
| ВложенныйЗапрос.Тип КАК Тип,
| ВложенныйЗапрос.Объект КАК Объект,
| МАКСИМУМ(ВложенныйЗапрос.Поле1) КАК Поле1,
| МАКСИМУМ(ВложенныйЗапрос.Поле2) КАК Поле2,
| МАКСИМУМ(ВложенныйЗапрос.Поле3) КАК Поле3,
| МАКСИМУМ(ВложенныйЗапрос.Поле4) КАК Поле4,
| МАКСИМУМ(ВложенныйЗапрос.Поле5) КАК Поле5,
| МАКСИМУМ(ВложенныйЗапрос.Поле6) КАК Поле6,
| МАКСИМУМ(ВложенныйЗапрос.Поле7) КАК Поле7,
| МАКСИМУМ(ВложенныйЗапрос.Поле8) КАК Поле8,
| МАКСИМУМ(ВложенныйЗапрос.Поле9) КАК Поле9,
| МАКСИМУМ(ВложенныйЗапрос.Поле10) КАК Поле10,
| МАКСИМУМ(ВложенныйЗапрос.Представление) КАК Представление,
| МАКСИМУМ(ВложенныйЗапрос.Комментарий) КАК Комментарий,
| МАКСИМУМ(ВложенныйЗапрос.ЗначениеПоУмолчанию) КАК ЗначениеПоУмолчанию,
| МАКСИМУМ(ВложенныйЗапрос.ТипДома) КАК ТипДома,
| МАКСИМУМ(ВложенныйЗапрос.ТипКорпуса) КАК ТипКорпуса,
| МАКСИМУМ(ВложенныйЗапрос.ТипКвартиры) КАК ТипКвартиры
|ИЗ
| (ВЫБРАТЬ
| &Объект КАК Объект,
| ВидыКонтактнойИнформации.Тип КАК Тип,
| ВидыКонтактнойИнформации.Ссылка КАК Вид,
| """" КАК Представление,
| """" КАК Поле1,
| """" КАК Поле2,
| """" КАК Поле3,
| """" КАК Поле4,
| """" КАК Поле5,
| """" КАК Поле6,
| """" КАК Поле7,
| """" КАК Поле8,
| """" КАК Поле9,
| """" КАК Поле10,
| """" КАК Комментарий,
| ЛОЖЬ КАК ЗначениеПоУмолчанию,
| ЗНАЧЕНИЕ(Перечисление.ТипыДомов.ПустаяСсылка) КАК ТипДома,
| ЗНАЧЕНИЕ(Перечисление.ТипыКорпусов.ПустаяСсылка) КАК ТипКорпуса,
| ЗНАЧЕНИЕ(Перечисление.ТипыКвартир.ПустаяСсылка) КАК ТипКвартиры
| ИЗ
| Справочник.ВидыКонтактнойИнформации КАК ВидыКонтактнойИнформации
| ГДЕ
| ЛОЖЬ И
| (НЕ ВидыКонтактнойИнформации.ПометкаУдаления)
| И ВидыКонтактнойИнформации.ВидОбъектаКонтактнойИнформации = &ВидОбъектаКонтактнойИнформации
|
| ОБЪЕДИНИТЬ
|
| ВЫБРАТЬ
| РегистрСведенийКонтактнаяИнформация.Объект,
| РегистрСведенийКонтактнаяИнформация.Тип,
| РегистрСведенийКонтактнаяИнформация.Вид,
| ВЫРАЗИТЬ(РегистрСведенийКонтактнаяИнформация.Представление КАК СТРОКА(1000)),
| РегистрСведенийКонтактнаяИнформация.Поле1,
| РегистрСведенийКонтактнаяИнформация.Поле2,
| РегистрСведенийКонтактнаяИнформация.Поле3,
| РегистрСведенийКонтактнаяИнформация.Поле4,
| РегистрСведенийКонтактнаяИнформация.Поле5,
| РегистрСведенийКонтактнаяИнформация.Поле6,
| РегистрСведенийКонтактнаяИнформация.Поле7,
| РегистрСведенийКонтактнаяИнформация.Поле8,
| РегистрСведенийКонтактнаяИнформация.Поле9,
| РегистрСведенийКонтактнаяИнформация.Поле10,
| ВЫРАЗИТЬ(РегистрСведенийКонтактнаяИнформация.Комментарий КАК СТРОКА(1000)),
| РегистрСведенийКонтактнаяИнформация.ЗначениеПоУмолчанию,
| РегистрСведенийКонтактнаяИнформация.ТипДома,
| РегистрСведенийКонтактнаяИнформация.ТипКорпуса,
| РегистрСведенийКонтактнаяИнформация.ТипКвартиры
| ИЗ
| РегистрСведений.КонтактнаяИнформация КАК РегистрСведенийКонтактнаяИнформация
| ГДЕ
| РегистрСведенийКонтактнаяИнформация.Объект = &Объект) КАК ВложенныйЗапрос
|
|СГРУППИРОВАТЬ ПО
| ВложенныйЗапрос.Вид,
| ВложенныйЗапрос.Тип,
| ВложенныйЗапрос.Объект
|
|УПОРЯДОЧИТЬ ПО
| Представление УБЫВ,
| ВложенныйЗапрос.Тип.Порядок,
| Вид";
Благодаря этому изменению в результирующую выборку попадут исключительно фактически записанные в регистр данные. В форме контрагента будут отображаться только заполненные контактные данные, а при необходимости добавить новый контакт пользователь сможет воспользоваться стандартной кнопкой добавления строки.
Если конфигурация находится на поддержке без возможности изменения общих модулей, либо требуется скрыть строки только в конкретном экземпляре формы, настройку фильтра необходимо вынести за пределы обработчиков отрисовки строк.
Рассмотрим правила корректной работы со свойством ОтборСтрок:
ПередОткрытием или ПриОткрытии, либо сразу после вызова процедуры считывания контактных данных.ВидСравнения.НеРавно) либо специализированные проверки заполненности.ВЫРАЗИТЬ(... КАК СТРОКА(1000)) на уровне формирования источника данных.Посмотрим на пример корректной установки отбора в процедуре формы:
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
// Устанавливаем отбор однократно до вывода элементов на экран
ОтборПредставление = ЭлементыФормы.КонтактнаяИнформация.ОтборСтрок.Представление;
ОтборПредставление.ВидСравнения = ВидСравнения.НеРавно;
ОтборПредставление.Значение = "";
ОтборПредставление.Использование = Истина;
КонецПроцедуры
Чтобы избежать аварийных падений платформы «1С:Предприятие» при работе со сложными элементами управления в обычных формах, зафиксируем основные правила:
ОтборСтрок), видимость или доступность колонок внутри обработчиков ПриПолученииДанных и ПриВыводеСтроки.ВидСравнения.Содержит с пустой строкой в качестве шаблона.ВЫРАЗИТЬ в запросах, если по этим полям предполагается интерактивная или программная фильтрация в табличных полях.