Книга знаний

1С:Предприятие / v8 / Объекты конфигурации / Регистры

v8: Запись таблицы значений в регистр сведений с автоматическими отборами

Чтобы не мучаться с отборами и записать таблицу значений в регистр сведений, используйте мою функцию.Автор статьи: Гений 1С | Редакторы:
Последняя редакция №3 от 07.12.06 | История
URL: http://kb.mista.ru/article.php?id=383

Ключевые слова: регистр сведений,набор записей,запись,измерения


Отборы - это структура, которая указывает, по каким измерениям делать отборы при записи таблицы значений в регистр сведений.
ТЗ - таблица, которая записывается в регистр сведений.

Если измерение есть в Отборы и в ТЗ, то значение измерения берется из ТЗ, это дает бонусы:
1. Можно в Отборы указать значение измерения, общего для всех строк.

Также можно использовать какую-либо колонку ТЗ (имя колонки задается в КолонкаОчистки), непустое значение в которой указывает, что строка используется только для очистки регистра сведений по содержащимся в строке измерениям.

Это позволяет использовать одну и ту же ТЗ для заполнения данных и очистки регистра сведений по тем измерениям, где данных нет.

Например, если мы заполняем РС по подразделениям, можно сначала получить данные для занесения в регистр и занести их в ТЗ, а затем добавить в ТЗ по одной строке на каждое подразделение.
Таким образом будет гарантировано, что по тем подразделениям, по которым не было получено данных, но были старые данные, произойдет очистка значений.

//Позволяет записать таблицу значений в регистр сведений, перезаписывая старые записи
//Отборы - показывает, в разрезе каких измерений очищать записи
//КолонкаОчистки - указывает на колонку (если она есть), если в ней содержится значение, не равное Неопределено,
//    то эта строка ТЗ не переносится в регистр сведений. Т.е. такие строки используются только для очистки значений.


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

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


20061018: немного переработал функцию, чтобы сначала шла очистка, если она есть, а затем уже запись по измерениям, иначе на практике порой очисткой перетирались данные по измерениям.

Ссылку на обсуждение не смог найти поиском.
Потом выложу как-нибудь.

Важно


Думаю, имеет смысл переписать функцию так, чтобы на ее вход передавался набор записей и структура, содержащая отбор.
Сначала по отбору очищается регистр сведений (выполняется запрос на чтение записей, записи удаляются).
Затем записываются записи из набора сведений.
Т.е. не нужно помечать в таблице значений никакие записи.
Ну можно еще сделать как вариант, чтобы данные брались или из таблицы значений или из набора записей.
Желающие займитесь. Мне пока некогда.

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика