Работа с графическими объектами в среде 1С:Предприятие 7.7 существенно отличается от современных версий платформы. Одной из часто встречающихся задач является динамическое обновление изображений в уже выведенном на экран отчете (например, в каталоге номенклатуры с фотографиями). Рассмотрим ситуацию: таблица сформирована, пользователь кликает на ячейку, и нам нужно заменить картинку в этой строке, не заставляя пользователя заново формировать весь отчет и искать нужное место. Выясним причину, по которой штатные методы не всегда справляются, и разберем по шагам доступные способы решения.
В платформе 1С 7.7 табличный документ (файл с расширением .mox) после вывода методом Показать() становится статичным. Если для текстовых данных мы можем использовать конструкцию Т.Область(Адр).Текст = НовЗн, то с картинками ситуация сложнее. Картинка в 1С 7.7 — это внедренный объект (Shape), который «лежит» поверх сетки ячеек. При попытке получить текст из ячейки, где визуально находится картинка, мы часто видим странные отрицательные числа (например, -821751257). Проанализируем ситуацию: это внутренний идентификатор объекта в памяти, но штатный язык 1С не предоставляет методов, чтобы по этому ID обратиться к объекту «Рисунок» и вызвать у него метод типа Загрузить() или УстановитьКартинку().
Это самый надежный «бесплатный» метод, не требующий сторонних библиотек. Его суть заключается в том, что мы не меняем объект в памяти, а формируем таблицу заново, подменяя данные в источнике. Рассмотрим алгоритм реализации:
ТаблицаЗначений.ТаблицаЗначений.ОбработкаЯчейкиТаблицы(Значение, Флаг, Таб, Адрес) выполняем действия по изменению данных (например, выбор нового фото).ТаблицаЗначений.Чтобы пользователь не «прыгал» в начало документа после обновления, используем методы позиционирования. Разберем пример кода:
Процедура ОбработкаЯчейкиТаблицы(ЗначРасшифровки, Флаг, Таб, Адрес)
// Изменяем данные в источнике (ТЗДанные - наша таблица с путями к фото)
НомерСтрокиТЗ = Число(ЗначРасшифровки);
НовыйПуть = ВыбратьФайлКартинки();
ТЗДанные.УстановитьЗначение(НомерСтрокиТЗ, "ПутьКФото", НовыйПуть);
// Запоминаем текущее положение, чтобы вернуть пользователя туда же
ТекущаяСтрока = Таб.ТекущаяСтрока();
// Переформируем таблицу (вызываем основную функцию отчета)
СформироватьОтчет(0);
// Возвращаем фокус
Таб.Показать("Заголовок", "");
Таб.ТекущаяСтрока(ТекущаяСтрока);
КонецПроцедуры
Важный момент: для минимизации мерцания экрана можно использовать внешние компоненты (например, FormEx) для блокировки обновления экрана (LockWindowUpdate), но штатно 1С будет «моргать» при полной перерисовке.
Если полная перерисовка неприемлема из-за большого объема данных, воспользуемся мощным инструментом — компонентой Yoksel (Йоксель). Она превращает «мертвый» табличный документ 1С в живую объектную модель. Проанализируем, как это помогает нам в работе с графикой.
Yoksel позволяет получить доступ к коллекции графических объектов табличного документа. Мы можем найти нужный рисунок по его координатам или имени. Посмотрим на примерную логику работы с Йокселем:
ТабличныйДокумент через Йоксель.Рисунки (или Объекты), чтобы найти нужную картинку.ЗагрузитьИзФайла или прямой подменой двоичных данных обновляем изображение.Преимущество этого метода в том, что Йоксель умеет обновлять только измененную часть графического слоя, что происходит мгновенно и без визуального дискомфорта для пользователя.
Рассмотрим еще один вариант: использование объектов ActiveX (например, стандартный Image или 1С.Picture) вместо обычных рисунков 1С. В макете 1С 7.7 можно вставить «Объект» (Вставка -> Объект). Если вставить его как элемент управления, у него появляется программный интерфейс.
При формировании таблицы каждому такому объекту можно попытаться присвоить уникальное имя. Однако в 7.7 доступ к программно созданным объектам в ячейках после метода ПрисоединитьСекцию() крайне ограничен. Выясним причину: 1С клонирует объекты из макета, и они теряют связь с переменными кода. Этот метод лучше всего работает, если таблица не динамическая (фиксированный бланк), где мы можем заранее знать имена объектов.
Существует экзотический, но рабочий способ без внешних компонент для изменения картинок. Если картинка вставлена в ячейку как OLE-объект, теоретически можно попытаться манипулировать данными через буфер обмена. Рассмотрим последовательность действий:
ОбработкаЯчейкиТаблицы программно (через скрипты Windows или ВК) эмулируем нажатие клавиш Ctrl+V, предварительно выделив нужную область таблицы Таб.Область(Адрес).Выделить().Этот метод считается «грязным», так как он сильно зависит от фокуса окна и состояния буфера обмена пользователя, поэтому мы рекомендуем использовать его только в крайнем случае.
Проанализировав все доступные варианты, мы можем сделать следующие выводы:
1. Если отчет небольшой и время формирования невелико — используйте Способ 1 (Перерисовка). Это самый простой код, который легко поддерживать другим программистам. Для улучшения визуального восприятия обязательно используйте ТекущаяСтрока().
2. Для сложных интерактивных отчетов с сотнями фотографий оптимальным выбором будет Yoksel. Он дает полный контроль над графическим слоем mox-файла, который недоступен стандартными средствами v77.
3. При использовании картинок помните, что 1С 7.7 хранит их внутри таблицы, что может привести к раздуванию размера файла mox и падению производительности. Всегда старайтесь оптимизировать разрешение изображений перед выводом в таблицу.
Выбирая подходящее решение, всегда ориентируйтесь на критичность скорости работы и возможность установки сторонних компонент на рабочие станции пользователей.