Обновить набор записей. Обновляет набор записей в базе данных,
// Обновляет набор записей в базе данных,
// если записи набора отличаются от записей в базе данных.
//
// Параметры:
// Данные - Структура - со свойствами:
// * НаборЗаписей - НаборЗаписей пустой или прочитанный с заданным отбором или без отбора.
// Менеджер регистра для создания набора записей.
//
// * НовыеЗаписи - ТаблицаЗначений в формате регистра.
//
// * ПоляСравнения - Строка - содержит список полей по значениям которых требуется вычислять
// отличие записей набора. Например, "Измерение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
///////////////////////////////////////////////////////////////////////////////////////////////////////
НаборЗаписейРегистраПустой (БСП)
ЭтоНезависимыйНаборЗаписей (БСП)
Канал FastCode 1C в Телеграм! Шаблоны кода, статьи, полезные советы, курсы по 1С (8К участников)