Это процедура начинается с вызова функции, в которой помещаются во временные таблицы все ключевые значения, в частности Номенклатуры, ХарактеристикаНоменклатуры, Склады, Контрагенты, Свойства и др.
МВТ=Получить_ВТ_НоменклатураДляВыгрузки_ВТ_ХарактеристикиНоменклатурыДляВыгрузки_ВТСклады(СтруктураПараметров);
Далее процедура состоит из нескольких десятков процедур, отвечающих за заполнение соответствующих регистров. Запросом получаются значения, которые должны быть на сайте и сравниваются с последними значениями в соответствующем регистре. Запись происходит только по записям с расхождениями.
В частности для заполнения РегистраСведений._СайтКлассификатор вызывается процедура
ЗаполнитьРС_СайтКлассификатор(СтруктураПараметров,МВТ,Справочники._СайтКлассификаторы.ГруппыНоменклатуры);
Процедура ЗаполнитьРС_СайтКлассификатор(СтруктураПараметров,МВТ,Классификатор)
Если СтруктураПараметров.Свойство("ClassifierFULL") Тогда
ClassifierFULL=Истина;
КонецЕсли;
Запрос=Новый Запрос;
Запрос.МенеджерВременныхТаблиц=МВТ;
Запрос.Текст="ВЫБРАТЬ РАЗЛИЧНЫЕ
| ВТ_НоменклатураДляВыгрузки.НоменклатураСсылка.Родитель КАК ГруппаКлассификатора,
| ВТ_НоменклатураДляВыгрузки.Сайт КАК Сайт
|ИЗ
| ВТ_НоменклатураДляВыгрузки КАК ВТ_НоменклатураДляВыгрузки
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| _СайтСписокНоменклатур.ВеткаКлассификатора,
| _СайтСписокНоменклатур.Сайт
|ИЗ
| Справочник._СайтСписокНоменклатур КАК _СайтСписокНоменклатур
|ГДЕ
| _СайтСписокНоменклатур.ПометкаУдаления = ЛОЖЬ
| И НЕ _СайтСписокНоменклатур.ВеткаКлассификатора = ЗНАЧЕНИЕ(справочник.номенклатура.пустаяссылка)";
ТЗГруппыКлассификатора=Новый ТаблицаЗначений;
ТЗГруппыКлассификатора.Колонки.Добавить("ГруппаКлассификатора",Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗГруппыКлассификатора.Колонки.Добавить("Сайт",Новый ОписаниеТипов("СправочникСсылка._Сайт"));
ТЗГруппыКлассификатора.Колонки.Добавить("УровеньГруппы",Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(2,0,ДопустимыйЗнак.Неотрицательный)));
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
РекурсивноЗаполнитьГруппы(ВыборкаДетальныеЗаписи.ГруппаКлассификатора,ТЗГруппыКлассификатора,1,ВыборкаДетальныеЗаписи.Сайт);
КонецЦикла;
Запрос=Новый Запрос;
Запрос.МенеджерВременныхТаблиц=МВТ;
Запрос.УстановитьПараметр("ТЗГруппыКлассификатора",ТЗГруппыКлассификатора);
Запрос.УстановитьПараметр("Классификатор",Классификатор);
Запрос.УстановитьПараметр("ClassifierFULL",ClassifierFULL);
Запрос.Текст="ВЫБРАТЬ
| ВЫРАЗИТЬ(ТЗГруппыКлассификатора.ГруппаКлассификатора КАК Справочник.Номенклатура) КАК ГруппаКлассификатора,
| ТЗГруппыКлассификатора.Сайт КАК Сайт,
| ТЗГруппыКлассификатора.УровеньГруппы КАК УровеньГруппы
|ПОМЕСТИТЬ ВТ_ГруппКлассификатораНеСвернуто
|ИЗ
| &ТЗГруппыКлассификатора КАК ТЗГруппыКлассификатора
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_ГруппКлассификатораНеСвернуто.ГруппаКлассификатора КАК ГруппаКлассификатора,
| ВТ_ГруппКлассификатораНеСвернуто.Сайт КАК Сайт,
| МАКСИМУМ(ВТ_ГруппКлассификатораНеСвернуто.УровеньГруппы) КАК УровеньГруппы
|ПОМЕСТИТЬ ВТ_ГруппКлассификатора
|ИЗ
| ВТ_ГруппКлассификатораНеСвернуто КАК ВТ_ГруппКлассификатораНеСвернуто
|
|СГРУППИРОВАТЬ ПО
| ВТ_ГруппКлассификатораНеСвернуто.ГруппаКлассификатора,
| ВТ_ГруппКлассификатораНеСвернуто.Сайт
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| &Классификатор КАК Classifier,
| ВТ_ГруппКлассификатора.Сайт КАК Сайт,
| ВТ_ГруппКлассификатора.ГруппаКлассификатора.Наименование КАК name,
| ВЫБОР
| КОГДА ВТ_ГруппКлассификатора.ГруппаКлассификатора.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
| ТОГДА ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
| КОГДА ВТ_ГруппКлассификатора.ГруппаКлассификатора.Родитель._СайтЭтоКорневаяПапка
| ТОГДА ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
| ИНАЧЕ ВТ_ГруппКлассификатора.ГруппаКлассификатора.Родитель
| КОНЕЦ КАК ID_1C_parent,
| ВТ_ГруппКлассификатора.ГруппаКлассификатора КАК ID_1C,
| ВТ_ГруппКлассификатора.УровеньГруппы КАК УровеньГруппы,
| 1 КАК Источник
|ПОМЕСТИТЬ СравнениеГруппКлассификатора
|ИЗ
| ВТ_ГруппКлассификатора КАК ВТ_ГруппКлассификатора
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| РС_СайтКлассификатор.Classifier,
| РС_СайтКлассификатор.Сайт,
| РС_СайтКлассификатор.name,
| РС_СайтКлассификатор.ID_1C_parent,
| РС_СайтКлассификатор.ID_1C,
| 0,
| -1
|ИЗ
| РегистрСведений._СайтКлассификатор.СрезПоследних КАК РС_СайтКлассификатор
|ГДЕ
| РС_СайтКлассификатор.Classifier = &Классификатор
| И РС_СайтКлассификатор.Удален = ЛОЖЬ
| И &ClassifierFULL = ЛОЖЬ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СравнениеГруппКлассификатора.Classifier КАК Classifier,
| СравнениеГруппКлассификатора.Сайт КАК Сайт,
| СравнениеГруппКлассификатора.name КАК name,
| СравнениеГруппКлассификатора.ID_1C_parent КАК ID_1C_parent,
| СравнениеГруппКлассификатора.ID_1C КАК ID_1C,
| СУММА(СравнениеГруппКлассификатора.Источник) КАК Источник,
| МАКСИМУМ(СравнениеГруппКлассификатора.УровеньГруппы) КАК УровеньГруппы,
| &ClassifierFULL КАК FULL
|ИЗ
| СравнениеГруппКлассификатора КАК СравнениеГруппКлассификатора
|
|СГРУППИРОВАТЬ ПО
| СравнениеГруппКлассификатора.Classifier,
| СравнениеГруппКлассификатора.name,
| СравнениеГруппКлассификатора.ID_1C_parent,
| СравнениеГруппКлассификатора.ID_1C,
| СравнениеГруппКлассификатора.Сайт,
| СравнениеГруппКлассификатора.ID_1C.Родитель
|
|ИМЕЮЩИЕ
| СУММА(СравнениеГруппКлассификатора.Источник) > 0
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| СравнениеГруппКлассификатора.Classifier,
| СравнениеГруппКлассификатора.Сайт,
| МАКСИМУМ(СравнениеГруппКлассификатора.name),
| МАКСИМУМ(СравнениеГруппКлассификатора.ID_1C_parent),
| СравнениеГруппКлассификатора.ID_1C,
| СУММА(СравнениеГруппКлассификатора.Источник),
| МАКСИМУМ(СравнениеГруппКлассификатора.УровеньГруппы),
| &ClassifierFULL
|ИЗ
| СравнениеГруппКлассификатора КАК СравнениеГруппКлассификатора
|
|СГРУППИРОВАТЬ ПО
| СравнениеГруппКлассификатора.Classifier,
| СравнениеГруппКлассификатора.ID_1C,
| СравнениеГруппКлассификатора.Сайт
|
|ИМЕЮЩИЕ
| СУММА(СравнениеГруппКлассификатора.Источник) < 0
|;
|
|";
ТекущаяДатаЗапроса=ТекущаяУниверсальнаяДата();
ИмяРегистра="_СайтКлассификатор";
Если ClassifierFULL Тогда
ЗапросДляОчисткиРегистра=Новый Запрос;
ЗапросДляОчисткиРегистра.МенеджерВременныхТаблиц=МВТ;
ЗапросДляОчисткиРегистра.Текст="ВЫБРАТЬ РАЗЛИЧНЫЕ
| ВТ_НоменклатураДляВыгрузки.Сайт
|ИЗ
| ВТ_НоменклатураДляВыгрузки как ВТ_НоменклатураДляВыгрузки ";
ВыборкаДляОчистки=ЗапросДляОчисткиРегистра.Выполнить().Выбрать();
Пока ВыборкаДляОчистки.Следующий() Цикл
СтруктураЗначенийИзмерений=Новый Структура;
СтруктураЗначенийИзмерений.Вставить("Сайт",ВыборкаДляОчистки.Сайт);
ОчиститьНезависимыйРСПоКлючам(Метаданные.РегистрыСведений._СайтКлассификатор,СтруктураЗначенийИзмерений);
КонецЦикла;
КонецЕсли;
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Количество()>0 Тогда
ЗаписатьВРегистр(ИмяРегистра,ВыборкаДетальныеЗаписи,ТекущаяДатаЗапроса);
КонецЕсли;
КонецПроцедуры
Прокомментирую последний запрос.
Когда есть запись в РегистрСведений._СайтКлассификатор.СрезПоследних, то колонка "Источник"=-1. Это означает, что ранее была уже подготовлена запись для передачи на сайт и возможно уже передана. Обращаю внимание, что в условиях где убираются записи для удаления (Удален=ЛОЖЬ).
Когда есть запись в ВТ_ГруппКлассификатораНеСвернуто, то колонка "Источник"=1. Это означает, что на момент запуска обмена в БД соответствующая строка должна быть передана на сайт.
Если обе записи присутствует и Сумма по полю Источник=0, то никаких действий не происходит
Если Сумма = 1, то означает, что нужно создать запись для передачи на сайт.
Если Сумма = -1, то означает, что нужно удалить запись для передачи на сайт, в РегистрСведений._СайтКлассификатор для такого случая ресурс Удален дб равен Истина.
Результатом выполнения процедура являются записи в периодических регистрах со статусом "Новый". В период записи заносится ТекущаяДата()
Вот и долгожданный результат: тк идет сравнение с ранее поставленных к обмену данных, то никаких лишний действий не произойдет, если в группах классификатора поменялся какой-то реквизит, который не участвует в обмене. Перезапись без изменений тоже не вызовет никаких событий