Разработка и Конфигурация · 10 мин
Как перебрать табличный документ в 1С
Как перебрать табличный документ 1С в цикле: чтение ячеек, обход областей, работа с ТекущаяОбласть, примеры кода на встроенном языке и типичные ошибки разработчиков.
Перебор табличного документа — типовая задача при разработке на платформе 1С:Предприятие. Она возникает, когда нужно прочитать данные из макета, загрузить таблицу из файла Excel, проверить заполнение печатной формы перед выводом или извлечь значения из произвольной табличной части, которую пользователь заполнил вручную. В отличие от таблицы значений, табличный документ хранит не только данные, но и оформление, поэтому работа с ним строится через координаты ячеек и области.
Основной способ перебора — цикл по номерам строк и колонок с обращением к методу Область() и чтением свойства Текст или Значение (через расшифровку для параметров). Границы документа определяют свойства ВысотаТаблицы и ШиринаТаблицы. Ниже разобраны все рабочие сценарии: от простого двойного цикла до обхода именованных областей и загрузки данных в таблицу значений.
Чем табличный документ отличается от таблицы значений
Табличный документ (объект ТабличныйДокумент) — это аналог листа электронной таблицы: у него есть строки, колонки, объединённые ячейки, форматирование и параметры. Обратиться к данным «по имени колонки», как в таблице значений, нельзя — только по координатам или по имени области. Это главное отличие, из-за которого начинающие разработчики путаются.
Таблица значений хранит типизированные данные и предназначена для вычислений, а табличный документ — для отображения и печати. Поэтому типовой приём выглядит так: перебрать табличный документ, построчно скопировать данные в таблицу значений и дальше работать уже с ней — искать, сортировать, сворачивать.
Базовый перебор всех ячеек в цикле
Универсальный вариант — вложенный цикл «Для». Внешний цикл идёт по строкам, внутренний — по колонкам. Общее число строк возвращает свойство ВысотаТаблицы, число колонок — ШиринаТаблицы. Если документ пустой, оба свойства равны нулю, и тело цикла просто не выполнится — отдельная проверка не обязательна, но полезна для понятного сообщения пользователю.
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
ТекстЯчейки = ТабДок.Область(НомерСтроки, НомерКолонки).Текст;
Если Не ПустаяСтрока(ТекстЯчейки) Тогда
// обработка значения
КонецЕсли;
КонецЦикла;
КонецЦикла;
Метод Область() с двумя числовыми параметрами возвращает одну ячейку. Свойство Текст всегда возвращает строку — то, что видно на экране. Если в ячейке записана дата или число, вы получите их отформатированное представление, и для обратного преобразования придётся учитывать формат. Это частая причина ошибок при загрузке данных.
Как получить типизированные значения, а не текст
Когда табличный документ сформирован программно через макет с параметрами, исходные значения доступны через расшифровку. У ячейки-параметра свойство Расшифровка хранит переданное значение с исходным типом. Это надёжнее, чем парсить текст.
Для документов, загруженных из файлов, типизированного значения нет — есть только текст. В этом случае применяют функцию преобразования: сначала пытаются привести строку к числу или дате, при неудаче оставляют строкой. Определить предполагаемый тип можно по номеру колонки, если структура файла известна заранее.
Функция СтрокаВЧисло(Стр)
Попытка
Возврат Число(СтрЗаменить(СтрЗаменить(Стр, " ", ""), Символ(160), ""));
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
Перебор именованных областей макета
Если документ построен по макету, удобнее работать не с «голыми» координатами, а с именованными областями. Имена областей макета сохраняются в результирующем документе, и их можно получить методом Область("ИмяОбласти"). У области есть свойства Верх, Низ, Лево, Право — координаты границ, по которым легко организовать цикл только внутри нужного блока.
ОбластьДанные = ТабДок.Область("СтрокаДанных");
Для НомерСтроки = ОбластьДанные.Верх По ОбластьДанные.Низ Цикл
Наименование = ТабДок.Область(НомерСтроки, 2).Текст;
КонецЦикла;
При многократном выводе одной и той же области макета (типовая ситуация для строк табличной части) в документе окажется много областей с одинаковым именем. Метод Область("Имя") вернёт первую найденную. Чтобы перебрать все, используют метод НайтиТекст() или отслеживают координаты вывода самостоятельно: запоминают ВысотаТаблицы до и после каждого Вывести().
При выводе строк макета в цикле сохраняйте границы каждой строки: Верх = ТабДок.ВысотаТаблицы + 1 перед Вывести(), Низ = ТабДок.ВысотаТаблицы после. Так получите точную карту документа без поиска по именам областей.
Загрузка табличного документа в таблицу значений
На практике чаще всего перебор нужен для одного: перенести данные из табличного документа (например, прочитанного из Excel методом Прочитать()) в таблицу значений. Алгоритм: первая строка документа считается шапкой, из неё формируются колонки, остальные строки перебираются и добавляются в таблицу.
- 1Прочитайте файл в табличный документ: ТабДок.Прочитать(ИмяФайла).
- 2Проверьте, что ВысотаТаблицы больше 1 — есть данные помимо шапки.
- 3Создайте таблицу значений и добавьте колонки по ячейкам первой строки.
- 4Переберите строки со второй по последнюю, заполняя новые строки таблицы.
- 5Пропускайте полностью пустые строки, чтобы не тащить мусор в дальнейшую обработку.
- 6Проверьте результат: количество строк и выборочные значения в нескольких колонках.
Имена колонок из шапки нужно нормализовать: убрать пробелы и недопустимые символы, потому что имя колонки таблицы значений должно быть допустимым идентификатором. Проще всего формировать служебные имена вида «Колонка1», «Колонка2», а соответствие с человекочитаемыми заголовками хранить отдельно.
ТЗ = Новый ТаблицаЗначений;
Для Кол = 1 По ТабДок.ШиринаТаблицы Цикл
ТЗ.Колонки.Добавить("Колонка" + Кол);
КонецЦикла;
Для Стр = 2 По ТабДок.ВысотаТаблицы Цикл
НоваяСтрока = ТЗ.Добавить();
Для Кол = 1 По ТабДок.ШиринаТаблицы Цикл
НоваяСтрока[Кол - 1] = СокрЛП(ТабДок.Область(Стр, Кол).Текст);
КонецЦикла;
КонецЦикла;
Производительность и ограничения
Обращение ТабДок.Область(Строка, Колонка) — относительно дорогая операция. На документах в сотни строк разницы не заметно, но на десятках тысяч строк перебор может занимать минуты. Ускорить процесс можно, читая сразу прямоугольные области: Область(Верх, Лево, Низ, Право) возвращает область, у которой затем перебирают вложенные ячейки, но выигрыш умеренный.
Дополнительные ограничения: объединённые ячейки возвращают текст только в левой верхней ячейке объединения, остальные будут пустыми — это нужно учитывать при разборе макетов с шапками. Скрытые строки и колонки при переборе по координатам читаются так же, как видимые, что иногда даёт неожиданные данные. Табличный документ целиком доступен только на сервере или в толстом клиенте; в тонком клиенте работа с ним ограничена.
Как проверить результат
Совпадает с числом непустых строк данных в документе
Строк больше или меньше — значит, съехала граница цикла или не отфильтрованы пустые строки
Числа распознаны как числа, итоги сходятся с источником
Числа остались строками или обрезаны — проблема с форматом и пробелами
Значения взяты из левой верхней ячейки объединения
Пустые значения там, где в документе текст виден
Частые вопросы
Как узнать, пустой ли табличный документ?
Проверьте свойства ВысотаТаблицы и ШиринаТаблицы: если оба равны нулю, документ пустой. Обратите внимание: документ, содержащий только пробелы или пустое форматирование, может иметь ненулевые размеры — тогда дополнительно проверяйте текст ячеек.
Можно ли перебрать табличный документ через «Для Каждого»?
Нет, табличный документ не является коллекцией — прямой итератор для него недоступен. Перебор выполняется только по координатам через цикл «Для» либо через поиск методом НайтиТекст().
Как найти ячейку с нужным значением без полного перебора?
Используйте метод НайтиТекст(СтрокаПоиска, ОбластьПоиска, ИскатьПоСтрокам, ЦелаяЯчейка) — он возвращает область первой найденной ячейки. Повторный вызов с указанием области после найденной позиции позволяет найти следующие вхождения.
Почему Область(Строка, Колонка) возвращает пустой текст, хотя в документе значение есть?
Чаще всего ячейка входит в объединённую область, а текст хранится в её левой верхней ячейке. Также проверьте, не смещены ли координаты: нумерация начинается с единицы, а шапка и итоговые строки сдвигают расположение данных.
Как перебрать табличный документ на управляемой форме?
Реквизит формы типа ТабличныйДокумент доступен в серверных процедурах. В клиентском контексте чтение ячеек ограничено, поэтому перебор выносят в серверную процедуру «&НаСервере» и передают туда данные или имя реквизита.
Что быстрее: перебор табличного документа или чтение Excel напрямую?
Для небольших файлов разница незаметна, и проще использовать ТабличныйДокумент.Прочитать(). Для больших файлов перебор через Область() становится узким местом, и прямое чтение файла потоковыми средствами обычно быстрее, хотя требует больше кода.
Что важно запомнить
Табличный документ перебирают вложенным циклом по строкам и колонкам в пределах ВысотаТаблицы и ШиринаТаблицы, читая ячейки через Область(). Свойство Текст возвращает строку — для чисел и дат нужно преобразование. Для дальнейшей обработки данные удобно переносить в таблицу значений, а на больших документах заранее оценивать производительность.