Как создать, изменить и удалить запись в регистре сведений программно

Содержание статьи

Виды регистров сведений

Регистры сведений делятся на два основных вида – независимые и подчиненные регистратору. Уже из названия понятно, что запись в подчиненный регистр происходит при проведении документа-регистратора. Таким образом, создание, изменение и удаление записей в таком регистре происходит с помощью движений документа. Добавление и изменение происходит при проведении документа, а вот удаление записи при отмене проведения. По сути, этот процесс уже автоматизирован компанией 1С, нужно только прописать механизм записи движений в регистр.

Независимый же регистр сведений не подчинен никому, он сам по себе. Да-да, прямо как кот, который гуляет сам по себе. Он хранит какие то информационные сведения, не привязанные к какому то документу. В нем создание, изменение и удаление записей происходит вручную.

Независимый регистр сведений

Создание записи

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

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

МенеджерЗаписи = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьМенеджерЗаписи(); 

МенеджерЗаписи.Период = ДатаЗаписи; 
МенеджерЗаписи.НомерДома = НомерДома; 
МенеджерЗаписи.НомерКвартиры = НомерКвартиры; 
МенеджерЗаписи.СредняяТемпература = СредняяТемпература; 
МенеджерЗаписи.Записать();  

После выполнения этого кода новая запись будет добавлена в регистр. Если же в регистре уже существует запись с заданным значением измерения “НомерКвартиры” и “НомерДома” на эту дату, то она будет заменена на новую.

Это мы привели пример, как создать одну запись в регистре сведений. А что, если нам нужно записывать данные сразу по всем квартирам? Для этого можно воспользоваться набором записей (метод СоздатьНаборЗаписей()). Предположим, что данные по квартирам уже сформированы в таблицу значений ТемператураВКвартирах специальным прибором. Тогда код создания набора записей будет выглядеть следующим образом:

НаборЗаписей = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Период.Уставноить(ДатаЗаписи);

Для Каждого СтрокаТаблицы Из ТемператураВКвартирах Цикл    
   НоваяЗапись = НаборЗаписей.Добавить();  
   НоваяЗапись.Период = ДатаЗаписи;  
   НоваяЗапись.НомерДома = СтрокаТаблицы.НомерДома; 
   НоваяЗапись.НомерКвартиры = СтрокаТаблицы.НомерКвартиры; 
   НоваяЗапись.СредняяТемпература = СтрокаТаблицы.СредняяТемпература; 
КонецЦикла; 

НаборЗаписей.Записать(); 

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

Создание записи в подчиненном регистре сведений

Обычно запись в такой регистр происходит при проведении документа-регистратора. Но, наверное, может возникнуть ситуация, когда нужно добавить запись в подчиненный регистр из какого то места в коде. Сделать это можно методом СоздатьНаборЗаписей(). Причем этот метод применяется как при создании одной записи, так и при создании коллекции. Для начала делаем отбор по регистратору, затем создаем запись в наборе записей. В данном случае создании одной записи практически ничем не отличается от создании сразу нескольких записей. Отличие лишь в том, что во втором случае код происходит в цикле. Поэтому для примера приведен один код для двух случаев. Представим, что если у нас нет записей в таблице, то формируем одну запись, в противном случае – коллекцию.

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

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

Изменение записей

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

Итак, для того, чтобы изменить запись в независимом регистре сведений будем использовать все тот же менеджер записи. После этого найдем конкретную запись. Для этого сделаем отбор по периоду и измерениям (НомерДома, НомерКвартиры). Далее проверим методом Выбран(), существует ли такая запись в регистре или нет. Если существует, то меняем среднюю температуру. Ниже приведем пример кода:

Запись = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьМенеджерЗаписи();
Запись.Период = '20241212';
Запись.НомерДома = 1;
Запись.НомерКвартиры = 12;
Запись.Прочитать();

Если Запись.Выбран() Тогда
   Запись.СредняяТемпература = 23.1;
   Запись.Записать();
КонецЕсли;

Для изменения набора записей можно придумать разные варианты. Все зависит от конкретной задачи. Наша задача довольно простая – мы имеем таблицу с корректировкой средней температуры на конкретный день. Тогда мы просто делаем отбор во всем наборе записей регистра по каждой строке таблицы. После этого просто меняем значение температуры в одной строке набора записей и записываем его. Ниже приведен код:

НаборЗаписей = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьНаборЗаписей();

Для каждого СтрокаТаблицы Из ТемператураВКвартирах Цикл	
   НаборЗаписей.Отбор.НомерДома.Установить(СтрокаТаблицы.НомерДома);
   НаборЗаписей.Отбор.НомерКвартиры.Установить(СтрокаТаблицы.НомерКвартиры);
   НаборЗаписей.Отбор.Период.Установить(ДатаЗаписи);
   НаборЗаписей.Прочитать();
	
   Если НаборЗаписей.Количество() > 0 Тогда				
      Запись = НаборЗаписей[0];			
      Запись.СредняяТемпература = СтрокаТаблицы.СредняяТемпература; 
      НаборЗаписей.Записать();
   КонецЕсли;
КонецЦикла;

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

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

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

  • создать набор записей;
  • установить отбор по регистратору;
  • прочитать набор записей;
  • перебрать все записи набора, сравнивая их с изменяемыми сведениями до тех пор, пока не будет найдена подходящая запись в регистре;
  • записать модифицированный набор записей (чтобы лишний раз не записывать набор, вдруг мы не найдем совпадений).

И уже здесь мы видим, что алгоритм не особо то эффективный. В независимом регистре сведений мы просто выставляли отборы, чтобы найти нужную запись. Вы спросите, почему нельзя сделать также? Дело в том, что в подчинённом регистре сведений отбор можно делать только по регистратору. Именно поэтому приходится перебирать все записи набора. Код изменения температуры в одной квартире в нашем примере будет иметь следующий вид:

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

Для каждого ЗаписьНабора Из НаборЗаписей Цикл			
   Если НачалоДня(ЗаписьНабора.Период) = НачалоДня(ДатаЗаписи) 
      И ЗаписьНабора.НомерДома = НомерДома
      И ЗаписьНабора.НомерКвартиры = НомерКвартиры Тогда				
      
      ЗаписьНабора.СредняяТемпература = СредняяТемпература; 
   КонецЕсли;				
КонецЦикла; 
		
Если НаборЗаписей.Модифицированность() Тогда
   НаборЗаписей.Записать();
КонецЕсли;

Заметьте, что при сравнении даты мы приводим обе даты в начало дня. Почему? Так как у нас периодичность регистра День, то мы все делаем в разрезе дня, то есть время в дате нам не важно. Но время в дате может не совпадать в изменяемой дате и в дате, которая в регистре. Поэтому мы приводим все в один формат. Если бы у нас была периодичность месяц, то мы бы приводили все к одному месяцу и т.д.

Изменение нескольких записей регистра

Изменение коллекции записей происходит по сути по той же схеме, но в чем же вопрос? А вопрос в том, как более эффективно это сделать. Если смотреть по аналогии, то мы перебираем все записи набора записей и ищем совпадения с изменяемыми данными. Но изменяемых то данных может быть много. Если у нас всего 1000 квартир, а изменять данные мы будем в 500 записях, то нужно каждую запись из 1000 сравнить с 500 измененными. Получается нужно пройти 1000*500 = 500 000 итераций цикла. А если записей еще больше? Поэтому здесь все зависит от задачи и ситуации. Если данных не много, то можно просто перебрать их с помощью вложенных циклов как описано выше. Вот как это будет выглядеть (первые 3 строки будет как и при изменении одной записи):

...
Для каждого ЗаписьНабора Из НаборЗаписей Цикл
			
   Для каждого СтрокаТаблицы Из ТемператураВКвартирах Цикл
				
      Если НачалоДня(ЗаписьНабора.Период) = НачалоДня(ДатаЗаписи) 
         И ЗаписьНабора.НомерДома = СтрокаТаблицы.НомерДома
         И ЗаписьНабора.НомерКвартиры = СтрокаТаблицы.НомерКвартиры Тогда
					
         ЗаписьНабора.СредняяТемпература = СтрокаТаблицы.СредняяТемпература; 
      КонецЕСли;
							
   КонецЦикла;
						
КонецЦикла;   
		
Если НаборЗаписей.Модифицированность() Тогда
   НаборЗаписей.Записать();
КонецЕсли;

Вы можете придумать свой вариант поиска совпадений. Например, можно каждый раз начинать поиск не с начала, а с места, где нашли первое совпадение. Или можно воспользоваться такими методами набора записей как Выгрузить() и Загрузить(). Таким образом мы можем выгрузить набор записей, отредактировать его каким то более эффективным способом и загрузить обратно. Но это уже тема немного другой статьи. Я думаю сама суть понятна.

Удаление записей

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

В независимом регистре сведений удаление одной записи происходит по тому же принципу, что и изменение. Мы по сути “утверждаем”, что в регистре существует запись с такими измерениями и пытаемся ее прочитать. Если она действительно существует (что мы проверяем методом Выбран()), то мы ее меняем. Ну или в данном случае удаляем. Ниже приведен пример кода:

Запись = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьМенеджерЗаписи();
Запись.Период = ДатаЗаписи;
Запись.НомерДома = НомерДома;
Запись.НомерКвартиры = НомерКвартиры;
Запись.Прочитать();
	
Если Запись.Выбран() Тогда	
   Запись.Удалить();
КонецЕсли; 

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

НаборЗаписей = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьНаборЗаписей();
	
Для каждого СтрокаТаблицы Из ТемператураВКвартирах Цикл	
   НаборЗаписей.Отбор.НомерДома.Установить(СтрокаТаблицы.НомерДома);
   НаборЗаписей.Отбор.НомерКвартиры.Установить(СтрокаТаблицы.НомерКвартиры);
   НаборЗаписей.Отбор.Период.Установить(ДатаЗаписи);
   НаборЗаписей.Прочитать();
	
   Если НаборЗаписей.Количество() > 0 Тогда				
      Запись = НаборЗаписей[0];			
      НаборЗаписей.Удалить(Запись);
      НаборЗаписей.Записать();
   КонецЕсли;		
КонецЦикла; 

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

Удаление одной записи в подчиненном регистре происходит также как и изменение. Только вместо изменения средней температуры в записи мы удаляем найденную запись. Получается такой код (меняется только одна строка):

...
Если НачалоДня(ЗаписьНабора.Период) = НачалоДня(ДатаЗаписи) 
	И ЗаписьНабора.НомерДома = НомерДома
	И ЗаписьНабора.НомерКвартиры = НомерКвартиры Тогда
				
	НаборЗаписей.Удалить(ЗаписьНабора); 
КонецЕсли;
...

А вот удаление коллекции записей из подчиненного регистра сведений снова немного отличается. Скорее всего снова можно придумать разные варианты. Здесь будет представлен тот, который мне ближе. Суть его в том, что мы вначале ищем записи, которые нужно удалить и добавляем из в массив. Далее мы обходим получившийся массив записей, удаляя их из набора. Если удалять сразу из набора, то при смещении индекса цикла могут быть пропущены записи. Пропустим часть кода, где устанавливается отбор и читается набор. Ее можно найти выше в статье. Таким образом, получаем следующий код:

...		
УдаляемыеЗаписи = Новый Массив;
		
Для каждого ЗаписьНабора Из НаборЗаписей Цикл			
   Для каждого СтрокаТаблицы Из ТемператураВКвартирах Цикл
				
      Если НачалоДня(ЗаписьНабора.Период) = НачалоДня(ДатаЗаписи) 
         И ЗаписьНабора.НомерДома = СтрокаТаблицы.НомерДома
         И ЗаписьНабора.НомерКвартиры = СтрокаТаблицы.НомерКвартиры Тогда
					
         УдаляемыеЗаписи.Добавить(ЗаписьНабора);
      КонецЕсли;
							
   КонецЦикла;						
КонецЦикла; 
		
Для каждого УдаляемаяЗапись Из УдаляемыеЗаписи Цикл		
   НаборЗаписей.Удалить(УдаляемаяЗапись);		
КонецЦикла;
		
Если НаборЗаписей.Модифицированность() Тогда
   НаборЗаписей.Записать();
КонецЕсли;

Очистка регистра сведений

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

НаборЗаписей = РегистрыСведений.ДневнаяТемператураВКвартирах.СоздатьНаборЗаписей(); 
НаборЗаписей.Записать();

Заключение

Надеемся, что эта статья оказалась для вас полезной. Если у вас остались какие то вопросы или есть свое видение каких то моментов мы ждем вас в комментариях. Также будем рады вам помочь с внедрением, доработкой, сопровождением или консультацией по продуктам 1С. Мы также являемся официальным представителем 1С. Поэтому вы можете приобрести лицензии 1С у нас. Мы поможем вам с установкой и проведем первичную консультацию по продукту. Телефон отдела продаж вы найдете в шапке сайта. Желаем развития вам и вашему бизнесу.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *