Как правильно искать и редактировать ячейки в табличном документе 1С при наличии нескольких таблиц?

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

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

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

Причина проблемы: разница между объектом области и её именем

Рассмотрим ситуацию, описанную пользователем: при вызове метода НайтиТекст возвращается область, имя которой выглядит как "R2C1". Однако при попытке установить цвет фона Область.ЦветФона = Новый Цвет(255, 0, 0), изменения применяются не в той части документа, которую ожидал разработчик. Почему так происходит?

Основная ошибка заключается в попытке работать со строковым представлением адреса (свойство Имя). Когда мы получаем результат поиска, 1С возвращает нам готовый объект типа ОбластьТабличногоДокумента. Этот объект уже «знает», на какую конкретную ячейку или группу ячеек он ссылается в контексте всего документа. Если вы берете строку "R2C1" и заново обращаетесь к методу ТабДок.Область("R2C1"), платформа может вернуть область в самом начале документа, игнорируя тот факт, что искомая ячейка находится, например, глубоко во второй таблице.

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

Решение 1: Прямое управление объектом найденной области

Разберем, как правильно изменить свойства ячейки сразу после её обнаружения. Нам не нужно знать адрес "R2C1", чтобы покрасить ячейку. Мы используем возвращаемое значение метода напрямую.

Посмотрим на пример кода:


// Предположим, ТабДок уже сформирован
ИскомыйТекст = "лялля";
НайденнаяОбласть = ТабДок.НайтиТекст(ИскомыйТекст);

Если НайденнаяОбласть <> Неопределено Тогда
    // Красим именно ту ячейку, которую нашла система
    НайденнаяОбласть.ЦветФона = Новый Цвет(255, 0, 0);
    
    // Если нужно записать текст в ячейку справа, используем координаты
    НомерСтроки = НайденнаяОбласть.Верх;
    НомерКолонки = НайденнаяОбласть.Лево;
    
    ТабДок.Область(НомерСтроки, НомерКолонки + 1).Текст = "Данные обновлены";
КонецЕсли;

В данном примере мы используем свойства Верх и Лево объекта области. Они возвращают числовые индексы строки и колонки, что позволяет нам абсолютно точно позиционироваться в документе и обращаться к соседним ячейкам, не полагаясь на строковые имена.

Решение 2: Поиск во второй таблице с использованием «Области начала»

Если искомый текст встречается в первой таблице (которую менять не надо) и во второй, то простой вызов НайтиТекст всегда будет останавливаться на первом совпадении. Чтобы «пропустить» первую таблицу и искать во второй, необходимо использовать второй параметр метода — ОбластьНачала.

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


// Находим первое вхождение (в первой таблице)
ПервоеВхождение = ТабДок.НайтиТекст("Заголовок");

// Если нам нужно второе вхождение, передаем первое в качестве стартовой точки
ВтороеВхождение = ТабДок.НайтиТекст("Заголовок", ПервоеВхождение);

Если ВтороеВхождение <> Неопределено Тогда
    ВтороеВхождение.Шрифт = Новый Шрифт(,,Истина); // Делаем жирным
КонецЕсли;

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

Решение 3: Циклический поиск всех вхождений

Выясним причину, по которой иногда требуется перебор. Если текст «лялля» встречается многократно и нам нужно обработать каждое вхождение именно во второй части документа, эффективнее всего использовать цикл Пока.

Рассмотрим по шагам реализацию такого поиска:

  1. Устанавливаем переменную ТекущаяОбласть в значение Неопределено (начало поиска).
  2. В цикле вызываем НайтиТекст, передавая вторым параметром ТекущаяОбласть.
  3. Проверяем, найдено ли что-то и не вышли ли мы за пределы документа.
  4. Выполняем необходимые действия с ячейкой.

ТекстДляПоиска = "лялля";
НайденнаяОбласть = ТабДок.НайтиТекст(ТекстДляПоиска);

Пока НайденнаяОбласть <> Неопределено Цикл
    
    // Проверяем, что мы уже во второй таблице (например, после 50-й строки)
    Если НайденнаяОбласть.Верх > 50 Тогда
        НайденнаяОбласть.ЦветТекста = ЦветаСтиля.ЦветОтрицательногоЧисла;
    КонецЕсли;
    
    // Ищем следующее вхождение, начиная с текущего найденного
    НайденнаяОбласть = ТабДок.НайтиТекст(ТекстДляПоиска, НайденнаяОбласть);
    
КонецЦикла;

Особенности работы с СКД и объединенными ячейками

При использовании Системы Компоновки Данных (СКД) важно учитывать несколько нюансов:

  1. Момент поиска: Убедитесь, что поиск выполняется ПОСЛЕ того, как ПроцессорВывода закончил свою работу и полностью сформировал ТабличныйДокумент. Если вы пытаетесь искать в процессе вывода, вторая таблица может еще просто не существовать в документе.
  2. Объединенные области: Если искомый текст находится в объединенной ячейке, метод НайтиТекст вернет область, соответствующую только верхней левой ячейке этого объединения. При попытке применить оформление оно может примениться только к этой части, если не использовать свойство Область.Объединение.
  3. Фиксация макета: Если вы используете макеты оформления, программное изменение цвета фона может быть «перекрыто» стилем отчета. В таких случаях после программной правки убедитесь, что вы не вызываете методы повторной генерации табличного документа.

Подводя итог, можно сказать, что работа с ТабличнымДокументом требует строгого соблюдения объектной модели. Использование свойств Верх, Низ, Лево и Право объекта ОбластьТабличногоДокумента является самым надежным способом навигации и редактирования ячеек, исключающим путаницу с адресацией в сложных многотабличных отчетах.

← На главную