При разработке интерактивных рабочих мест в 1С, таких как схемы складов, карты цехов или визуализация расположения оборудования, программисты часто используют объект ТабличныйДокумент и его коллекцию Рисунки. Однако работа в веб-клиенте существенно отличается от работы в тонком или толстом клиенте. Часто возникает ситуация, когда при попытке изменить цвет фона одного рисунка (например, выбранного станка на схеме), окрашиваются абсолютно все рисунки на форме, либо изменения не отображаются вовсе до полной перезагрузки страницы.
В этой статье мы подробно разберем, почему веб-клиент ведет себя именно так, проанализируем внутренние механизмы платформы и найдем эффективные способы решения задачи.
Разберем первопричину проблемы. В обычном приложении или тонком клиенте 1С отрисовка табличного документа происходит средствами графического движка самой платформы или операционной системы. Каждый объект РисунокТабличногоДокумента является отдельным экземпляром с индивидуальным набором свойств.
В веб-клиенте ситуация иная: 1С преобразует ТабличныйДокумент в набор HTML-тегов и CSS-стилей. Для оптимизации объема передаваемых данных платформа часто группирует визуально похожие объекты. Если у вас на форме расположено несколько десятков рисунков одного типа, веб-клиент может создать для них общий CSS-класс. При динамическом изменении свойства ЦветФона через код ТабДокумент.Рисунки.ИмяРисунка.ЦветФона, движок веб-клиента может ошибочно обновить этот общий стиль, что приведет к визуальному изменению всех связанных объектов. Это является известной особенностью (а иногда и багом) платформы при работе с DOM-моделью документа в браузере.
Для начала проанализируем, как правильно обращаться к рисунку. Использование строкового имени в квадратных скобках Рисунки["Имя"] в веб-клиенте иногда работает нестабильно, особенно если имена формируются динамически. Рассмотрим более надежный способ через индекс:
// Получаем индекс рисунка по его имени
ИмяНужногоРисунка = "Picture" + Элементы.Список.ТекущиеДанные.Код;
Рисунок = ТабДокумент.Рисунки.Найти(ИмяНужногоРисунка);
Если Рисунок <> Неопределено Тогда
Индекс = ТабДокумент.Рисунки.Индекс(Рисунок);
// Обращаемся строго по индексу для стабильности в WEB
ТабДокумент.Рисунки.Получить(Индекс).ЦветФона = WebЦвета.КрасноФиолетовый;
КонецЕсли;
Также крайне важно использовать свойство ПараметрРасшифровки. При клике на рисунок в веб-клиенте идентификация по имени может сбоить, а расшифровка передается надежнее. Мы рекомендуем записывать уникальный идентификатор объекта (например, ссылку или код) именно в расшифровку при создании рисунка.
Проанализируем вторую часть проблемы: изменения внесены в код, но на экране ничего не поменялось. Конструкция ТабДокумент = ТабДокумент; — это старый «хак», который заставляет платформу считать, что данные реквизита изменились, и инициирует перерисовку. Однако в веб-клиенте этого часто недостаточно.
Рассмотрим способы, которые реально заставляют браузер обновить картинку:
ОбновитьИнтерфейс(): Этот метод пересчитывает видимость и доступность элементов, а также может спровоцировать перерисовку связанных данных.Высота или Ширина на 1. Это заставляет JS-движок 1С пересчитать стили конкретного элемента.Рассмотрим по шагам, как реализовать выделение выбранного оборудования на схеме так, чтобы это работало в браузере.
Шаг 1. Сброс оформления всех рисунков. Перед тем как выделить новый объект, нужно очистить предыдущее выделение. Проанализируем цикл обработки:
Для Каждого Рис Из ТабДокумент.Рисунки Цикл
// Проверяем, что это именно наш тип рисунка (например, по префиксу имени)
Если Найти(Рис.Имя, "Picture") > 0 Тогда
Рис.ЦветФона = WebЦвета.Белый;
// Можно также сбросить линию или узор
Рис.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии);
КонецЕсли;
КонецЦикла;
Шаг 2. Выделение активного объекта. Теперь находим нужный рисунок и меняем его свойства. Обратите внимание на установку линии — это дополнительно помогает браузеру корректно отрисовать границы объекта.
ИмяРисунка = "Picture" + СсылкаНаОбъект.Код;
ВыбранныйРисунок = ТабДокумент.Рисунки.Найти(ИмяРисунка);
Если ВыбранныйРисунок <> Неопределено Тогда
ВыбранныйРисунок.ЦветФона = WebЦвета.КрасноФиолетовый;
// Добавляем рамку, чтобы объект "выделился" для движка рендеринга
ВыбранныйРисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.Сплошная, 1);
КонецЕсли;
Шаг 3. Сохранение изменений в БД. Если табличный документ хранится в реквизите типа ХранилищеЗначения, важно правильно выполнять перезапись. Посмотрим на пример кода:
&НаСервере
Процедура СохранитьСхемуНаСервере(ПомещениеСсылка, ВременныйТабДок)
ОбъектПомещение = ПомещениеСсылка.ПолучитьОбъект();
ОбъектПомещение.Схема = Новый ХранилищеЗначения(ВременныйТабДок);
ОбъектПомещение.Записать();
КонецПроцедуры
Проанализируем ситуацию, описанную в сообщениях форума, когда рисунки добавляются динамически. Выясним причину, по которой РазмерКартинки.Пропорционально может влиять на отображение фона. В веб-клиенте картинка внутри рисунка может перекрывать собой фон самого контейнера Рисунок. Если ваша картинка (PNG или JPG) не имеет прозрачности и занимает всю площадь рисунка, изменение ЦветФона просто не будет видно за самим изображением.
Совет: Используйте изображения с прозрачным фоном (PNG) и устанавливайте свойство Узор в значение Сплошной. Это гарантирует, что установленный вами ЦветФона будет просвечивать сквозь прозрачные области картинки.
Работа с графикой в веб-клиенте 1С требует понимания того, как платформа транслирует объекты в HTML. Если вы столкнулись с тем, что «красится всё сразу», помните — это не ошибка вашей логики, а особенность оптимизации стилей браузером. Используйте обращение по индексам, принудительно обновляйте свойства границ (линий) и при необходимости делайте «микро-изменения» размеров объектов для инициации индивидуальной перерисовки элемента.