Рассмотрим ситуацию, с которой иногда сталкиваются разработчики при работе с веб-клиентом 1С. Проблема заключается в том, что метод ПроверитьСтроку() начинает вести себя некорректно при установке множественного отбора в табличной части на форме. Разберем по шагам, как проявляется этот баг, выясним причину его возникновения и проанализируем доступные способы решения.
Проанализируем ситуацию подробнее. Пользователь работает в веб-клиенте (например, на платформе версии 8.3.18.1957) и использует нативный отбор в табличной части. Проблема воспроизводится по следующему сценарию:
ПроверитьСтроку() отрабатывает абсолютно корректно и показывает, удовлетворяет ли строка текущему условию.ПроверитьСтроку() вызывается повторно, но отрабатывает только по первому установленному отбору, игнорируя второе и все последующие условия.Важный момент: на обычном или тонком клиенте данная логика работает без ошибок, баг специфичен именно для веб-клиента.
Прежде чем исправлять ошибку, рассмотрим назначение самого метода. Метод ПроверитьСтроку() предназначен для проверки того, соответствует ли переданная строка текущему отбору, установленному пользователем в таблице формы. Этот метод доступен исключительно на клиенте, так как работает с элементами интерфейса (UI).
Посмотрим на особенности его работы:
Истина, если строка проходит проверку отбором, и Ложь в противном случае.Неопределено.Выясним причину такого странного поведения. Архитектура веб-клиента 1С кардинально отличается от десктопных клиентов. В веб-клиенте весь интерфейсный код, написанный на встроенном языке платформы, транслируется в JavaScript-код, который затем выполняется движком браузера. Обмен данными при этом идет через веб-сервер (например, Apache или IIS).
Ошибка игнорирования второго и последующих условий отбора в платформе 8.3.18 связана с некорректной трансляцией массива условий фильтрации в JavaScript-скриптах платформы. Из-за этого браузер просто "не видел" добавленные фильтры и проверял строку только по первому элементу массива отборов.
Проанализируем несколько путей решения данной проблемы, от самых простых к более сложным обходным путям.
Если обновление платформы для вас затратно или невозможно в данный момент, рассмотрим первый вариант. Часто проблема уходит после комплексного обновления стороннего ПО.
Почему это работает: новые версии браузеров имеют обновленные JS-движки, которые иначе обрабатывают сценарии, а обновление и перезагрузка веб-сервера устраняют проблемы с кэшированием старых модулей веб-клиента 1С.
Рассмотрим самое надежное решение — обновление платформы. Разработчики 1С признали этот баг и исправили его в более новых релизах. Если вы перейдете на свежую версию платформы (например, ветки 8.3.22 и выше, как подтверждено в обсуждении), метод ПроверитьСтроку() будет корректно обрабатывать множественные отборы прямо из коробки.
Если первые два варианта не подходят, разберем программный обходной путь. Поскольку встроенный метод ломается на клиенте, мы можем написать свою логику проверки на сервере.
Посмотрим на пример того, как можно эмулировать работу метода, используя серверный вызов и метод НайтиСтроки() для табличной части:
&НаКлиенте
Процедура ПроверкаСтрокиОбходнойПуть(Команда)
// Получаем текущую строку таблицы
ТекущиеДанные = Элементы.МояТабличнаяЧасть.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Формируем структуру с условиями отбора (собираем их вручную из элементов формы)
УсловияОтбора = Новый Структура;
УсловияОтбора.Вставить("Номенклатура", ТекущийОтборНоменклатура);
УсловияОтбора.Вставить("Склад", ТекущийОтборСклад);
// Вызываем нашу серверную функцию
СтрокаПодходит = ПроверитьСтрокуНаСервере(ТекущиеДанные.НомерСтроки, УсловияОтбора);
Если СтрокаПодходит Тогда
Сообщить("Строка соответствует отбору!");
Иначе
Сообщить("Строка скрыта отбором.");
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПроверитьСтрокуНаСервере(НомерСтроки, ПараметрыОтбора)
// Ищем строки в табличной части объекта по заданным параметрам
НайденныеСтроки = Объект.МояТабличнаяЧасть.НайтиСтроки(ПараметрыОтбора);
// Проверяем, есть ли наша строка среди результатов отбора
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Если НайденнаяСтрока.НомерСтроки = НомерСтроки Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Разберем по шагам предложенный код:
Структура, где ключ — это имя колонки, а значение — искомое значение.НайтиСтроки() к данным нашей табличной части.Таким образом, мы полностью обходим баг веб-клиента, перенося вычислительную нагрузку по фильтрации на сторону сервера приложения 1С.