При программном анализе отчетов, макетов или результатов сравнения конфигураций нередко возникает задача распознавания пиктограмм в ячейках табличного документа. Разберем по шагам, как правильно получить доступ к графическим объектам табличного документа, избежать типичных ошибок платформы и выполнить надежное сравнение двух изображений.
Попытка обратиться напрямую к свойству через ячейку вида Область.Примечание или неверное использование методов выборки областей приводит к ошибкам времени выполнения. Проанализируем, почему это происходит:
Область() и ПолучитьОбласть(): метод Область() возвращает объект ОбластьЯчеекТабличногоДокумента, у которого нет прямой коллекции рисунков ячейки. Для доступа к отдельным элементам оформления используется свойство Рисунки самого документа или создаваемой области.РисунокТабличногоДокумента может содержать не только графическое изображение, но и текст, диаграмму или геометрическую фигуру. Свойство Картинка доступно только в том случае, если ТипРисунка имеет значение ТипРисункаТабличногоДокумента.Картинка.Рассмотрим два подхода к получению графических объектов из таблицы:
Способ 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С и пиктограмм стандартных отчетов, так как они формируются платформой из одних и тех же исходных графических ресурсов.