Как получить список рисунков (диаграмм) в заданной области табличного документа 1С и определить их положение в строках?

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

При работе с табличными документами в системе 1С:Предприятие 8.3 часто возникает задача программного анализа содержимого, в том числе и графических элементов, таких как диаграммы, изображения или другие рисунки. Рассмотрим ситуацию, когда нам необходимо получить список рисунков, расположенных строго в определенном диапазоне строк табличного документа, и при этом определить их точное положение в терминах номеров строк, а не миллиметровых координат.

Представим, что у нас есть табличный документ, который содержит несколько диаграмм, выведенных, например, из отчета на Системе Компоновки Данных (СКД). Наша цель — найти все диаграммы, которые попадают, допустим, между строками 60 и 90 этого табличного документа. Стандартные свойства рисунков, такие как Верх и Низ, возвращают значения в миллиметрах, что требует дополнительного преобразования для сопоставления с номерами строк.

Особенности работы с рисунками и областями табличного документа

Прежде всего, давайте разберемся с основными концепциями. В 1С:Предприятии рисунки в табличном документе располагаются в отдельном "слое". Это означает, что они не являются непосредственным содержимым конкретных ячеек, хотя их положение может быть привязано к ячейкам или областям. Из-за такой архитектуры, непосредственно у объекта ОбластьТабличногоДокумента нет свойства Рисунки.

Для доступа ко всем рисункам, которые были добавлены в табличный документ, мы используем коллекцию ТабличныйДокумент.Рисунки. Каждый элемент этой коллекции представляет собой объект типа РисунокТабличногоДокумента, который обладает важными свойствами для определения положения и размеров:

  1. Верх: Определяет верхнюю границу рисунка в миллиметрах относительно верхнего края табличного документа.
  2. Низ: Определяет нижнюю границу рисунка в миллиметрах относительно верхнего края табличного документа.
  3. Лево: Определяет левую границу рисунка в миллиметрах относительно левого края табличного документа.
  4. Право: Определяет правую границу рисунка в миллиметрах относительно левого края табличного документа.
  5. Высота и Ширина: Определяют размеры рисунка в миллиметрах.

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

Ключевое решение: Использование метода ТабличныйДокумент.ПолучитьОбласть()

Для того чтобы получить список рисунков, которые фактически находятся в определенной области табличного документа (например, с 60 по 90 строку), мы не можем обратиться к свойству Рисунки у объекта ОбластьТабличногоДокумента, поскольку такого свойства там просто нет. Вместо этого мы воспользуемся очень мощным и важным методом — ТабличныйДокумент.ПолучитьОбласть().

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

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

Посмотрим на пример, как мы можем применить этот подход:


// Предположим, у нас уже есть сформированный объект ТабличныйДокумент.
// Например, ТабДок может быть результатом формирования отчета или загружен из файла.
// ТабДок = Новый ТабличныйДокумент;
// ... здесь ТабДок заполняется данными и рисунками ...

// Определяем интересующий нас диапазон строк для поиска рисунков
НачальнаяСтрокаПоиска = 60;
КонечнаяСтрокаПоиска  = 90;

// Очень важный шаг: получаем новый табличный документ, который является копией нужной нам области.
// Мы указываем диапазон колонок от 1 до ТабДок.МаксимальнаяКолонка, чтобы гарантировать,
// что рисунки не будут обрезаны по горизонтали и все горизонтально расположенные части попадут в выборку.
ОбластьДляАнализа = ТабДок.ПолучитьОбласть(НачальнаяСтрокаПоиска, 1, КонечнаяСтрокаПоиска, ТабДок.МаксимальнаяКолонка);

// Теперь у объекта ОбластьДляАнализа есть своя коллекция Рисунки.
// Эта коллекция будет содержать только те рисунки, которые попали в наш диапазон строк.
Если ОбластьДляАнализа.Рисунки.Количество() > 0 Тогда
    Сообщить("В указанной области найдено " + ОбластьДляАнализа.Рисунки.Количество() + " рисунков.");
    Для Каждого Рисунок Из ОбластьДляАнализа.Рисунки Цикл
        Сообщить("Найден рисунок: '" + Рисунок.Имя + 
                 "' (Верхняя граница: " + Рисунок.Верх + " мм, Нижняя граница: " + Рисунок.Низ + " мм)");
        // Важно понимать, что координаты Рисунок.Верх и Рисунок.Низ здесь
        // являются относительными к верхнему левому углу ОбластьДляАнализа,
        // а не к исходному ТабДок. Это критично для дальнейшего пересчета.
    КонецЦикла;
Иначе
    Сообщить("В указанной области рисунки не найдены.");
КонецЕсли;

Этот подход позволяет нам эффективно отфильтровать рисунки по вертикальному диапазону строк. Однако, как мы уже отметили в комментарии к коду, координаты Верх и Низ рисунков внутри этого нового объекта ОбластьДляАнализа будут выражены в миллиметрах относительно его собственного верхнего левого угла. Это означает, что если рисунок начинался в 70-й строке исходного документа, а ОбластьДляАнализа начинается с 60-й строки, то Рисунок.Верх будет отсчитываться от начала 60-й строки, а не от начала всего документа. Это необходимо учитывать при следующем шаге.

Детальное преобразование координат: из миллиметров в номера строк

Для точного определения номера строки, в которую попадает рисунок, нам необходимо перевести его миллиметровые координаты (`Верх`, `Низ`) в номера строк исходного табличного документа. Для этого мы должны знать высоту каждой строки или, по крайней мере, уметь ее определить. В 1С высота строки задается в пунктах (pt), а не в миллиметрах. Приблизительно 1 пункт равен 0.3527 миллиметра.

Разберем процесс преобразования по шагам:

  1. Создание карты высот строк исходного табличного документа:

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

    Мы будем итерировать по всем строкам исходного ТабДок, получать высоту каждой строки в пунктах с помощью свойства ВысотаСтроки объекта ОбластьЯчеекТабличногоДокумента и суммировать эти высоты, переводя их в миллиметры. Важно помнить, что в 1С размеры ячеек задаются с точностью до 0.25 пункта, что может влиять на итоговую точность пересчета.

    Представим, что мы создаем массив ГраницыСтрокВММ. ГраницыСтрокВММ[N] будет хранить суммарную высоту всех строк до конца строки N включительно, выраженную в миллиметрах. ГраницыСтрокВММ[0] будет равно 0.

    
    // Коэффициент пересчета из пунктов в миллиметры.
    // Это приближенное значение, в реальных условиях может потребоваться уточнение.
    // 1 пункт = 0.3527 мм
    КоэффициентПунктВММ = 0.3527; 
    
    // Инициализируем массив для хранения миллиметровых координат нижней границы каждой строки
    // Индекс массива соответствует номеру строки. Размер массива на 1 больше количества строк.
    ГраницыСтрокВММ = Новый Массив(ТабДок.КоличествоСтрок() + 1); 
    ГраницыСтрокВММ[0] = 0; // Нулевая координата перед первой строкой
    
    ТекущаяНакопленнаяВысотаВММ = 0;
    Для НомерСтроки = 1 По ТабДок.КоличествоСтрок() Цикл
        // Для получения высоты строки нам нужно получить ОбластьЯчеекТабличногоДокумента
        // для этой конкретной строки. Мы берем ее из основного ТабДок.
        ОбластьСтроки = ТабДок.Область(НомерСтроки, 1, НомерСтроки, 1);
                
        // Свойство ВысотаСтроки возвращает высоту в пунктах
        ВысотаСтрокиВПунктах = ОбластьСтроки.ВысотаСтроки;
    
        // Переводим высоту текущей строки в миллиметры
        ВысотаСтрокиВММ = ВысотаСтрокиВПунктах * КоэффициентПунктВММ;
                
        // Суммируем высоты, чтобы получить накопленную высоту до конца текущей строки
        ТекущаяНакопленнаяВысотаВММ = ТекущаяНакопленнаяВысотаВММ + ВысотаСтрокиВММ;
                
        // Записываем накопленную высоту (нижнюю границу строки) в массив
        ГраницыСтрокВММ[НомерСтроки] = ТекущаяНакопленнаяВысотаВММ;
    КонецЦикла;
    

    Теперь у нас есть массив ГраницыСтрокВММ, где ГраницыСтрокВММ[N] содержит миллиметровую координату нижней границы строки N (относительно верхнего края исходного табличного документа).

  2. Определение начальной и конечной строк для каждого рисунка:

    Имея миллиметровые координаты рисунка (`Верх`, `Низ`) из ОбластьДляАнализа и массив ГраницыСтрокВММ, мы можем определить, какие строки он охватывает. Однако, как было упомянуто ранее, координаты рисунков в ОбластьДляАнализа являются относительными к началу этой области.

    Поэтому нам необходимо сначала пересчитать эти относительные координаты рисунка в абсолютные координаты относительно верхнего края исходного ТабДок. Для этого нам нужно знать миллиметровое смещение начала нашей ОбластьДляАнализа от верхнего края исходного ТабДок. Это смещение можно получить из нашего массива ГраницыСтрокВММ, взяв значение для строки, предшествующей начальной строке нашей области.

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

    
    // Вспомогательная функция, которая по миллиметровой координате (относительно начала ТабДок)
    // определяет номер строки, в которую эта координата попадает.
    Функция ОпределитьНомерСтрокиПоКоординате(Знач КоординатаВММ, Знач ГраницыСтрокВМММассив)
        // Итерируем по массиву накопленных высот
        Для ИндексСтроки = 1 По ГраницыСтрокВМММассив.ВВерхнейГранице() - 1 Цикл // -1, так как 0-й элемент - это 0
            // Если координата меньше или равна накопленной высоте до конца текущей строки,
            // значит, эта координата находится в текущей строке или выше.
            Если КоординатаВММ <= ГраницыСтрокВМММассив[ИндексСтроки] Тогда
                Возврат ИндексСтроки;
            КонецЕсли;
        КонецЦикла;
        // Если координата больше максимальной накопленной высоты, она находится
        // после последней строки. В этом случае возвращаем номер последней строки.
        Возврат ГраницыСтрокВМММассив.ВВерхнейГранице() - 1; 
    КонецФункции;
    
    // Определим смещение начала нашей ОбластьДляАнализа в миллиметрах от верхнего края ТабДок.
    // Если НачальнаяСтрокаПоиска = 1, то смещение равно 0.
    СмещениеНачалаОбластиВММ = 0;
    Если НачальнаяСтрокаПоиска > 1 Тогда
        // Смещение равно нижней границе строки, предшествующей нашей НачальнойСтрокеПоиска
        СмещениеНачалаОбластиВММ = ГраницыСтрокВММ[НачальнаяСтрокаПоиска - 1];
    КонецЕсли;
    
    Для Каждого Рисунок Из ОбластьДляАнализа.Рисунки Цикл
        // Сначала пересчитываем относительные координаты рисунка (из ОбластьДляАнализа)
        // в абсолютные координаты относительно верхнего края исходного ТабДок.
        АбсолютныйВерхРисункаВММ = Рисунок.Верх + СмещениеНачалаОбластиВММ;
        АбсолютныйНизРисункаВММ  = Рисунок.Низ  + СмещениеНачалаОбластиВММ;
    
        // Используем вспомогательную функцию для определения начальной и конечной строк рисунка
        СтрокаНачалаРисунка = ОпределитьНомерСтрокиПоКоординате(АбсолютныйВерхРисункаВММ, ГраницыСтрокВММ);
        СтрокаОкончанияРисунка = ОпределитьНомерСтрокиПоКоординате(АбсолютныйНизРисункаВММ, ГраницыСтрокВММ);
    
        Сообщить("Рисунок '" + Рисунок.Имя + "' (из области): расположен между строками " + 
                 СтрокаНачалаРисунка + " - " + СтрокаОкончанияРисунка + " основного документа.");
    КонецЦикла;
    

Этот двухступенчатый процесс — сначала фильтрация рисунков с помощью ПолучитьОбласть(), а затем преобразование их координат с учетом относительности и карты высот строк — обеспечивает надежное и точное определение положения рисунков в табличном документе.

Важные нюансы и практические рекомендации

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

  1. Особенности переиндексации имен рисунков:

    Когда мы используем метод ПолучитьОбласть(), мы фактически создаем новый табличный документ, который является копией части исходного. При этом коллекция рисунков у этого нового документа будет формироваться заново. Если исходные рисунки не имели явно заданных имен (например, были автоматически сгенерированы), система может присвоить им новые, уникальные имена в рамках этого нового документа (например, "Диаграмма1", "Диаграмма2"). Эти новые имена могут отличаться от тех, что были у рисунков в исходном документе. Поэтому, если вы полагаетесь на имена рисунков для их идентификации, крайне важно убедиться, что эти имена были явно заданы — либо в конфигураторе при создании макета, либо программно при добавлении рисунков. В противном случае, для идентификации придется полагаться исключительно на их позиционные характеристики, которые мы как раз и учимся определять.

  2. Работа с динамически генерируемыми диаграммами:

    В случаях, когда диаграммы создаются динамически (например, в отчетах, построенных на Системе Компоновки Данных, СКД), их количество, имена и точное позиционирование могут сильно варьироваться в зависимости от данных и настроек пользователя. В таких сценариях полагаться на жестко заданные или автоматически сгенерированные имена рисунков нецелесообразно. Методы определения рисунков по их координатам и диапазонам строк, как мы рассмотрели, являются наиболее надежным и универсальным подходом для их идентификации и дальнейшей обработки.

  3. Вопрос точности пересчета координат:

    Использованный нами коэффициент пересчета из пунктов в миллиметры (0.3527) является приближенным. Внутренние механизмы 1С могут использовать более точные значения или оперировать с другими единицами измерения с большей детализацией. Для достижения максимальной точности в критически важных задачах вы можете попробовать эмпирически определить более точный коэффициент. Это можно сделать, создав в макете ячейку с известной высотой в пунктах, затем программно считав ее высоту в миллиметрах и вычислив фактическое соотношение. Также полезно помнить, что в конфигураторе 1С при ручном изменении высоты ячейки мышью в статусной строке иногда отображается высота в миллиметрах, что может помочь в калибровке. В большинстве практических задач, однако, стандартный коэффициент вполне достаточен.

  4. Различия между программным и пользовательским выделением:

    Важно не путать программный анализ рисунков с механизмом пользовательского выделения. Свойства ТабличныйДокумент.ТекущаяОбласть и ТабличныйДокумент.ВыделенныеОбласти относятся к текущему состоянию пользовательского интерфейса — они отражают то, что выделено пользователем в данный момент. Эти свойства не предназначены для систематического программного обхода или анализа всех рисунков в документе, а скорее для реакции на интерактивные действия пользователя.

Пример полного решения для получения рисунков в диапазоне строк

Соберем все рассмотренные шаги и принципы в единый, комплексный пример кода. Этот код можно использовать, например, в обработке или модуле формы, где у нас есть доступ к объекту ТабличныйДокумент.


// Предполагается, что эта процедура вызывается, например, из команды на форме,
// и объект ТабДок уже заполнен и содержит необходимые рисунки.
&НаКлиенте
Процедура НайтиРисункиВЗаданномДиапазонеСтрок(Команда)
    
    // Получаем текущий табличный документ, например, из элемента формы типа ПолеТабличногоДокумента
    Перем ТабДок;
    Если Не Элементы.ПолеТабличногоДокумента.ПолучитьФорматированныйДокумент(ТабДок) Тогда
        Сообщить("Не удалось получить табличный документ с формы.");
        Возврат;
    КонецЕсли;

    // Определяем начальную и конечную строки диапазона, в котором мы ищем рисунки.
    // Эти значения могут быть получены от пользователя или заданы программно.
    НачальнаяСтрокаПоиска = 60;
    КонечнаяСтрокаПоиска  = 90;

    // Выполняем предварительную проверку корректности заданного диапазона строк.
    Если НачальнаяСтрокаПоиска < 1 Или КонечнаяСтрокаПоиска > ТабДок.КоличествоСтрок() Или НачальнаяСтрокаПоиска > КонечнаяСтрокаПоиска Тогда
        Сообщить("Указан некорректный диапазон строк для поиска рисунков.");
        Возврат;
    КонецЕсли;

    Сообщить("Начинаем поиск рисунков между строками " + НачальнаяСтрокаПоиска + " и " + КонечнаяСтрокаПоиска + "...");

    // =========================================================================
    // ШАГ 1: Создание массива границ строк в миллиметрах для всего ТабДок.
    // Это ключевой шаг для последующего перевода миллиметровых координат рисунков в номера строк.
    // =========================================================================
    // Коэффициент для пересчета из пунктов (pt) в миллиметры (mm).
    // Стандартное значение: 1pt = 0.352778 mm. Здесь используется приближенное.
    КоэффициентПунктВММ = 0.3527; 

    // Массив будет хранить миллиметровую координату нижней границы каждой строки
    // относительно верхнего края ТабДок. Индекс массива = номер строки.
    // Размер: КоличествоСтрок() + 1, где 0-й элемент - это координата перед 1-й строкой.
    ГраницыСтрокВММ = Новый Массив(ТабДок.КоличествоСтрок() + 1);
    ГраницыСтрокВММ[0] = 0; // Верхняя граница перед первой строкой находится на 0 мм.

    ТекущаяНакопленнаяВысотаВММ = 0; // Переменная для накопления высоты в миллиметрах.

    // Проходим по всем строкам исходного табличного документа, чтобы вычислить их миллиметровые границы.
    Для НомерСтроки = 1 По ТабДок.КоличествоСтрок() Цикл
        // Получаем объект ОбластьЯчеекТабличногоДокумента для текущей строки.
        ОбластьСтроки = ТабДок.Область(НомерСтроки, 1, НомерСтроки, 1);
        
        // Получаем высоту строки в пунктах.
        ВысотаСтрокиВПунктах = ОбластьСтроки.ВысотаСтроки;

        // Переводим высоту строки из пунктов в миллиметры.
        ВысотаСтрокиВММ = ВысотаСтрокиВПунктах * КоэффициентПунктВММ;
        
        // Накапливаем общую высоту от начала документа до конца текущей строки.
        ТекущаяНакопленнаяВысотаВММ = ТекущаяНакопленнаяВысотаВММ + ВысотаСтрокиВММ;
        
        // Записываем накопленную высоту (нижнюю миллиметровую границу) для текущей строки.
        ГраницыСтрокВММ[НомерСтроки] = ТекущаяНакопленнаяВысотаВММ;
    КонецЦикла;

    // =========================================================================
    // ШАГ 2: Вспомогательная функция для определения номера строки.
    // Эта функция по заданной миллиметровой координате (абсолютной, от начала ТабДок)
    // находит соответствующий номер строки.
    // =========================================================================
    Функция ОпределитьНомерСтрокиПоММКоординате(Знач КоординатаВММ, Знач ГраницыСтрокВМММассив)
        // Итерируем по массиву накопленных высот (границ строк).
        Для ИндексСтроки = 1 По ГраницыСтрокВМММассив.ВВерхнейГранице() - 1 Цикл 
            // Если заданная координата меньше или равна нижней границе текущей строки,
            // значит, эта координата находится в текущей строке или выше. Возвращаем номер строки.
            Если КоординатаВММ <= ГраницыСтрокВМММассив[ИндексСтроки] Тогда
                Возврат ИндексСтроки;
            КонецЕсли;
        КонецЦикла;
        // Если координата превышает нижнюю границу последней строки,
        // считаем, что она относится к последней строке (или за ее пределами).
        Возврат ГраницыСтрокВМММассив.ВВерхнейГранице() - 1; 
    КонецФункции;

    // =========================================================================
    // ШАГ 3: Получение нового табличного документа, содержащего только интересующую область,
    // и последующий анализ рисунков в нем.
    // =========================================================================
    // Вычисляем миллиметровое смещение начала нашей интересующей области
    // относительно верхнего края исходного ТабДок.
    // Это необходимо, потому что Рисунок.Верх/Низ в ОбластьДляАнализа будут относительными.
    СмещениеНачалаОбластиВММ = 0;
    Если НачальнаяСтрокаПоиска > 1 Тогда
        // Смещение равно нижней миллиметровой границе строки, предшествующей началу нашей области.
        СмещениеНачалаОбластиВММ = ГраницыСтрокВММ[НачальнаяСтрокаПоиска - 1];
    КонецЕсли;

    // Создаем новый табличный документ, который является копией нашей целевой области.
    // Он будет содержать только те рисунки, которые попадают в заданные строки.
    ОбластьДляАнализа = ТабДок.ПолучитьОбласть(НачальнаяСтрокаПоиска, 1, КонечнаяСтрокаПоиска, ТабДок.МаксимальнаяКолонка);

    // Итерируем по коллекции рисунков, которые нашлись в ОбластьДляАнализа.
    Если ОбластьДляАнализа.Рисунки.Количество() > 0 Тогда
        Сообщить("В диапазоне строк " + НачальнаяСтрокаПоиска + " - " + КонечнаяСтрокаПоиска + 
                 " найдено " + ОбластьДляАнализа.Рисунки.Количество() + " рисунков:");
        
        Для Каждого Рисунок Из ОбластьДляАнализа.Рисунки Цикл
            // Пересчитываем относительные координаты рисунка (Верх, Низ) из ОбластьДляАнализа
            // в абсолютные миллиметровые координаты относительно верхнего края исходного ТабДок.
            АбсолютныйВерхРисункаВММ = Рисунок.Верх + СмещениеНачалаОбластиВММ;
            АбсолютныйНизРисункаВММ  = Рисунок.Низ  + СмещениеНачалаОбластиВММ;

            // Используем нашу вспомогательную функцию для определения начальной и конечной строк рисунка
            // в контексте исходного ТабДок.
            СтрокаНачалаРисунка = ОпределитьНомерСтрокиПоММКоординате(АбсолютныйВерхРисункаВММ, ГраницыСтрокВММ);
            СтрокаОкончанияРисунка = ОпределитьНомерСтрокиПоММКоординате(АбсолютныйНизРисункаВММ, ГраницыСтрокВММ);

            Сообщить("    Рисунок: '" + Рисунок.Имя + 
                     "', Верх: " + Формат(Рисунок.Верх, "ЧДЦ=2") + " мм, Низ: " + Формат(Рисунок.Низ, "ЧДЦ=2") + " мм" + 
                     " (в исходном документе находится между строками: " + СтрокаНачалаРисунка + " - " + СтрокаОкончанияРисунка + ")");
        КонецЦикла;
    Иначе
        Сообщить("В заданном диапазоне строк рисунки не найдены.");
    КонецЕсли;

КонецПроцедуры

// Примечание: Для выполнения этого кода на управляемой форме необходимо:
// 1. Разместить на форме элемент "ПолеТабличногоДокумента" с именем "ПолеТабличногоДокумента".
// 2. В обработчике события "ПриСозданииНаСервере" или в другом подходящем месте создать и заполнить
//    объект ТабличныйДокумент, добавить в него рисунки и установить его в элемент формы:
//    ТабДок = Новый ТабличныйДокумент;
//    // ... код по заполнению ТабДок и добавлению рисунков ...
//    Элементы.ПолеТабличногоДокумента.УстановитьДокумент(ТабДок);
// 3. Создать команду на форме, привязать ее к кнопке и в обработчике команды вызвать процедуру
//    "НайтиРисункиВЗаданномДиапазонеСтрок".

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

← На главную