ОбновитьНаборЗаписей (БСП)

Автор: 1С
ОбщийМодуль.УправлениеДоступомСлужебный
1С БСП

Обновить набор записей. Обновляет набор записей в базе данных,

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

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

Рекомендации

Похожие публикации

ОбновитьНаборыЗаписей (БСП)

ВсеНаборыЗаписей (БСП)

ЗаписатьНаборЗаписей (БСП)

ЭтоНаборЗаписей (БСП)

НаборЗаписейРегистраПустой (БСП)

ЭтоНезависимыйНаборЗаписей (БСП)

ПолучитьПорциюДанныхНезависимогоНабораЗаписей (БСП)

ОбновитьНаборыЗначенийДоступа (БСП)

TurboConf 6 - расширение Конфигуратора 1С