v8: Запись таблицы значений в регистр сведений с автоматическими отборами Ключевые слова: регистр сведений,набор записей,запись,измерения
Отборы - это структура, которая указывает, по каким измерениям делать отборы при записи таблицы значений в регистр сведений.
ТЗ - таблица, которая записывается в регистр сведений.
Если измерение есть в Отборы и в ТЗ, то значение измерения берется из ТЗ, это дает бонусы:
1. Можно в Отборы указать значение измерения, общего для всех строк.
Также можно использовать какую-либо колонку ТЗ (имя колонки задается в КолонкаОчистки), непустое значение в которой указывает, что строка используется только для очистки регистра сведений по содержащимся в строке измерениям.
Это позволяет использовать одну и ту же ТЗ для заполнения данных и очистки регистра сведений по тем измерениям, где данных нет.
Например, если мы заполняем РС по подразделениям, можно сначала получить данные для занесения в регистр и занести их в ТЗ, а затем добавить в ТЗ по одной строке на каждое подразделение.
Таким образом будет гарантировано, что по тем подразделениям, по которым не было получено данных, но были старые данные, произойдет очистка значений.
//Позволяет записать таблицу значений в регистр сведений, перезаписывая старые записи
//Отборы - показывает, в разрезе каких измерений очищать записи
//КолонкаОчистки - указывает на колонку (если она есть), если в ней содержится значение, не равное Неопределено,
// то эта строка ТЗ не переносится в регистр сведений. Т.е. такие строки используются только для очистки значений.
Функция обЗаписатьРегистрСведений(РСМенеджер, ТЗ, Отборы, КолонкаОчистки=Неопределено) Экспорт
Если КолонкаОчистки=Неопределено Тогда
//Сразу записываем всю таблицу без очистки
обЗаписатьРегистрСведенийСлуж(РСМенеджер, ТЗ, Отборы, ложь);
Иначе
//Сначала очищаем
ТЗ1=ТЗ.Скопировать();
ТЗ2=ТЗ.Скопировать();
ВсегоСтрок=ТЗ1.Количество();
Для Инд=1 По ВсегоСтрок Цикл
Стр=ТЗ1[ВсегоСтрок-Инд];
Если Стр[КолонкаОчистки]=Неопределено Тогда
ТЗ1.Удалить(Стр);
КонецЕсли;
КонецЦикла;
обЗаписатьРегистрСведенийСлуж(РСМенеджер, ТЗ1, Отборы, истина);
//Потом записываем
ТЗ1=ТЗ.Скопировать();
ВсегоСтрок=ТЗ1.Количество();
Для Инд=1 По ВсегоСтрок Цикл
Стр=ТЗ1[ВсегоСтрок-Инд];
Если Стр[КолонкаОчистки]<>Неопределено Тогда
ТЗ1.Удалить(Стр);
КонецЕсли;
КонецЦикла;
обЗаписатьРегистрСведенийСлуж(РСМенеджер, ТЗ1, Отборы, ложь);
КонецЕсли;
КонецФункции
Функция обЗаписатьРегистрСведенийСлуж(РСМенеджер, ТЗ, Отборы, Очищать=ложь)
НЗ=РСМенеджер.СоздатьНаборЗаписей();
//Получаем всевозможные наборы отборов из таблицы значений
СписокКлючей="";
Ключи=Новый Структура(); //Содержатся все ключи из отбора
Поиск=Новый Структура(); //Содержатся только те ключи, что есть в таблице значений
Для Каждого Отбор из Отборы Цикл
Ключи.Вставить(Отбор.Ключ, Отбор.Значение);
Если ТЗ.Колонки.Найти(Отбор.Ключ)<>Неопределено Тогда
Поиск.Вставить(Отбор.Ключ);
СписокКлючей=СписокКлючей+?(СписокКлючей="","",",")+Отбор.Ключ;
КонецЕсли;
КонецЦикла;
ТЗ1=ТЗ.Скопировать();
ТЗ1.Свернуть(СписокКлючей, ""); //Получаем различные наборы измерений
Для Каждого СтрОтбор из ТЗ1 Цикл
ЗаполнитьЗначенияСвойств(Поиск, СтрОтбор);
ЗаполнитьЗначенияСвойств(Ключи, СтрОтбор);
Строки=ТЗ.НайтиСтроки(Поиск); //Ищем строки по выбранным измерениям
//Устанавливаем отбор
Для Каждого Эл из Ключи Цикл
Если Эл.Значение<>Неопределено Тогда
НЗ.Отбор[Эл.Ключ].Значение=Эл.Значение;
НЗ.Отбор[Эл.Ключ].Использование=истина;
КонецЕсли;
КонецЦикла;
//Очищаем набор записей
НЗ.Очистить();
Если Не Очищать Тогда
Для Каждого Стр ИЗ Строки Цикл
МЗ=НЗ.Добавить();
ЗаполнитьЗначенияСвойств(МЗ, Ключи);
ЗаполнитьЗначенияСвойств(МЗ, Стр);
КонецЦикла;
КонецЕсли;
НаборЗаписейЗаписать(НЗ);
КонецЦикла;
КонецФункции
20061018: немного переработал функцию, чтобы сначала шла очистка, если она есть, а затем уже запись по измерениям, иначе на практике порой очисткой перетирались данные по измерениям.
Ссылку на обсуждение не смог найти поиском.
Потом выложу как-нибудь.
Важно
Думаю, имеет смысл переписать функцию так, чтобы на ее вход передавался набор записей и структура, содержащая отбор.
Сначала по отбору очищается регистр сведений (выполняется запрос на чтение записей, записи удаляются).
Затем записываются записи из набора сведений.
Т.е. не нужно помечать в таблице значений никакие записи.
Ну можно еще сделать как вариант, чтобы данные брались или из таблицы значений или из набора записей.
Желающие займитесь. Мне пока некогда. |