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