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