Как извлечь и сравнить картинки в табличном документе 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Причина ошибки «Поле объекта недоступно для чтения (Картинка)»

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

  1. Разница между Область() и ПолучитьОбласть(): метод Область() возвращает объект ОбластьЯчеекТабличногоДокумента, у которого нет прямой коллекции рисунков ячейки. Для доступа к отдельным элементам оформления используется свойство Рисунки самого документа или создаваемой области.
  2. Несоответствие типа рисунка: объект РисунокТабличногоДокумента может содержать не только графическое изображение, но и текст, диаграмму или геометрическую фигуру. Свойство Картинка доступно только в том случае, если ТипРисунка имеет значение ТипРисункаТабличногоДокумента.Картинка.

Правильное извлечение рисунков из табличного документа

Рассмотрим два подхода к получению графических объектов из таблицы:

Способ 1: Прямой обход всей коллекции документа (рекомендуемый)

Вызов метода ПолучитьОбласть() в цикле для каждой ячейки создает избыточные копии фрагментов документа в оперативной памяти. Для быстрого анализа большого отчета эффективнее перебрать коллекцию ТабличныйДокумент.Рисунки напрямую и проанализировать позицию каждого элемента через свойство Расположение.


Для Каждого ТекРисунок Из ТабДокумент.Рисунки Цикл
    Если ТекРисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Картинка Тогда
        ОбластьПривязки = ТекРисунок.Расположение; // ОбластьЯчеекТабличногоДокумента
        ТекКартинка = ТекРисунок.Картинка;
        
        // Получаем координаты ячейки
        НомерСтроки = ОбластьПривязки.Верх;
        НомерКолонки = ОбластьПривязки.Лево;
    КонецЕсли;
КонецЦикла;

Способ 2: Получение рисунка по имени из конкретной области

Если требуется получить рисунок из конкретного именованного сектора или по координатам ячейки, используем обращение к коллекции рисунков полученной области:


ОбластьЯчейки = ТабДокумент.ПолучитьОбласть("R9C3");
Если ОбластьЯчейки.Рисунки.Количество() > 0 Тогда
    РисунокЯчейки = ОбластьЯчейки.Рисунки[0];
    Если РисунокЯчейки.ТипРисунка = ТипРисункаТабличногоДокумента.Картинка Тогда
        Изображение = РисунокЯчейки.Картинка;
    КонецЕсли;
КонецЕсли;

Как правильно сравнить два графических объекта на равенство

Важно помнить, что стандартный оператор = для типа Картинка выполняет проверку равенства ссылок на объекты в памяти. Две совершенно одинаковые иконки, извлеченные из разных строк документа, при прямом сравнении через Картинка1 = Картинка2 вернут результат Ложь.

Для корректной проверки содержимого необходимо сравнивать их двоичные данные или вычислять хеш-сумму.

Вариант 1: Сравнение через Base64-строку

Для небольших пиктограмм и значков статусов наиболее наглядным является преобразование двоичных данных в строку Base64:


Функция КартинкиОдинаковыеBase64(Картинка1, Картинка2)
    ДвоичныеДанные1 = Картинка1.ПолучитьДвоичныеДанные();
    ДвоичныеДанные2 = Картинка2.ПолучитьДвоичныеДанные();
    
    Возврат Base64Строка(ДвоичныеДанные1) = Base64Строка(ДвоичныеДанные2);
КонецФункции

Вариант 2: Сравнение по хеш-сумме (MD5 / SHA256)

Когда требуется многократно сверять графические маркеры строк с эталонными образцами, оптимально один раз вычислить хеш-сумму эталонов и сравнивать только полученные строки хешей:


Функция ПолучитьХешКартинки(ОбъектКартинка)
    ДвоичныеДанные = ОбъектКартинка.ПолучитьДвоичныеДанные();
    Возврат ПолучитьХешСуммуИзДвоичныхДанных(ДвоичныеДанные, ХешФункция.MD5);
КонецФункции

// Пример использования при анализе отчета
ХешЭталонаУдален = "d41d8cd98f00b204e9800998ecf8427e"; // Предварительно рассчитанный хеш

Для Каждого ТекРисунок Из ТабДокумент.Рисунки Цикл
    Если ТекРисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Картинка Тогда
        Если ПолучитьХешКартинки(ТекРисунок.Картинка) = ХешЭталонаУдален Тогда
            Сообщить("В строке " + ТекРисунок.Расположение.Верх + " найден удаленный объект");
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Побайтовое сравнение и сверка по MD5/SHA256 гарантированно работают для системных значков 1С и пиктограмм стандартных отчетов, так как они формируются платформой из одних и тех же исходных графических ресурсов.

← На главную