&НаКлиенте
Процедура ВыполнитьЗаполнение(Команда)
ЗаполнитьДанныеНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДанныеНаСервере()
// 1. Собираем уникальные значения для поиска
Артикулы = Новый СписокЗначений;
ДопЗначения = Новый СписокЗначений;
Для Каждого СтрокаТЧ из Объект.Товары Цикл
Если ЗначениеЗаполнено(СтрокаТЧ.Артикул) Тогда
Если Артикулы.НайтиПоЗначению(СтрокаТЧ.Артикул) = Неопределено Тогда
Артикулы.Добавить(СтрокаТЧ.Артикул);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаТЧ.ДопРеквизит) Тогда
Если ДопЗначения.НайтиПоЗначению(СтрокаТЧ.ДопРеквизит) = Неопределено Тогда
ДопЗначения.Добавить(СтрокаТЧ.ДопРеквизит);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Артикулы.Количество() = 0 И ДопЗначения.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Заполните хотя бы одну строку Артикулом или Доп. реквизитом");
Возврат;
КонецЕсли;
// 2. Формируем запрос
Запрос = Новый Запрос;
// В УТ 11 рекомендуется явно указывать Свойство доп. реквизита,
// иначе поиск будет идти по ВСЕМ доп. реквизитам, что может дать дубли.
// Если нужно искать строго по одному ДР, добавьте параметр &СвойствоДР
Запрос.Текст = "
|ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.СтавкаНДС КАК СтавкаНДС,
| Номенклатура.ДополнительныеРеквизиты.(
| Значение КАК ЗначениеДР
| ) КАК ДополнительныеРеквизиты
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул В(&Артикулы)
| ИЛИ Номенклатура.ДополнительныеРеквизиты.Значение В(&ДопЗначения)
|";
Запрос.УстановитьПараметр("Артикулы", Артикулы);
Запрос.УстановитьПараметр("ДопЗначения", ДопЗначения);
Выборка = Запрос.Выполнить().Выбрать();
// 3. Индексируем результаты для быстрого сопоставления O(1)
КартаПоАртикулу = Новый Соответствие();
КартаПоДопРеквизиту = Новый Соответствие();
Пока Выборка.Следующий() Цикл
// Индекс по артикулу
Если ЗначениеЗаполнено(Выборка.Артикул) Тогда
КартаПоАртикулу.Вставить(Выборка.Артикул, Выборка);
КонецЕсли;
// Индекс по доп. реквизиту
Для Каждого ДР из Выборка.ДополнительныеРеквизиты Цикл
Если ЗначениеЗаполнено(ДР.ЗначениеДР) И Не КартаПоДопРеквизиту.Содержит(ДР.ЗначениеДР) Тогда
КартаПоДопРеквизиту.Вставить(ДР.ЗначениеДР, Выборка);
КонецЕсли;
КонецЦикла;
КонецЦикла;
// 4. Заполняем табличную часть
Для Каждого СтрокаТЧ из Объект.Товары Цикл
Найдено = Неопределено;
// Приоритет: Артикул -> Доп. реквизит
Если ЗначениеЗаполнено(СтрокаТЧ.Артикул) Тогда
Найдено = КартаПоАртикулу.Получить(СтрокаТЧ.Артикул);
КонецЕсли;
Если Найдено = Неопределено И ЗначениеЗаполнено(СтрокаТЧ.ДопРеквизит) Тогда
Найдено = КартаПоДопРеквизиту.Получить(СтрокаТЧ.ДопРеквизит);
КонецЕсли;
Если Найдено <> Неопределено Тогда
СтрокаТЧ.Наименование = Найдено.Наименование;
СтрокаТЧ.СтавкаНДС = Найдено.СтавкаНДС;
// Опционально: можно подтянуть Артикул/ДР из справочника, если они были пустые
Иначе
СтрокаТЧ.Наименование = "[Не найдено] " + СтрокаТЧ.Наименование;
КонецЕсли;
КонецЦикла;
КонецПроцедуры