Работа с табличными данными является фундаментальной частью разработки прикладных решений на платформе 1С:Предприятие 8. Одной из самых востребованных операций является фильтрация информации, хранящейся в оперативной памяти. В отличие от работы с базами данных SQL, где отбор выполняется на стороне сервера СУБД, в коде 1С разработчик часто сталкивается с необходимостью обрабатывать уже загруженные наборы данных.

Объект ТаблицаЗначений представляет собой универсальный контейнер для хранения строк и колонок, не привязанный напрямую к метаданным конфигурации. Эффективный отбор строк в этом объекте критически важен для быстродействия программы, особенно при обработке больших объемов данных во временных хранилищах или перед выводом на экран пользователя. Неправильный выбор метода фильтрации может привести к существенному замедлению работы приложения.

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

Использование метода СоздатьОтбор для фильтрации

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

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

⚠️ Внимание: Метод СоздатьОтбор создает полную копию отфильтрованных строк в памяти. Если исходная таблица содержит миллионы записей, а отбор возвращает 90% из них, это может привести к резкому скачку потребления оперативной памяти сервером 1С.

Рассмотрим пример кода, где мы фильтруем список номенклатуры по признаку "ЭтоГруппа". Мы используем перечисление ВидСравнения для явного указания типа операции, что делает код более читаемым и защищенным от ошибок при рефакторинге.

ОтфильтрованнаяТаблица = ИсходнаяТаблица.СоздатьОтбор(

"ЭтоГруппа",

ВидСравнения.Равно,

Ложь

);

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

💡

При фильтрации по строковым значениям всегда приводите данные к единому регистру или используйте оператор "Подобно", если точное совпадение не критично, чтобы избежать ошибок из-за лишних пробелов.

Применение структуры отбора для сложных условий

Когда логика фильтрации становится нетривиальной, использование множества вызовов метода СоздатьОтбор может сделать код громоздким. В таких случаях на помощь приходит объект Структура. Передача структуры в качестве параметра отбора позволяет задать набор пар "Ключ-Значение", где ключом выступает имя колонки, а значением — критерий поиска.

Главное преимущество такого подхода заключается в том, что все условия, заданные в структуре, объединяются логическим оператором "И". Это идеально подходит для случаев, когда пользователю необходимо найти записи, соответствующие сразу нескольким критериям, например, конкретному контрагенту и определенной дате документа.

  • 🔹 Простота синтаксиса: код становится компактнее и легче читается, так как все условия собраны в одном месте.
  • 🔹 Динамичность: структуру можно наполнять программно в цикле, добавляя условия только если они были заданы пользователем в форме.
  • 🔹 Типобезопасность: платформа автоматически проверяет соответствие типов данных в колонке и передаваемом значении.

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

ОтборСтруктура = Новый Структура;

ОтборСтруктура.Вставить("Контрагент", ВыбранныйКонтрагент);

ОтборСтруктура.Вставить("Дата", НачальнаяДата);

Результат = ТаблицаДокументов.СоздатьОтбор(ОтборСтруктура);

Стоит отметить, что структура не поддерживает сложные логические операции, такие как "ИЛИ" или "НЕ", внутри себя. Для реализации таких сценариев придется комбинировать несколько отборов или переходить к использованию языка запросов. Тем не менее, для большинства типовых задач фильтрации по точному совпадению этот метод является оптимальным.

📊 Какой метод фильтрации вы используете чаще всего?
Метод СоздатьОтбор
Структура отбора
Язык запросов
Ручной цикл с Если

Фильтрация с помощью языка запросов

Для сложных аналитических выборок или работы с очень большими объемами данных наиболее мощным инструментом остается язык запросов 1С. Вы можете поместить вашу ТаблицуЗначений во временную таблицу и выполнить к ней полноценный SQL-подобный запрос. Это открывает доступ ко всему арсеналу функций языка: группировкам, соединениям и сложным условиям.

Основной сценарий использования выглядит следующим образом: сначала данные из таблицы значений загружаются во временное хранилище с помощью метода Загрузить. Затем формируется текст запроса, в котором эта временная таблица выступает в роли источника данных. В секции ГДЕ вы прописываете любую необходимую логику фильтрации.

⚠️ Внимание: При использовании запросов к временным таблицам убедитесь, что имена полей в тексте запроса точно совпадают с именами колонок в Таблице Значений. Регистр букв имеет значение, если имена чувствительны к регистру в вашей конфигурации.

Преимущество данного подхода заключается в оптимизации выполнения. Движок запросов 1С способен построить эффективный план выполнения, особенно если временная таблица велика. Кроме того, вы можете сразу получить данные в нужном порядке, используя секцию УПОРЯДОЧИТЬ ПО, что избавит от необходимости дополнительной сортировки в коде.

Ниже приведен пример кода, демонстрирующий создание запроса к временной таблице. Мы используем параметр запроса для передачи значения фильтра, что защищает от SQL-инъекций (хотя в 1С это менее актуально, это хорошая практика) и позволяет перекомпоновывать запрос без изменения его текста.

ВТ = Запрос.МенеджерВременныхТаблиц.Загрузить(ИсходнаяТаблица);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ВТ.Номенклатура,

| ВТ.Количество

|ИЗ

| &ТаблицаКакВТ КАК ВТ

|ГДЕ

| ВТ.Количество > &МинКоличество";

Запрос.УстановитьПараметр("ТаблицаКакВТ", ВТ);

Запрос.УстановитьПараметр("МинКоличество", 100);

Результат = Запрос.Выполнить().Выгрузить();

Когда запрос быстрее метода СоздатьОтбор?

Запрос становится предпочтительнее, когда объем данных превышает десятки тысяч строк или когда требуется сложная логика фильтрации с использованием функций (например, ПОДОБНО, ЕСТЬNULL, работа с датами).

Ручная фильтрация в цикле и производительность

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

Суть метода заключается в создании новой пустой таблицы значений с той же структурой, что и исходная. Затем вы проходите в цикле по строкам источника, проверяете условие с помощью оператора Если и, если условие истинно, добавляете строку в новую таблицу. Этот подход дает полный контроль над процессом, но имеет свои недостатки.

Главный минус ручной фильтрации — низкая производительность на больших массивах данных. Интерпретатор 1С выполняет код цикла пошагово, что значительно медленнее, чем оптимизированные внутренние методы платформы или движок запросов. Поэтому использовать этот способ рекомендуется только для небольших таблиц или когда другие методы неприменимы.

Метод Производительность Гибкость Сложность кода
СоздатьОтбор Высокая Средняя Низкая
Структура Высокая Низкая (только И) Низкая
Язык запросов Очень высокая Максимальная Средняя
Ручной цикл Низкая Максимальная Высокая

При реализации ручного отбора важно правильно скопировать структуру колонок. Для этого удобно использовать метод Колонки.Скопировать, чтобы новая таблица полностью соответствовала старой по составу и типам полей. Ошибка в типах может привести к исключительной ситуации при попытке записи данных.

💡

Ручной цикл следует использовать как крайнюю меру, когда встроенные средства 1С не могут реализовать требуемую бизнес-логику фильтрации.

Особенности работы с типами данных при отборе

Одной из частых причин ошибок при выполнении отбора является несоответствие типов данных. Платформа 1С:Предприятие строго типизирована, и попытка сравнить строку с числом или дату с булевым значением приведет к исключению. Особенно внимательно нужно относиться к полям, имеющим тип Неопределено (Null).

Если в колонке таблицы значений могут храниться пустые значения, стандартное сравнение на равенство может не сработать ожидаемым образом. В языке запросов для проверки на пустое значение используется конструкция ЕСТЬNULL или сравнение с NULL. В методе СоздатьОтбор необходимо передавать специальное значение Неопределено.

Также стоит учитывать особенности сравнения строк. По умолчанию сравнение может быть чувствительным к регистру в зависимости от настроек базы данных и используемого метода. Для обеспечения стабильности работы рекомендуется использовать функции приведения регистра, такие как РегСтр или СтрНиж, особенно если данные вводятся пользователем вручную.

⚠️ Внимание: При работе с датами всегда учитывайте время. Дата "01.01.2026" в 1С — это "01.01.2026 00:00:00". Если в таблице есть время, отбор по дате без учета времени может не найти нужные строки. Используйте функцию НачалоДня для нормализации.

Для числовых полей важно следить за точностью. Сравнение чисел с плавающей точкой на строгое равенство часто приводит к ошибкам из-за особенностей представления вещественных чисел в компьютере. Лучше использовать проверку на попадание в диапазон с небольшой погрешностью.

Оптимизация и лучшие практики

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

Если вам нужно просто получить количество строк, удовлетворяющих условию, не создавайте новую таблицу. Используйте метод НайтиСтроки, который возвращает массив индексов или ссылок на строки. Это позволяет избежать дублирования данных в памяти и работает значительно быстрее.

  • 🚀 Индексация: хоть Таблица Значений не имеет индексов в классическом понимании СУБД, порядок строк может влиять на скорость поиска в некоторых сценариях.
  • 🚀 Избегание лишних копий: если данные не нужно изменять, передавайте ссылку на таблицу или используйте только чтение.
  • 🚀 Очистка ресурсов: своевременно обнуляйте ссылки на большие временные таблицы, чтобы сборщик мусора мог освободить память.

В современных версиях платформы механизмы работы с памятью стали умнее, но принцип "меньше операций — выше скорость" остается неизменным. Профилируйте ваш код с помощью встроенных инструментов производительности, чтобы находить узкие места именно в вашей конфигурации.

☑️ Чек-лист оптимизации отбора

Выполнено: 0 / 5
В чем разница между методом НайтиСтроки и СоздатьОтбор?

Метод НайтиСтроки возвращает массив ссылок на строки исходной таблицы, не создавая копию данных. Это экономит память, но вы работаете с исходными данными. СоздатьОтбор создает новую независимую таблицу с копией строк, что безопасно для изменений, но требует больше ресурсов.

Можно ли использовать отбор по нескольким условиям "ИЛИ" в структуре?

Нет, структура поддерживает только логику "И". Для реализации условия "ИЛИ" необходимо использовать язык запросов или выполнять несколько отборов отдельно, а затем объединять результаты.

Как отфильтровать таблицу значений по частичному совпадению строки?

В методе СоздатьОтбор используйте вид сравнения ВидСравнения.Подобно и значение с символами подстановки (например, "Товар"). В запросах используется оператор ПОДОБНО.

Что делать, если отбор возвращает пустую таблицу?

Проверьте соответствие типов данных, наличие значений в колонках (не являются ли они Неопределено), а также логику условий. Убедитесь, что имена полей указаны без опечаток и с правильным регистром.

Влияет ли отбор на исходную таблицу значений?

Нет, стандартные методы отбора (СоздатьОтбор, запросы) всегда работают с копией данных или возвращают новый набор. Исходная таблица остается неизменной, если вы явно не модифицируете её в цикле.