Работа с графическими объектами в табличных документах 1С:Предприятие требует особого внимания к деталям позиционирования и управлению коллекциями объектов. Часто разработчики сталкиваются с ситуацией, когда при выводе нескольких строк с картинками изображения начинают «наслаиваться» друг на друга, дублироваться или вовсе исчезать. Рассмотрим подробнее, почему это происходит и как правильно организовать вывод чертежей или фотографий в печатную форму.
Основная причина «задвоения» изображений кроется в механизме работы метода ПолучитьОбласть(). Когда мы вызываем этот метод в цикле, система может возвращать ссылку на один и тот же объект области в памяти (кэширование). Если внутри цикла мы используем команду Рисунки.Добавить(), то при каждой новой итерации в коллекцию Рисунки этой области добавляется новый графический объект, в то время как старые никуда не исчезают. В итоге в первой строке документа выводится одна картинка, во второй — две (новая и старая), в третьей — три и так далее.
Проанализируем ситуацию, когда изображение не выводится вовсе во второй области. Это часто связано с неправильным использованием метода Расположить() или его полным отсутствием. Без указания точных координат в рамках области рисунок может иметь нулевой размер или располагаться за пределами видимости.
Если вы решили добавлять рисунки динамически с помощью кода, необходимо соблюдать строгую последовательность действий. Главное правило: рисунок нужно располагать внутри области макета до того, как эта область будет выведена в итоговый документ.
Разберем по шагам правильный алгоритм:
Расположить().Посмотрим на пример корректного кода:
Для Каждого СтрокаТЧ Из ТехнологическиеОперации Цикл
// Получаем область заново на каждой итерации для чистоты объекта
ОбластьЧертёж1 = Макет.ПолучитьОбласть("Строка|Ч1");
// Обязательно очищаем рисунки, если область берется из кэша
ОбластьЧертёж1.Рисунки.Очистить();
// Добавляем рисунок
Рис1 = ОбластьЧертёж1.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
// Загружаем данные из ХранилищаЗначений
ДанныеКартинки = СтрокаТЧ.Чертёж1.Чертёж.Получить();
Если ДанныеКартинки <> Неопределено Тогда
Рис1.Картинка = ДанныеКартинки;
// Позиционируем рисунок.
// Важно: метод Расположить() вызывается для ОБЛАСТИ МАКЕТА,
// а не итогового документа.
Рис1.Расположить(ОбластьЧертёж1.Область(1, 1));
// Настройка пропорций
Рис1.РазмерКартинки = РазмерКартинки.Пропорционально;
КонецЕсли;
ДокументРезультат.Присоединить(ОбластьЧертёж1);
КонецЦикла;
Обратите внимание на использование ОбластьЧертёж1.Область(1, 1) внутри метода Расположить(). Это указывает системе, что картинка должна занять место, начиная с первой ячейки текущего фрагмента макета.
Этот метод считается более надежным и менее трудозатратным с точки зрения написания кода. Вместо того чтобы создавать объекты программно, мы заранее размещаем их в макете визуально.
Выясним причину, по которой этот метод предпочтительнее: вам не нужно программно вычислять координаты, высоту и ширину. Вы просто рисуете прямоугольник в макете, задаете ему имя (например, D9) и настраиваете его свойства (рамки, тип масштабирования) через палитру свойств 1С.
Рассмотрим, как изменится код при таком подходе:
Для Каждого СтрокаТЧ Из ТехнологическиеОперации Цикл
ОбластьЧертёж2 = Макет.ПолучитьОбласть("Строка|Ч2");
// Находим уже существующий в макете рисунок по имени
ПолеКартинки = ОбластьЧертёж2.Рисунки.D10;
Данные = СтрокаТЧ.Чертёж2.Чертёж.Получить();
Если Данные <> Неопределено Тогда
ПолеКартинки.Картинка = Данные;
ПолеКартинки.Видимость = Истина;
Иначе
// Если картинки нет, скрываем объект-пустышку
ПолеКартинки.Видимость = Ложь;
КонецЕсли;
ДокументРезультат.Присоединить(ОбластьЧертёж2);
КонецЦикла;
Важный момент: Если вы используете статические рисунки в макете, их не нужно «добавлять» через Рисунки.Добавить(). Вы просто обращаетесь к ним по имени, которое задали в конфигураторе.
При выводе чертежей критически важно сохранять их читаемость и пропорции. Для этого у объекта РисунокТабличногоДокумента существует свойство РазмерКартинки. Рассмотрим основные варианты:
Расположить, что может привести к искажениям (чертеж станет «сплюснутым»).Проанализируем ситуацию с производительностью. Если ваш отчет содержит сотни строк с изображениями высокого разрешения, память сервера или клиентского приложения может быстро закончиться. 1С хранит картинки в табличном документе в несжатом виде.
Для оптимизации рекомендуем:
Если ТипЗнч(Данные) = Тип("Картинка") Тогда....Очистить() для коллекции рисунков, если область макета используется многократно.Также стоит помнить, что метод Расположить() может принимать не только одну ячейку, но и целую область. Например, Рис.Расположить(Область.Область("R1C1:R5C5")) позволит растянуть картинку на блок ячеек 5 на 5.
Если вы столкнулись с тем, что конфигуратор «ругается» на отсутствие области при вызове Расположить(ДокументРезультат.Область(...)), это происходит потому, что в итоговом документе строки еще не сформированы или координаты указаны неверно. Всегда старайтесь позиционировать рисунок относительно локальной области макета (где координаты всегда начинаются с 1, 1), а уже потом выводить эту область в итоговый отчет.
Подводя итог, можно сказать: для стабильной работы печатной формы лучше всего использовать именованные рисунки-пустышки в макете. Это избавляет от необходимости сложного позиционирования и исключает риск накопления (задвоения) объектов в памяти табличного документа.