Часто в процессе разработки на платформе 1С мы сталкиваемся с задачей фильтрации данных. Например, у нас есть ТаблицаЗначений, и нам нужно найти в ней все строки, которые соответствуют нескольким значениям одного и того же поля. Использование стандартного объекта Структура в методе НайтиСтроки() в таких случаях часто заводит в тупик, так как Структура не допускает дублирования ключей.
Давайте разберемся, почему так происходит и какие существуют способы элегантно решить эту задачу, сделав код производительным и читаемым (в этом поможет Консоль кода + ИИ-помощник).
Когда вы создаете объект Структура, система ожидает пары «ключ-значение». Ключ в структуре — это уникальный идентификатор. Если вы попытаетесь вставить в структуру два значения с одним и тем же ключом, второе просто перезапишет первое. Именно поэтому классический подход с НайтиСтроки(Новая Структура("Статья", Значение1)) работает для одного условия, но становится бесполезным, когда нужно выбрать список элементов.
Самый профессиональный и эффективный способ работы с выборками в 1С — это использование Запрос. Вместо того чтобы перебирать таблицу значений в цикле, мы передаем всю таблицу в запрос и используем мощный механизм оператора В.
Давайте рассмотрим, как это реализовать по шагам:
ГДЕ СтатьяОборотов В (&МассивСтатей).Посмотрим на пример кода:
// Создаем массив нужных нам значений
МассивСтатей = Новый Массив;
МассивСтатей.Добавить(Справочники.бит_СтатьиОборотов.НайтиПоКоду("TS-000566"));
МассивСтатей.Добавить(Справочники.бит_СтатьиОборотов.НайтиПоКоду("TS-000567"));
// Настраиваем запрос
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.Сумма КАК Сумма
|ИЗ
| &ТаблицаЗначений КАК ТЗ
|ГДЕ
| ТЗ.СтатьяОборотов В (&МассивСтатей)";
Запрос.УстановитьПараметр("ТаблицаЗначений", ТабЗнач);
Запрос.УстановитьПараметр("МассивСтатей", МассивСтатей);
Результат = Запрос.Выполнить().Выбрать();
Преимущество этого метода очевидно: запрос выполняет фильтрацию на уровне платформы, что значительно быстрее ручного перебора. Кроме того, мы сразу можем обработать NULL значения, используя функцию ЕСТЬNULL, что избавит нас от лишних проверок внутри цикла.
Если по каким-то архитектурным причинам вы не хотите или не можете использовать запрос (например, таблица очень маленькая, или мы находимся в специфическом контексте), можно применить метод последовательного поиска.
Суть метода заключается в том, чтобы выполнить поиск для каждого значения отдельно и объединить результаты. Рассмотрим пример:
МассивИтог = Новый Массив;
СписокЗначенийСтатей = Новый Массив;
// Добавляем нужные элементы в список для поиска
СписокЗначенийСтатей.Добавить(Справочники.бит_СтатьиОборотов.НайтиПоКоду("TS-000566"));
СписокЗначенийСтатей.Добавить(Справочники.бит_СтатьиОборотов.НайтиПоКоду("TS-000567"));
Для Каждого Статья Из СписокЗначенийСтатей Цикл
ПараметрыОтбора = Новый Структура("СтатьяОборотов", Статья);
НайденныеСтроки = ТабЗнач.НайтиСтроки(ПараметрыОтбора);
Для Каждого Стр Из НайденныеСтроки Цикл
МассивИтог.Добавить(Стр);
КонецЦикла;
КонецЦикла;
Этот метод подходит для простых задач, но помните: при большом количестве данных он будет работать медленнее, чем запрос, так как мы совершаем несколько проходов по одной и той же таблице (альтернатива — Функция отбора элементов коллекции быстрым условием).
При работе с данными всегда помните о производительности. Если вы используете метод НайтиСтроки() внутри цикла по большой таблице, это может привести к замедлению работы всей обработки или отчета. Запрос всегда будет предпочтительнее, так как он оптимизирован для пакетной обработки данных.
Также важно правильно обрабатывать пустые значения. В 1С значения, которые не были инициализированы, могут принимать значение NULL или Неопределено. Всегда используйте конструкцию ?() или функцию ЕСТЬNULL(), чтобы ваша программа не «падала» при попытке выполнить арифметические операции над «пустыми» переменными.
Используя эти методы, вы сможете сделать код более чистым, поддерживаемым и быстрым. Рекомендуем всегда отдавать предпочтение запросам при работе с отборами данных.