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