Программная работа с регистром сведений в 1С 8.3

Jul 10, 2022 17:27

Добавление записей в регистр сведений выполняется с помощью набора записей. Набор записей - это коллекция нескольких записей регистра сведений.

Для добавление новых записей в регистр сведений нужно:

- Создать набор записей
- Установить у него отбор по тем измерениям и периоду (если регистр периодический), по которым нужно добавить новые записи
- Добавить в набор необходимое количество новых записей
- Записать набор записей

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//устанавливаем отбор по измерениям и периоду
НаборЦен.Отбор.Товар.Установить(СсылкаНаТовар);
НаборЦен.Отбор.ТипЦен.Установить(СсылкаНаТипЦен);
НаборЦен.Отбор.Период.Установить(Дата);

//добавляем новую запись
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = СсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

//записываем набор записей
НаборЦен.Записать();


Набор записей с установленным отбором можно назвать гранулой. Запись в регистр сведений выполняется гранулами.

Если при записи не устанавливать отбор, то будет перезаписан весь регистр сведений, все предыдущие записи будут удалены:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();

//добавляем новую запись
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = СсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

//записываем набор записей
НаборЦен.Записать();
//после записи все предыдущие записи регистра будут удалены
//так как не был установлен отбор

Можно установить отбор только по одному измерению и сразу добавить несколько записей:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//устанавливаем отбор по одному измерению
НаборЦен.Отбор.ТипЦен.Установить(СсылкаНаТипЦен);

//добавляем новую запись
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = СсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

//добавляем еще одну запись
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = ЕщеОднаСсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 850;

//записываем набор записей
НаборЦен.Записать();

То есть при записи выполняется добавление новых записей с замещением тех записей, которые удовлетворяют установленному отбору.

Но если в метод Записать набора записей передать параметр Ложь, то запись будет выполнена с добавлением новых записей:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();

//добавляем новую запись
//не устанавливаем отбор в регистре сведений
//так как будем записывать с добавлением
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = СсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

//записываем набор записей с добавлением
НаборЦен.Записать(Ложь);

В результате в регистр сведений будет добавлена новая запись, но при этом все предыдущие записи не были удалены.

Если попытаться добавить в регистр сведений записи, которые не совпадают с установленным отбором, то будет выброшено исключение «Запись не верна! Значение поля не соответствует установленному отбору»:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//устанавливаем отбор по измерениям и периоду
НаборЦен.Отбор.Товар.Установить(СсылкаНаТовар);
НаборЦен.Отбор.ТипЦен.Установить(СсылкаНаТипЦен);
НаборЦен.Отбор.Период.Установить(Дата);

//добавляем новую запись, но товар записываем не тот, который указали в отборе
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = ЕщеОднаСсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

//записываем набор записей
НаборЦен.Записать(); //НЕ ЗАПИШЕТСЯ

Запись в регистр сведений, подчиненный регистратору может выполняться только с отбором по регистратору. В обработке проведения отбор по регистратору устанавливается автоматически, но если запись выполнять в другом месте, то нужно сделать это вручную:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//устанавливаем отбор по регистратору
НаборЦен.Отбор.Регистратор.Установить(СсылкаНаДок);

//добавляем новые записи
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = СсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = ЕщеОднаСсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 950;

//записываем набор записей
НаборЦен.Записать();

Отбор записей регистра сведений

Отбор позволяет не только установить гранулу при записи в регистр сведений, но и прочитать нужные записи регистра. Например, можно получить все записи по одному товару:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//отбор записей регистра сведений
НаборЦен.Отбор.Товар.Установить(СсылкаНаТовар);
//читаем набор записей
НаборЦен.Прочитать();

Для Каждого ЗаписьРег Из НаборЦен Цикл
Сообщить(ЗаписьРег.Период);
Сообщить(ЗаписьРег.Цена);
КонецЦикла;

После установки отбора набора записей, мы прочитали данные из регистра методом Прочитать. Данный метод загрузил в переменную НаборЦен все записи, удовлетворяющие отбору. После этого их можно перебрать в цикле и через точку обращаться к полям записи регистра.

Удаление записей регистра сведений

Чтобы удалить запись из регистра сведений нужно создать набор записей, установить необходимый отбор и записать пустой набор записей:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//устанавливаем отбор по измерениям и периоду
НаборЦен.Отбор.Товар.Установить(СсылкаНаТовар);
НаборЦен.Отбор.ТипЦен.Установить(СсылкаНаТипЦен);
НаборЦен.Отбор.Период.Установить(Дата);

//записываем пустой набор записей
НаборЦен.Записать();

Чтобы очистить весь регистр сведений можно записать пустой набор записей без отбора:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//записываем пустой набор записей
НаборЦен.Записать();
//регистр сведений будет очищен

Если регистр сведений подчинен регистратору, то нужно устанавливать отбор по документу-регистратору:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//отбор по регистратору
НаборЦен.Отбор.Регистратор.Установить(СсылкаНаДок);
//записываем пустой набор записей
НаборЦен.Записать();

Если нужно удалить записи с отбором по ресурсу, то можно запросом выбрать необходимые записи, в цикле установить по нужным измерениям отбор и записать пустой набор записей:

ЗапросКРегистру = Новый Запрос;
ЗапросКРегистру.Текст = "ВЫБРАТЬ
| ЦеныНаТовары.Период КАК Период,
| ЦеныНаТовары.Товар КАК Товар,
| ЦеныНаТовары.ТипЦен КАК ТипЦен
|ИЗ
| РегистрСведений.ЦеныНаТовары КАК ЦеныНаТовары
|ГДЕ
| ЦеныНаТовары.Цена >= &Цена";
ЗапросКРегистру.УстановитьПараметр("Цена", 500);
ВыборкаРегистра = ЗапросКРегистру.Выполнить().Выбрать();
//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
Пока ВыборкаРегистра.Следующий() Цикл
//устанавливаем отбор регистра сведений
НаборЦен.Отбор.Период.Установить(ВыборкаРегистра.Период);
НаборЦен.Отбор.Товар.Установить(ВыборкаРегистра.Товар);
НаборЦен.Отбор.ТипЦен.Установить(ВыборкаРегистра.ТипЦен);
//записываем пустой набор записей
НаборЦен.Записать();
КонецЦикла;

В данном примере мы удалили все записи, у которых цена больше или равна 500. Но можно было решить ее от обратного: выбрать все записи, у которых цена меньше 500, создать набор записей и загрузить в него результат запроса. Так как отбор не был установлен, то весь регистр будет перезаписан и в нем останутся только те записи, где цена меньше 500:

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

Изменение записей регистра сведений

Чтобы изменить существующие записи регистра сведений нужно сначала прочитать их через набор записей, потом перебрать в цикле, изменить и записать набор записей. Например, увеличим все цены по одному типу цен на 10%:

//создаем набор записей регистра сведений
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();
//устанавливаем отбор по типу цен
НаборЦен.Отбор.ТипЦен.Установить(СсылкаНаТипЦен);
//читаем набор записей из базы
НаборЦен.Прочитать();

//перебираем в цикле записи
Для Каждого ЗаписьРег Из НаборЦен Цикл
//увеличиваем на 10%
ЗаписьРег.Цена = ЗаписьРег.Цена * 1.1;
КонецЦикла;

//записываем набор записей
НаборЦен.Записать();

Можно в запросе выбрать все измерения и период (для периодического регистра) и также изменить через набор записей, установив необходимый отбор:

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

//перебираем в цикле записи
Для Каждого ЗаписьРег Из НаборЦен Цикл
//увеличиваем на 10%
ЗаписьРег.Цена = ЗаписьРег.Цена * 1.1;
КонецЦикла;

//записываем набор записей
НаборЦен.Записать();
КонецЦикла;

Если регистр сведений подчинен регистратору, то отбор нужно устанавливать по регистратору:

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

//перебираем в цикле записи
Для Каждого ЗаписьРег Из НаборЦен Цикл
//увеличиваем на 10% только для одного типа цен
Если ЗаписьРег.ТипЦен = СсылкаНаТипЦен Тогда
ЗаписьРег.Цена = ЗаписьРег.Цена * 1.1;
КонецЕсли;
КонецЦикла;

//записываем набор записей
НаборЦен.Записать();
КонецЦикла;

Менеджер записи регистра сведений

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

Менеджер записи доступен только для регистров сведений с режимом записи Независимый.

Менеджер записи можно создать программно:

//добавление записи в регистр сведений
//через менеджер записи
МенеджерЦен = РегистрыСведений.ЦеныНаТовары.СоздатьМенеджерЗаписи();
МенеджерЦен.Товар = СсылкаНаТовар;
МенеджерЦен.ТипЦен = СсылкаНаТипЦен;
МенеджерЦен.Период = Дата(2021,4,1);
МенеджерЦен.Цена = 500;
МенеджерЦен.Записать();

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

//удаление записи из регистра сведений
//через менеджер записи
МенеджерЦен = РегистрыСведений.ЦеныНаТовары.СоздатьМенеджерЗаписи();
МенеджерЦен.Товар = СсылкаНаТовар;
МенеджерЦен.ТипЦен = СсылкаНаТипЦен;
МенеджерЦен.Период = Дата(2021,4,1);
МенеджерЦен.Удалить();

С помощью менеджера записи сначала была добавлена новая запись затем изменена и наконец удалена.

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

Для примера добавим в модуль набора записей следующий код:

Процедура ПередЗаписью(Отказ, Замещение)
Сообщить("Товар: " + ЭтотОбъект.Отбор.Товар);
Сообщить("Количество: " + ЭтотОбъект.Количество());
КонецПроцедуры

Откроем форму записи для товара Шкаф, изменим измерение товар на Тумбочку и запишем. В сообщениях увидим следующий результат:

Сначала был записан старый пустой набор записей с товаром Шкаф, а потом новый с товаром Тумбочка.

Набор записей регистра сведений

Программную работу с набором записей регистра сведений рассмотрим на примерах:

//создание набора записей
НаборЦен = РегистрыСведений.ЦеныНаТовары.СоздатьНаборЗаписей();

//количество записей набора
Колво = НаборЦен.Количество(); //0

//чтение набора записей из базы
НаборЦен.Прочитать();
Колво = НаборЦен.Количество(); //6

//добавление записей
НоваяЦена = НаборЦен.Добавить();
НоваяЦена.Товар = СсылкаНаТовар;
НоваяЦена.ТипЦен = СсылкаНаТипЦен;
НоваяЦена.Период = Дата;
НоваяЦена.Цена = 750;

//выгрузка в таблицу значений
ТаблицаЦен = НаборЦен.Выгрузить();

//удаление всех записей набора
НаборЦен.Очистить();

//загрузка из таблицы значений
НаборЦен.Загрузить(ТаблицаЦен);

//удаление первой записи набора
НаборЦен.Удалить(0);

//выгрузка одной колонки в массив
МассивТоваров = НаборЦен.ВыгрузитьКолонку("Товар");
//загружаем обратно
НаборЦен.ЗагрузитьКолонку(МассивТоваров, "Товар");

//сумма всех цен
Итог = НаборЦен.Итог("Цена");

//запись набора
НаборЦен.Записать();

Ключ записи регистра сведений

Так как регистр сведений относится к необъектным данным, то у него нет реквизита Ссылка. Если нужно сослаться на определенную запись регистра, то можно использовать Ключ записи. Ключ записи можно создать через конструктор или через менеджер регистра сведений методом СоздатьКлючЗаписи:

//пустой ключ
ПустойКлюч = Новый("РегистрСведенийКлючЗаписи.ЦеныНаТовары");
//можно через менеджер
ПустойКлюч = РегистрыСведений.ЦеныНаТовары.ПустойКлюч();

//ключ на определенную запись регистра
ЗначенияКлюча = Новый Структура;
ЗначенияКлюча.Вставить("Период", Дата(2021,4,1));
ЗначенияКлюча.Вставить("Товар", СсылкаНаТовар);
ЗначенияКлюча.Вставить("ТипЦен", СсылкаНаТипЦен);
КлючНаЗапись = РегистрыСведений.ЦеныНаТовары.СоздатьКлючЗаписи(ЗначенияКлюча);

Смотрите также:
Электронный учебник по программированию в 1С
Рекомендации по изучению программирования 1С с нуля
Игра "Кто хочет стать миллионером?" с вопросами на определенную тематику (язык программирования JavaScript, английские, немецкие, французские, испанские, португальские, ни­дер­ландские, итальянские слова, электробезопасность, промышленная безопасность, бокс и т.п.), написанная на 1С
Программирование в 1С 8.3 с нуля - краткий самоучитель
Комплексная подготовка программистов 1С:Предприятие 8.2
Сайты с уроками программирования и со справочниками
Youtube-каналы с уроками программирования
Сайты для обучения программированию
Лекции и уроки

программирование

Previous post Next post
Up