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