Как программно изменить размер картинки в печатной форме 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке печатных форм в системе 1С:Предприятие 7.7 разработчики часто сталкиваются с аппаратными ограничениями штатного табличного документа (так называемого "Мокселя"). Одной из наиболее острых проблем является невозможность напрямую управлять геометрическими размерами и координатами рамки рисунка из встроенного языка 1С. Попытка динамически загрузить картинку (например, логотип компании, изображение товара или факсимиле подписи) в заранее подготовленный макет часто приводит к тому, что изображение либо искажается, либо не влезает в отведенные рамки.

В этой статье мы подробно разберем, как обойти это ограничение платформы. Мы изучим несколько альтернативных подходов: от штатного позиционирования с привязкой к ячейкам до использования мощной внешней компоненты Йоксель (Yoksel) и встроенных системных библиотек Windows для работы с метаданными изображений.

Метод 1. Штатный способ динамического масштабирования через привязку к сетке ячеек

Самый простой и надежный способ управлять физическим размером картинки программно без привлечения сторонних библиотек — это использование механизма привязки графического объекта к сетке ячеек таблицы 1С. Выясним, как работает этот алгоритм.

По умолчанию любой рисунок, добавленный в макет 1С 7.7, позиционируется независимо от ячеек. Однако мы можем изменить это поведение:

  1. Откроем макет печатной формы в конфигураторе.
  2. Выделим рамку нашей картинки (рисунка), кликнем правой кнопкой мыши и перейдем в «Свойства».
  3. Перейдем на вкладку «Положение» (Position).
  4. Установим переключатель в положение «Перемещать и изменять размеры вместе с ячейками» (или «Привязать к ячейке»).

После активации этого режима границы рамки жестко привязываются к индексам строк и колонок таблицы. Теперь, чтобы программно изменить физический размер графического "окна" на экране или при печати, нам достаточно программно изменить высоту строк и ширину колонок, на пересечении которых находится данный рисунок.

Проанализируем пример кода, который выполняет масштабирование ячеек под нужные физические параметры:


// Создаем табличный документ
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("МакетСКартинкой");

// Выводим секцию, содержащую привязанную картинку
Таб.ВывестиСекцию("Шапка");

// Определяем область ячеек, к которым привязан наш рисунок.
// Допустим, рисунок расположен в диапазоне строк с 3 по 5 и колонок с 2 по 4.
СтрокаСтарт = 3;
СтрокаКонец = 5;
КолонкаСтарт = 2;
КолонкаКонец = 4;

// Задаем новые физические размеры для ячеек (в пунктах для высоты и символах для ширины)
НоваяВысотаСтроки = 45; // Примерное значение высоты
НоваяШиринаКолонки = 18; // Примерное значение ширины

// Применяем изменения к области таблицы
Для НомерСтроки = СтрокаСтарт По СтрокаКонец Цикл
    Таб.Область(НомерСтроки, , НомерСтроки, ).ВысотаСтроки(НоваяВысотаСтроки);
КонецЦикла;

Для НомерКолонки = КолонкаСтарт По КолонкаКонец Цикл
    Таб.Область(, НомерКолонки, , НомерКолонки).ШиринаСтолбца(НоваяШиринаКолонки);
КонецЦикла;

// Показываем готовый документ пользователю
Таб.Показать("Печать документа");

Благодаря этому методу картинка автоматически сожмется или растянется вслед за ячейками таблицы. Это исключает необходимость создавать десятки дублирующих секций под разные размеры в конфигураторе.

Метод 2. Использование возможностей компоненты Йоксель (Yoksel)

Если штатных возможностей масштабирования ячеек недостаточно, на помощь приходит специализированная внешняя компонента Йоксель. Она полностью заменяет стандартный движок отображения таблиц 1С 7.7 и предоставляет разработчику колоссальный набор инструментов для работы с графикой.

С помощью Йокселя мы можем напрямую обращаться к объекту графики, динамически создавать рисунки в памяти, точно задавать их координаты в пикселях и изменять размеры изображений "на лету" перед выводом на печать.

Рассмотрим пример загрузки и изменения размеров картинки с использованием объекта Йоксель.Картинка:


// Загружаем внешнюю компоненту Йоксель
Если ЗагрузитьВнешнююКомпоненту("yoksel.dll") = 0 Тогда
    Предупреждение("Компонента Йоксель не найдена!");
    Возврат;
КонецЕсли;

// Создаем объект графического изображения Йоксель
ЙоксКартинка = СоздатьОбъект("Йоксель.Картинка");

// Загружаем файл изображения с диска
ПутьКФайлу = "C:\images\logo.jpg";
ЙоксКартинка.Загрузить(ПутьКФайлу);

// Программно изменяем размеры картинки до точных значений в пикселях (Ширина, Высота)
НоваяШиринаПикс = 300;
НоваяВысотаПикс = 150;
ЙоксКартинка.ИзменитьРазмер(НоваяШиринаПикс, НоваяВысотаПикс);

// Теперь мы можем сохранить отмасштабированное изображение или внедрить его
// непосредственно в отчет Йокселя по точным координатам без привязки к ячейкам макета.

Использование Йокселя полностью решает проблему "сломанных" макетов, поскольку вся геометрия и параметры позиционирования прописываются непосредственно в коде модуля и не зависят от случайных действий пользователей в конфигураторе.

Метод 3. Определение реальных размеров картинки встроенными средствами Windows

Часто перед тем как выводить изображение в табличный документ, программисту требуется узнать оригинальное разрешение файла (ширину и высоту в пикселях), чтобы рассчитать пропорции рамки. Вместо тяжелых внешних библиотек можно задействовать стандартные интерфейсы операционной системы Windows через OLE/COM-соединение.

Вариант А. Использование библиотеки WIA (Windows Image Acquisition)

Компонента WIA предустановлена во всех современных версиях операционных систем семейства Windows и позволяет мгновенно считывать свойства медиафайлов.

Разберем по шагам, как прочитать разрешение файла:


Функция ПолучитьРазмерыКартинкиWIA(ПутьКФайлу, Ширина, Высота)
    Попытка
        WiaImage = СоздатьОбъект("WIA.ImageFile");
        WiaImage.LoadFile(ПутьКФайлу);
        Ширина = WiaImage.Width;
        Высота = WiaImage.Height;
        Возврат 1;
    Исключение
        Сообщить("Ошибка при чтении файла через WIA: " + ОписаниеОшибки(), "!");
        Возврат 0;
    КонецПопытки;
КонецФункции

Вариант Б. Использование интерфейса Shell.Application

Если по какой-то причине библиотека WIA недоступна, мы можем прочитать метаданные файла напрямую из проводника Windows с помощью объекта Shell.Application:


Функция ПолучитьРазмерыЧерезShell(КаталогФайла, ИмяФайла, Ширина, Высота)
    Попытка
        Shell = СоздатьОбъект("Shell.Application");
        Folder = Shell.Namespace(КаталогФайла);
        FolderItem = Folder.ParseName(ИмяФайла);
        
        // Индекс 31 в свойствах проводника Windows отвечает за размеры (ширина х высота)
        РазмерыТекст = Folder.GetDetailsOf(FolderItem, 31);
        
        // Текст возвращается в формате "‎?300 x 150‎", очистим его от лишних символов
        ОчищенныйТекст = "";
        Для НомерСимвола = 1 По СтрДлина(РазмерыТекст) Цикл
            Симв = Сред(РазмерыТекст, НомерСимвола, 1);
            Если Найти("0123456789x ", Симв) > 0 Тогда
                ОчищенныйТекст = ОчищенныйТекст + Симв;
            КонецЕсли;
        КонецЦикла;
        
        // Разбираем строку на ширину и высоту
        ПозицияРазделителя = Найти(ОчищенныйТекст, "x");
        Если ПозицияРазделителя > 0 Тогда
            Ширина = СокрЛП(Лев(ОчищенныйТекст, ПозицияРазделителя - 1));
            Высота = СокрЛП(Сред(ОчищенныйТекст, ПозицияРазделителя + 1));
            Возврат 1;
        КонецЕсли;
    Исключение
        Сообщить("Ошибка Shell: " + ОписаниеОшибки());
    КонецПопытки;
    Возврат 0;
КонецФункции

Метод 4. Настройка пропорций через метод РежимРисования()

При динамической загрузке изображений в подготовленный макет критически важно правильно настроить поведение картинки внутри рамки. Платформа 1С 7.7 предоставляет встроенный метод РежимРисования(), который применяется к объекту типа "Рисунок" в таблице.

Выясним, какие режимы нам доступны и как они влияют на визуализацию изображения:

Проанализируем пример применения режима сохранения пропорций в сочетании с динамической загрузкой файла:


Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Макет");
Таб.ВывестиСекцию("КартинкаТовара");

// Получаем доступ к объекту рисунка по его имени в макете
// Предположим, что рисунок в макете назван "Логотип"
Попытка
    Рис = Таб.Рисунок("Логотип");
    
    // Устанавливаем режим рисования "Сохранять пропорции"
    Рис.РежимРисования(3);
    
    // Загружаем изображение
    Рис.Загрузить("C:\images\product.png");
Исключение
    Сообщить("Не удалось загрузить картинку в макет: " + ОписаниеОшибки());
КонецПопытки;

Подведем итоги

Мы подробно разобрали, как решать проблему фиксированных размеров макетов в 1С 7.7. Наш анализ показывает, что:

  1. Для простых отчетов без внешних библиотек идеальным выбором будет комбинация привязки рисунка к сетке ячеек (Метод 1) и установка режима сохранения пропорций РежимРисования(3).
  2. Если требуется пиксельная точность, динамическое формирование сложных графических прайс-листов или каталогов продукции, следует использовать внешнюю компоненту Йоксель (Метод 2).
  3. Для проверки корректности файлов перед печатью и динамического анализа пропорций можно использовать встроенные системные COM-объекты Windows вроде WIA или Shell без установки дополнительного софта на рабочие станции пользователей.
← На главную