Обновить прогресс фоне.
Процедура ОбновитьПрогрессВФоне(Контекст, АдресРезультата) Экспорт
ДатаНачалаОбновленияПрогресса = ТекущаяДатаСеанса();
ДлительныеОперации.СообщитьПрогресс(0); // Обновление прогресса выполняется.
СтрокиСписков = Контекст.ХранимыеДанные.СтрокиСписков;
СвойстваСписков = Контекст.ХранимыеДанные.СвойстваСписков;
Если Не Контекст.ЭтоПовторноеОбновлениеПрогресса Тогда
Контекст.ХранимыеДанные.ДатаПоследнегоОбновления = '00010101';
КонецЕсли;
ДействующиеПараметры = Неопределено;
ИдентификаторыТаблиц = ИдентификаторыСписковСОграничением(ДействующиеПараметры);
Для Каждого КлючИЗначение Из ИдентификаторыТаблиц Цикл
Если Не Контекст.ПоказыватьОбработанныеСписки Тогда
Продолжить;
КонецЕсли;
Если СтрокиСписков.Получить(КлючИЗначение.Значение) <> Неопределено Тогда
Продолжить;
КонецЕсли;
ДобавитьНовуюСтрокуСписка(Контекст, КлючИЗначение.Значение, КлючИЗначение.Ключ);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("МаксимальнаяДата", МаксимальнаяДатаПриПродолжении());
Запрос.УстановитьПараметр("ДатаПоследнегоОбновления", Контекст.ХранимыеДанные.ДатаПоследнегоОбновления);
Запрос.УстановитьПараметр("ПустойУникальныйИдентификатор",
ОбщегоНазначенияКлиентСервер.ПустойУникальныйИдентификатор());
Контекст.ХранимыеДанные.ДатаПоследнегоОбновления = ДатаНачалаОбновленияПрогресса;
ТекстыЗапросов = Новый Массив;
ТекстыЗапросов.Добавить(
"ВЫБРАТЬ
| ВсеСпискиОбновления.Список КАК Список,
| МАКСИМУМ(ВсеСпискиОбновления.ОбновлениеЭлементов) КАК ОбновлениеЭлементов,
| МАКСИМУМ(ВсеСпискиОбновления.ОбновлениеКлючейДоступа) КАК ОбновлениеКлючейДоступа
|ИЗ
| (ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОбновлениеКлючейДоступаКДанным.Список КАК Список,
| ИСТИНА КАК ОбновлениеЭлементов,
| ЛОЖЬ КАК ОбновлениеКлючейДоступа
| ИЗ
| РегистрСведений.ОбновлениеКлючейДоступаКДанным КАК ОбновлениеКлючейДоступаКДанным
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОбновлениеКлючейДоступаПользователей.Список,
| ЛОЖЬ,
| ИСТИНА
| ИЗ
| РегистрСведений.ОбновлениеКлючейДоступаПользователей КАК ОбновлениеКлючейДоступаПользователей) КАК ВсеСпискиОбновления
|
|СГРУППИРОВАТЬ ПО
| ВсеСпискиОбновления.Список");
ТекстыЗапросов.Добавить(
"ВЫБРАТЬ
| ОбновлениеКлючей.Список КАК Список,
| ОбновлениеКлючей.ДляВнешнихПользователей КАК ДляВнешнихПользователей,
| ОбновлениеКлючей.КлючУникальности = &ПустойУникальныйИдентификатор КАК ЭтоОсновнаяЗапись,
| МАКСИМУМ(ОбновлениеКлючей.РазмерЗадания) КАК РазмерЗадания,
| МАКСИМУМ(ОбновлениеКлючей.ДатаИзмененияЗаписиРегистра) КАК МаксимальнаяДатаИзменения,
| МИНИМУМ(ОбновлениеКлючей.ДатаИзмененияЗаписиРегистра) КАК МинимальнаяДатаИзменения
|ИЗ
| РегистрСведений.ОбновлениеКлючейДоступаКДанным КАК ОбновлениеКлючей
|ГДЕ
| ОбновлениеКлючей.ДатаИзмененияЗаписиРегистра >= &ДатаПоследнегоОбновления
|
|СГРУППИРОВАТЬ ПО
| ОбновлениеКлючей.Список,
| ОбновлениеКлючей.ДляВнешнихПользователей,
| ОбновлениеКлючей.КлючУникальности = &ПустойУникальныйИдентификатор
|ИТОГИ ПО
| Список,
| ДляВнешнихПользователей");
ТекстыЗапросов.Добавить(СтрЗаменить(ТекстыЗапросов[1],
"РегистрСведений.ОбновлениеКлючейДоступаКДанным",
"РегистрСведений.ОбновлениеКлючейДоступаПользователей"));
Если Контекст.РассчитыватьПоКоличествуДанных Тогда
ТекстыЗапросов.Добавить(
"ВЫБРАТЬ
| ОбновлениеКлючей.Список КАК Список,
| ОбновлениеКлючей.ДляВнешнихПользователей КАК ДляВнешнихПользователей,
| ОбновлениеКлючей.ПараметрыЗадания КАК ПараметрыЗадания
|ИЗ
| РегистрСведений.ОбновлениеКлючейДоступаКДанным КАК ОбновлениеКлючей
|ГДЕ
| ОбновлениеКлючей.ДатаИзмененияЗаписиРегистра >= &ДатаПоследнегоОбновления
| И ОбновлениеКлючей.КлючУникальности = &ПустойУникальныйИдентификатор
| И ОбновлениеКлючей.Список <> НЕОПРЕДЕЛЕНО
|ИТОГИ ПО
| Список");
ТекстыЗапросов.Добавить(СтрЗаменить(ТекстыЗапросов[3],
"РегистрСведений.ОбновлениеКлючейДоступаКДанным",
"РегистрСведений.ОбновлениеКлючейДоступаПользователей"));
ТекстыЗапросов.Добавить(
"ВЫБРАТЬ
| КОЛИЧЕСТВО(*) КАК Количество
|ИЗ
| Справочник.КлючиДоступа КАК КлючиДоступа");
КонецЕсли;
Запрос.Текст = СтрСоединить(ТекстыЗапросов, ОбщегоНазначения.РазделительПакетаЗапросов());
РезультатыЗапроса = Запрос.ВыполнитьПакет();
ВсеСпискиОбновления = РезультатыЗапроса[0].Выгрузить();
СтрокиОбновленияКоличестваЭлементов = Новый Массив;
СтрокиОбновленияКоличестваКлючейДоступа = Новый Массив;
Для Каждого СписокОбновления Из ВсеСпискиОбновления Цикл
Если Не ЗначениеЗаполнено(СписокОбновления.Список) Тогда
Продолжить;
КонецЕсли;
Строка = СтрокиСписков.Получить(СписокОбновления.Список);
Если Строка = Неопределено Тогда
ДобавитьНовуюСтрокуСписка(Контекст, СписокОбновления.Список, "");
КонецЕсли;
КонецЦикла;
УдаляемыеСтроки = Новый Массив;
Для Каждого КлючИЗначение Из СтрокиСписков Цикл
Строка = КлючИЗначение.Значение;
СписокОбновления = ВсеСпискиОбновления.Найти(Строка.Список, "Список");
Если СписокОбновления = Неопределено И Не Контекст.ПоказыватьОбработанныеСписки Тогда
УдаляемыеСтроки.Добавить(Строка);
Продолжить;
КонецЕсли;
СвойстваСписка = СвойстваСписков.Получить(Строка.Список);
Если СписокОбновления = Неопределено Или Не СписокОбновления.ОбновлениеЭлементов Тогда
СвойстваСписка.РазмерЗаданияОбновленияЭлементов = 0;
СвойстваСписка.ПоследнийОбновленныйЭлемент = Null;
СвойстваСписка.РазмерЗаданияОбновленияЭлементовДляВнешнихПользователей = 0;
СвойстваСписка.ПоследнийОбновленныйЭлементДляВнешнихПользователей = Null;
Строка.ДоляОбработанныхЭлементовДляПользователей = 1;
Строка.ДоляОбработанныхЭлементовДляВнешнихПользователей = 1;
Если Контекст.РассчитыватьПоКоличествуДанных Тогда
Если Строка.ОбработаноЭлементов <> 100 Тогда
СтрокиОбновленияКоличестваЭлементов.Добавить(Строка);
КонецЕсли;
Иначе
ОбнулитьКоличествоЭлементов(Строка, Контекст);
КонецЕсли;
ОбновитьЗначениеВСтроке(Строка.ОбработаноЭлементов, 100, Строка, Контекст);
КонецЕсли;
Если СписокОбновления = Неопределено Или Не СписокОбновления.ОбновлениеКлючейДоступа Тогда
СвойстваСписка.РазмерЗаданияОбновленияКлючейДоступа = 0;
СвойстваСписка.ПоследнийОбновленныйКлючДоступа = Null;
СвойстваСписка.РазмерЗаданияОбновленияКлючейДоступаДляВнешнихПользователей = 0;
СвойстваСписка.ПоследнийОбновленныйКлючДоступаДляВнешнихПользователей = Null;
Строка.ДоляОбработанныхКлючейДоступаДляПользователей = 1;
Строка.ДоляОбработанныхКлючейДоступаДляВнешнихПользователей = 1;
Если Контекст.РассчитыватьПоКоличествуДанных Тогда
Если Строка.ОбработаноКлючейДоступа <> 100 Тогда
СтрокиОбновленияКоличестваКлючейДоступа.Добавить(Строка);
КонецЕсли;
Иначе
ОбнулитьКоличествоКлючейДоступа(Строка, Контекст);
КонецЕсли;
ОбновитьЗначениеВСтроке(Строка.ОбработаноКлючейДоступа, 100, Строка, Контекст);
КонецЕсли;
Если СписокОбновления = Неопределено Тогда
ОбновитьЗначениеВСтроке(Строка.ПоследнееОбновление, '00010101', Строка, Контекст);
ОбновитьЗначениеВСтроке(Строка.ПервоеПланированиеОбновления, МаксимальнаяДата(), Строка, Контекст);
КонецЕсли;
КонецЦикла;
Если Контекст.РассчитыватьПоКоличествуДанных Тогда
ВыборкаПоСпискам = РезультатыЗапроса[3].Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаПоСпискам.Следующий() Цикл
СвойстваСписка = СвойстваСписков.Получить(ВыборкаПоСпискам.Список);
Если СвойстваСписка = Неопределено Тогда
Продолжить;
КонецЕсли;
ВыборкаПоВидамПользователей = ВыборкаПоСпискам.Выбрать();
Пока ВыборкаПоВидамПользователей.Следующий() Цикл
Если ВыборкаПоВидамПользователей.ДляВнешнихПользователей Тогда
СвойстваСписка.ПоследнийОбновленныйЭлементДляВнешнихПользователей
= ВыборкаПоВидамПользователей.ПараметрыЗадания;
Иначе
СвойстваСписка.ПоследнийОбновленныйЭлемент
= ВыборкаПоВидамПользователей.ПараметрыЗадания;
КонецЕсли;
КонецЦикла;
КонецЦикла;
ВыборкаПоСпискам = РезультатыЗапроса[4].Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаПоСпискам.Следующий() Цикл
СвойстваСписка = СвойстваСписков.Получить(ВыборкаПоСпискам.Список);
Если СвойстваСписка = Неопределено Тогда
Продолжить;
КонецЕсли;
ВыборкаПоВидамПользователей = ВыборкаПоСпискам.Выбрать();
Пока ВыборкаПоВидамПользователей.Следующий() Цикл
Если ВыборкаПоВидамПользователей.ДляВнешнихПользователей Тогда
СвойстваСписка.ПоследнийОбновленныйКлючДоступаДляВнешнихПользователей
= ВыборкаПоВидамПользователей.ПараметрыЗадания;
Иначе
СвойстваСписка.ПоследнийОбновленныйКлючДоступа
= ВыборкаПоВидамПользователей.ПараметрыЗадания;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
СпискиОбновленияЭлементов = РезультатыЗапроса[1].Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
ОбъектыМетаданныхПоИдентификаторам = ОбщегоНазначения.ОбъектыМетаданныхПоИдентификаторам(
СпискиОбновленияЭлементов.Строки.ВыгрузитьКолонку("Список"), Ложь);
Для Каждого ОписаниеОбновления Из СпискиОбновленияЭлементов.Строки Цикл
Строка = СтрокиСписков.Получить(ОписаниеОбновления.Список);
Если Строка = Неопределено Тогда
Продолжить;
КонецЕсли;
ОбъектМетаданных = ОбъектыМетаданныхПоИдентификаторам.Получить(ОписаниеОбновления.Список);
Если ОбъектМетаданных = Неопределено Или Не ЗначениеЗаполнено(Строка.Список) Тогда
Если УдаляемыеСтроки.Найти(Строка) = Неопределено Тогда
УдаляемыеСтроки.Добавить(Строка);
КонецЕсли;
Продолжить;
ИначеЕсли ТипЗнч(ОбъектМетаданных) = Тип("ОбъектМетаданных")
И Не ЗначениеЗаполнено(Строка.ИмяТаблицы) Тогда
Строка.ИмяТаблицы = ОбъектМетаданных.ПолноеИмя();
КонецЕсли;
СвойстваСписка = СвойстваСписков.Получить(Строка.Список);
ЗаполнитьДолиОбработанных(Строка, ОписаниеОбновления, СвойстваСписка, Истина, Контекст);
Если Не Контекст.РассчитыватьПоКоличествуДанных Тогда
Обработано = ОбработаноПоДолям(Строка.ДоляОбработанныхЭлементовДляПользователей,
Строка.ДоляОбработанныхЭлементовДляВнешнихПользователей, Строка.ИмяТаблицы, ДействующиеПараметры);
ОбновитьЗначениеВСтроке(Строка.ОбработаноЭлементов, Обработано, Строка, Контекст);
ОбнулитьКоличествоЭлементов(Строка, Контекст);
Иначе
Если Контекст.ЭтоПовторноеОбновлениеПрогресса Тогда
СтрокиОбновленияКоличестваЭлементов.Добавить(Строка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
СпискиОбновленияКлючейДоступа = РезультатыЗапроса[2].Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
ОбъектыМетаданныхПоИдентификаторам = ОбщегоНазначения.ОбъектыМетаданныхПоИдентификаторам(
СпискиОбновленияКлючейДоступа.Строки.ВыгрузитьКолонку("Список"), Ложь);
Для Каждого ОписаниеОбновления Из СпискиОбновленияКлючейДоступа.Строки Цикл
ОбъектМетаданных = ОбъектыМетаданныхПоИдентификаторам.Получить(ОписаниеОбновления.Список);
Строка = СтрокиСписков.Получить(ОписаниеОбновления.Список);
Если Строка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ОбъектМетаданных = Неопределено Или Не ЗначениеЗаполнено(Строка.Список) Тогда
Если УдаляемыеСтроки.Найти(Строка) = Неопределено Тогда
УдаляемыеСтроки.Добавить(Строка);
КонецЕсли;
Продолжить;
ИначеЕсли ТипЗнч(ОбъектМетаданных) = Тип("ОбъектМетаданных")
И Не ЗначениеЗаполнено(Строка.ИмяТаблицы) Тогда
Строка.ИмяТаблицы = ОбъектМетаданных.ПолноеИмя();
КонецЕсли;
СвойстваСписка = СвойстваСписков.Получить(Строка.Список);
ЗаполнитьДолиОбработанных(Строка, ОписаниеОбновления, СвойстваСписка, Ложь, Контекст);
Если Не Контекст.РассчитыватьПоКоличествуДанных Тогда
Обработано = ОбработаноПоДолям(Строка.ДоляОбработанныхКлючейДоступаДляПользователей,
Строка.ДоляОбработанныхКлючейДоступаДляВнешнихПользователей, Строка.ИмяТаблицы, ДействующиеПараметры);
ОбновитьЗначениеВСтроке(Строка.ОбработаноКлючейДоступа, Обработано, Строка, Контекст);
ОбнулитьКоличествоКлючейДоступа(Строка, Контекст);
Иначе
Если Контекст.ЭтоПовторноеОбновлениеПрогресса Тогда
СтрокиОбновленияКоличестваКлючейДоступа.Добавить(Строка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемаяСтрока Из УдаляемыеСтроки Цикл
СтрокиСписков.Удалить(УдаляемаяСтрока.Список);
СвойстваСписков.Удалить(УдаляемаяСтрока.Список);
Индекс = Контекст.ДобавленныеСтроки.Найти(УдаляемаяСтрока);
Если Индекс <> Неопределено Тогда
Контекст.ДобавленныеСтроки.Удалить(Индекс);
Продолжить;
КонецЕсли;
Контекст.УдаленныеСтроки.Вставить(УдаляемаяСтрока.Список, Истина);
КонецЦикла;
Индекс = Контекст.ДобавленныеСтроки.Количество() - 1;
Пока Индекс >= 0 Цикл
Если Не ЗначениеЗаполнено(Контекст.ДобавленныеСтроки[Индекс].ИмяТаблицы) Тогда
Контекст.ДобавленныеСтроки.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
Если Не Контекст.ЭтоПовторноеОбновлениеПрогресса Тогда
Для Каждого ОписаниеСтроки Из СтрокиСписков Цикл
СтрокиОбновленияКоличестваЭлементов.Добавить(ОписаниеСтроки.Значение);
СтрокиОбновленияКоличестваКлючейДоступа.Добавить(ОписаниеСтроки.Значение);
КонецЦикла;
КонецЕсли;
Если Контекст.РассчитыватьПоКоличествуДанных Тогда
КоличествоКлючей = РезультатыЗапроса[5].Выгрузить()[0].Количество;
Если Контекст.ЭтоПовторноеОбновлениеПрогресса
И Контекст.ХранимыеДанные.КоличествоКлючей <> КоличествоКлючей Тогда
Для Каждого ОписаниеСтроки Из СтрокиСписков Цикл
Если СтрокиОбновленияКоличестваКлючейДоступа.Найти(ОписаниеСтроки.Значение) = Неопределено Тогда
СтрокиОбновленияКоличестваКлючейДоступа.Добавить(ОписаниеСтроки.Значение);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Контекст.ХранимыеДанные.КоличествоКлючей = КоличествоКлючей;
Иначе
Контекст.ХранимыеДанные.КоличествоКлючей = 0;
КонецЕсли;
Если Контекст.РассчитыватьПоКоличествуДанных Тогда
ТекущийКонтекст = Новый Структура;
ТекущийКонтекст.Вставить("ДобавленныеСтроки", Контекст.ДобавленныеСтроки);
ТекущийКонтекст.Вставить("ИзмененныеСтроки", Контекст.ИзмененныеСтроки);
ТекущийКонтекст.Вставить("СвойстваСписков", СвойстваСписков);
ТекущийКонтекст.Вставить("СтрокиСписков", СтрокиСписков);
ТекущийКонтекст.Вставить("ДействующиеПараметры", ДействующиеПараметры);
ТекущийКонтекст.Вставить("СтрокиОбновленияКоличестваЭлементов", СтрокиОбновленияКоличестваЭлементов);
ТекущийКонтекст.Вставить("СтрокиОбновленияКоличестваКлючейДоступа", СтрокиОбновленияКоличестваКлючейДоступа);
ТекущийКонтекст.Вставить("ИдентификаторыТаблиц", ИдентификаторыТаблиц);
ТекущийКонтекст.Вставить("ХранимыеДанные", Контекст.ХранимыеДанные);
ВсегоОбновлено = 100;
РассчитатьВсегоОбновленоПоКоличествуДанных(ТекущийКонтекст, ВсегоОбновлено);
Иначе
Если Контекст.ХранимыеДанные.Свойство("КоличествоЭлементовПоСпискам") Тогда
Контекст.ХранимыеДанные.Удалить("КоличествоЭлементовПоСпискам");
Контекст.ХранимыеДанные.Удалить("КоличествоКлючейДоступаПоСпискам");
КонецЕсли;
ВсегоКоличество = ИдентификаторыТаблиц.Количество();
Если СтрокиСписков.Количество() > ВсегоКоличество Тогда
ВсегоКоличество = СтрокиСписков.Количество();
КонецЕсли;
ВсегоОбновлено = (100 + 100) * (ВсегоКоличество - СтрокиСписков.Количество());
Для Каждого КлючИЗначение Из СтрокиСписков Цикл
Строка = КлючИЗначение.Значение;
ВсегоОбновлено = ВсегоОбновлено + Строка.ОбработаноЭлементов + Строка.ОбработаноКлючейДоступа;
КонецЦикла;
ВсегоОбновлено = ВсегоОбновлено / 2 / ВсегоКоличество;
КонецЕсли;
Если ВсегоОбновлено > 100 Тогда
ВсегоОбновлено = 100;
КонецЕсли;
Контекст.ВсегоОбновлено = Цел(ВсегоОбновлено);
ВремяОбновления = ТекущаяДатаСеанса() - ДатаНачалаОбновленияПрогресса;
Если Контекст.ЭтоПовторноеОбновлениеПрогресса
И ВремяОбновления > Контекст.ПериодОбновленияПрогресса Тогда
Контекст.ПериодОбновленияПрогресса = ВремяОбновления;
Иначе
Контекст.Удалить("ПериодОбновленияПрогресса");
КонецЕсли;
Если Не Контекст.ЭтоПовторноеОбновлениеПрогресса И ВремяОбновления > 60 Тогда
Контекст.АвтообновлениеПрогресса = Ложь;
Иначе
Контекст.Удалить("АвтообновлениеПрогресса");
КонецЕсли;
Отбор = Новый Структура("Метаданные", Метаданные.РегламентныеЗадания.ОбновлениеДоступаНаУровнеЗаписей);
Задания = РегламентныеЗаданияСервер.НайтиЗадания(Отбор);
Включено = Ложь;
Для Каждого Задание Из Задания Цикл
Если Задание.Использование Тогда
Включено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не Включено И Контекст.ВсегоОбновлено < 100 Тогда
Контекст.Вставить("РегламентноеЗаданиеОтключено");
КонецЕсли;
ПоместитьВоВременноеХранилище(Контекст, АдресРезультата);
КонецПроцедуры
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
ОбновитьИнформационнуюБазуВФоне (БСП)
Прогресс с помощью СКД на обычных формах