Загрузка данных


&НаКлиенте
Процедура ВыполнитьЗаполнение(Команда)
	ЗаполнитьДанныеНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДанныеНаСервере()
	// 1. Собираем уникальные значения для поиска
	Артикулы = Новый СписокЗначений;
	ДопЗначения = Новый СписокЗначений;

	Для Каждого СтрокаТЧ из Объект.Товары Цикл
		Если ЗначениеЗаполнено(СтрокаТЧ.Артикул) Тогда
			Если Артикулы.НайтиПоЗначению(СтрокаТЧ.Артикул) = Неопределено Тогда
				Артикулы.Добавить(СтрокаТЧ.Артикул);
			КонецЕсли;
		КонецЕсли;
		Если ЗначениеЗаполнено(СтрокаТЧ.ДопРеквизит) Тогда
			Если ДопЗначения.НайтиПоЗначению(СтрокаТЧ.ДопРеквизит) = Неопределено Тогда
				ДопЗначения.Добавить(СтрокаТЧ.ДопРеквизит);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

	Если Артикулы.Количество() = 0 И ДопЗначения.Количество() = 0 Тогда
		ПоказатьПредупреждение(, "Заполните хотя бы одну строку Артикулом или Доп. реквизитом");
		Возврат;
	КонецЕсли;

	// 2. Формируем запрос
	Запрос = Новый Запрос;
	// В УТ 11 рекомендуется явно указывать Свойство доп. реквизита, 
	// иначе поиск будет идти по ВСЕМ доп. реквизитам, что может дать дубли.
	// Если нужно искать строго по одному ДР, добавьте параметр &СвойствоДР
	Запрос.Текст = "
		|ВЫБРАТЬ
		|	Номенклатура.Ссылка КАК Ссылка,
		|	Номенклатура.Наименование КАК Наименование,
		|	Номенклатура.Артикул КАК Артикул,
		|	Номенклатура.СтавкаНДС КАК СтавкаНДС,
		|	Номенклатура.ДополнительныеРеквизиты.(
		|		Значение КАК ЗначениеДР
		|	) КАК ДополнительныеРеквизиты
		|ИЗ
		|	Справочник.Номенклатура КАК Номенклатура
		|ГДЕ
		|	Номенклатура.Артикул В(&Артикулы)
		|	ИЛИ Номенклатура.ДополнительныеРеквизиты.Значение В(&ДопЗначения)
	|";
	Запрос.УстановитьПараметр("Артикулы", Артикулы);
	Запрос.УстановитьПараметр("ДопЗначения", ДопЗначения);

	Выборка = Запрос.Выполнить().Выбрать();

	// 3. Индексируем результаты для быстрого сопоставления O(1)
	КартаПоАртикулу = Новый Соответствие();
	КартаПоДопРеквизиту = Новый Соответствие();

	Пока Выборка.Следующий() Цикл
		// Индекс по артикулу
		Если ЗначениеЗаполнено(Выборка.Артикул) Тогда
			КартаПоАртикулу.Вставить(Выборка.Артикул, Выборка);
		КонецЕсли;
		
		// Индекс по доп. реквизиту
		Для Каждого ДР из Выборка.ДополнительныеРеквизиты Цикл
			Если ЗначениеЗаполнено(ДР.ЗначениеДР) И Не КартаПоДопРеквизиту.Содержит(ДР.ЗначениеДР) Тогда
				КартаПоДопРеквизиту.Вставить(ДР.ЗначениеДР, Выборка);
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;

	// 4. Заполняем табличную часть
	Для Каждого СтрокаТЧ из Объект.Товары Цикл
		Найдено = Неопределено;
		
		// Приоритет: Артикул -> Доп. реквизит
		Если ЗначениеЗаполнено(СтрокаТЧ.Артикул) Тогда
			Найдено = КартаПоАртикулу.Получить(СтрокаТЧ.Артикул);
		КонецЕсли;
		Если Найдено = Неопределено И ЗначениеЗаполнено(СтрокаТЧ.ДопРеквизит) Тогда
			Найдено = КартаПоДопРеквизиту.Получить(СтрокаТЧ.ДопРеквизит);
		КонецЕсли;

		Если Найдено <> Неопределено Тогда
			СтрокаТЧ.Наименование = Найдено.Наименование;
			СтрокаТЧ.СтавкаНДС = Найдено.СтавкаНДС;
			// Опционально: можно подтянуть Артикул/ДР из справочника, если они были пустые
		Иначе
			СтрокаТЧ.Наименование = "[Не найдено] " + СтрокаТЧ.Наименование;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры