1С: Фоновые задания внутри фоновых заданий

Задача: распаралелить медленную вставку записей в БД 1С, при чтении файла Excel

Как ни странно, но такая возможность есть и работает начиная с версии платформы 8.3.8. Т.е. можно запустить фоновое задание внутри фонового задания….ну например по вставке в БД большого количества записей, которая выполняется весьма медленно. Полноценно этот процесс распаралелить можно например как-то так:

Функция СделатьЗаписьвБДПДЗФоново(парам) экспорт
	...
    // делаем медленную запись в БД
	...
конецфункции	

// Просматриваем массив с идентификаторами фоновых заданий и удаляем те которые завершились
Функция ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий) экспорт
		для каждого ФЗМ из МассивФоновыхЗаданий цикл
			ФЗ = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ФЗМ);
			если ФЗ.Состояние<>СостояниеФоновогоЗадания.Активно тогда
				МассивФоновыхЗаданий.Удалить(МассивФоновыхЗаданий.Найти(ФЗМ));
			конецесли;	
		конеццикла;		
	возврат МассивФоновыхЗаданий;
конецфункции		

// выполняем загрузку построчно файла Excel, запуская запись данных в БД
// отдельным потоком. Количество потоков ограничивам 10 штуками
Функция ВыполнитьЗагрузку(парам) экспорт
	МассивФоновыхЗаданий=Новый Массив();
	МаксимумЗаданий=10;
...
    Для	 нСтрокаТФ = 2 ПО КолВоСтрокФайла Цикл  
        ....
			МассивПараметров = Новый Массив;
			Параметры=Новый Структура("aa,bb,cc",
				1,
				2,
				3,
            );
			МассивПараметров.Добавить(Параметры);
			ФЗ = ФоновыеЗадания.Выполнить("ДлительныеОперации.СделатьЗаписьвБДПДЗФоново",МассивПараметров);	
			МассивФоновыхЗаданий.Добавить(ФЗ.УникальныйИдентификатор);											
			МассивФоновыхЗаданий=ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий);
			// ждём пока завершаться запущеные потоки, если их больше 10
			пока МассивФоновыхЗаданий.Количество()>МаксимумЗаданий цикл
				МассивФоновыхЗаданий=ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий);
			конеццикла;	        
        ....
   конеццикла;
конецфункции	   

В ниже приведённом каркасе кода, фоново выполняется функция ВыполнитьЗагрузку(), которая читает большой файл Excel, затем каждый цикл вставки записи в БД запускает в свою очередь фоново, ограничивая в данном случае количество фоновых заданий 10 штуками.

Сложение с null в запросе

Иногда удаётся найти подводные камни там, где совсем не ждешь от 1С. Оказывается в запросах 1С, сложение столбцов а+б даёт в сумме null, если одно из значений равно null. даже если чётко укажешь преобразовать значение в строку, например так:

строка(geo_coors_public_regions.name)+строка(geo_coors_public_areas.name)

Не прокатывает (с). Приходится городить код вида:

ВЫБОР
		КОГДА geo_coors_public_regions.name ЕСТЬ NULL
			ТОГДА ""
		ИНАЧЕ geo_coors_public_regions.name
	КОНЕЦ + "," + ВЫБОР
		КОГДА geo_coors_public_areas.name ЕСТЬ NULL
			ТОГДА ""
		ИНАЧЕ geo_coors_public_areas.name
	КОНЕЦ + "," + ВЫБОР
		КОГДА geo_coors_public_cities.name ЕСТЬ NULL
			ТОГДА ""
		ИНАЧЕ geo_coors_public_cities.name
	КОНЕЦ + "," + ВЫБОР
		КОГДА geo_coors_public_settlers.name ЕСТЬ NULL
			ТОГДА ""
		ИНАЧЕ geo_coors_public_settlers.name
	КОНЕЦ
ИЗ
...

1С: Получить название и код региона по почтовому индексу

Может пригодится кому, если у кого как у меня не получается воспользоваться стандартным функционалом БСП:

АдресныйКлассификаторСлужебный.ОпределитьРегионПоИндексу

Лично у меня например конфигурация ругается в 211 строчке, что «Регион.Сокращение» нет такого параметра:

Посему навелосипедил свой вариант:

&НаСервере
Функция ПолучитьРегионПоИндексу(индекс) экспорт	
		Регионы=Новый Массив();
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",01,"Республика Адыгея (Адыгея)","385"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",02,"Республика Башкортостан","450-453"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",03,"Республика Бурятия","670-671"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",04,"Республика Алтай","649"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",05,"Республика Дагестан","367-368"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",06,"Республика Ингушетия","386"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",07,"Кабардино-Балкарская Республика","360-367"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",08,"Республика Калмыкия","358-359"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",09,"Карачаево-Черкесская Республика","369"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",10,"Республика Карелия","185-186"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",11,"Республика Коми","167-169"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",12,"Республика Марий Эл","424-425"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",13,"Республика Мордовия","430-431"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",14,"Республика Саха (Якутия)","677-678"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",15,"Республика Северная Осетия - Алания","362-363"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",16,"Республика Татарстан (Татарстан)","420-423"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",17,"Республика Тыва","667-668"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",18,"Удмуртская Республика","426-427"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",19,"Республика Хакасия","655"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",20,"Чеченская Республика","364-366"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",21,"Чувашская республика - Чувашия","428-429"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",22,"Алтайский край","656-659"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",23,"Краснодарский край","350-354"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",24,"Красноярский край","660-663,647-648"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",25,"Приморский край","690-692"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",26,"Ставропольский край","355-357"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",27,"Хабаровский край","680-682"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",28,"Амурская область","675-676"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",29,"Архангельская область","163-165"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",30,"Астраханская область","414-416"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",31,"Белгородская область","308-309"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",32,"Брянская область","241-243"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",33,"Владимирская область","600-602"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",34,"Волгоградская область","400-404"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",35,"Вологодская область","160-162"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",36,"Воронежская область","394-397"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",37,"Ивановская область","153-155"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",38,"Иркутская область","664-668,669"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",39,"Калининградская область","236-238"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",40,"Калужская область","248-249"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",41,"Камчатский край","683-684,688"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",42,"Кемеровская область - Кузбасс","650-654"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",43,"Кировская область","610-613"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",44,"Костромская область","156-157"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",45,"Курганская область","640-641"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",46,"Курская область","305-307"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",47,"Ленинградская область","187-188"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",48,"Липецкая область","398-399"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",49,"Магаданская область","685-686"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",50,"Московская область","140-144"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",51,"Мурманская область","183-184"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",52,"Нижегородская область","603-607"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",53,"Новгородская область","173-175"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",54,"Новосибирская область","630-633"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",55,"Омская область","644-646"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",56,"Оренбургская область","460-462"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",57,"Орловская область","302-303"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",58,"Пензенская область","440-442"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",59,"Пермский край","614-619"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",60,"Псковская область","180-182"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",61,"Ростовская область","344-347"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",62,"Рязанская область","390-391"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",63,"Самарская область","443-446"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",64,"Саратовская область","410-413"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",65,"Сахалинская область","693-694"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",66,"Свердловская область","620-624"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",67,"Смоленская область","214-216"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",68,"Тамбовская область","392-393"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",69,"Тверская область","170-172"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",70,"Томская область","634-636"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",71,"Тульская область","300-301"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",72,"Тюменская область","625-627"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",73,"Ульяновская область","432-433"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",74,"Челябинская область","454-457"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",75,"Забайкальский край","672-674,687"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",76,"Ярославская область","150-152"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",77,"Город Москва","101-135"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",78,"Город Санкт-Петербург","190-199"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",79,"Еврейская автономная область","679"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",83,"Ненецкий автономный округ","166"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",86,"Ханты-Мансийский автономный округ - Югра","628"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",87,"Чукотский автономный округ","689"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",89,"Ямало-Ненецкий автономный округ","629"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",90,"Запорожская область",""));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",91,"Республика Крым","295-298"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",92,"Город Севастополь","299"));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",93,"Донецкая Народная Республика",""));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",94,"Луганская Народная Республика",""));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",95,"Херсонская область",""));
		Регионы.Добавить(Новый Структура("Код,Наименование,Диапазоны",99,"Город Байконур","468"));
		ПервыйТриЦифрыИндекса = Число(Лев(Индекс, 3));
		для каждого стр из Регионы цикл
			диапазон=СтрРазделить(стр.Диапазоны,"-");
			если диапазон.Количество()=1 тогда
				дначало=Число(диапазон[0]);
				дконец=Число(диапазон[0]);
			иначе
				дначало=Число(диапазон[0]);
				дконец=Число(диапазон[1]);								
			конецесли;	
			если ПервыйТриЦифрыИндекса>=дначало и  ПервыйТриЦифрыИндекса<=дконец тогда
				возврат стр;
			конецесли;	
		конеццикла;	
		возврат неопределено;
КонецФункции

Тупо, в лоб. Но ничего умнее быстро не придумал

1C: фоновая загрузка большого файла Excel в табличный документ

Задача: загрузить в табличный документ на форме файл большого размера, с индикацией прогресса загрузки с использованием фоновой работы.

Решение: если поддержка фоновой работы в 1С была уже довольно давно, то асинхронная загрузка файлов на сервер появилась лишь начиная с версии 8.3.15.1489 ,Ну тоже уже давно, но руки добрались начать использовать только сейчас, т.к. ранее было не критично — не настолько большие файлы загружал/обрабатывал.

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

индикатор загрузки
индикатор загрузки
индикатор загрузки

На кнопку «Загрузить ЛС» навесим открытие диалогового окна:

	Фильтр = "Файл с лицевыми счетами(*.xlsx)|*.xlsx";
	ПараметрыДиалога = новый ПараметрыДиалогаПомещенияФайлов("Выберите файлы XLSX", Истина, Фильтр);		

А чуть ниже определим обработчики оповещения о ходе загрузки файла на сервер и окончании загрузки файла, которые укажем при вызове процедуры «НачатьПомещениеФайлаНаСервер» (есть еще и «НачатьПомещениеФайловНаСервер»). В итоге код получится такой:

&НаКлиенте
Процедура ЗагрузитьЛС(Команда)
	этаформа.ИндикаторЗагрузкиЛС=0;				
	Фильтр = "Файл с лицевыми счетами(*.xlsx)|*.xlsx";
	ПараметрыДиалога = новый ПараметрыДиалогаПомещенияФайлов("Выберите файлы XLSX", Истина, Фильтр);		
	
	ОповещениеОЗавершении = новый ОписаниеОповещения("ПослеЗагрузкиФайлаЛС", ЭтаФорма);		
	ОповещениеОХодеЗагрузки = новый ОписаниеОповещения("ОповещениеОХодеЗагрузкиЛС", ЭтаФорма);		
	
	Этаформа.Элементы.ПояснениеКЗагрузкеЛС.Заголовок="Перемещаю файл на сервер..";
	НачатьПомещениеФайлаНаСервер(ОповещениеОЗавершении,ОповещениеОХодеЗагрузки,,,ПараметрыДиалога, УникальныйИдентификатор);								                                                 

КонецПроцедуры

&НаКлиенте
Процедура ПослеЗагрузкиФайлаЛС (ОписаниеФайла, ДопПараметры) Экспорт
	Этаформа.Элементы.ПояснениеКЗагрузкеЛС.Заголовок="Файл загружен, обрабатываю..";
	этаформа.ИндикаторЗагрузкиЛС=0;				
КонецПроцедуры	

&НаКлиенте
Процедура ОповещениеОХодеЗагрузкиЛС (ПомещаемыйФайл, Помещено, ОтказОтПомещенияФайла,ДополнительныеПараметры) Экспорт
	этаформа.ИндикаторЗагрузкиЛС=Помещено;				
КонецПроцедуры	

В результате чего после выбора файла, по экрану побежит индикатор хода перемещения файла на сервер. Далее этот файл необходимо будет обработать на сервере фоново. И тут возникает один нюанс: мы не можем передать в фоновое задание ссылку на перемещенный файл во временном хранилище.Точнее можем, но фоновое задание это хранилище прочитать не может (это то ли глюк, то ли фича платформы — не понятно). Проблема.. Тогда делаем финт ушами: перед уходом в «фон», мы создадим временный файл во временной папке пользователя 1С, и передадим в фон уже не ссылку на него, а непосредственно имя временного файла. Для этого я просто написал функцию, которая на входе получает адрес загруженного файла, а на выходе даёт имя временного файла:

&НаСервере
Функция СохранитьФайлНаСервере(АдресВременногоХранилища,расш)
		ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
	    ИмяВременногоФайлаХар = ПолучитьИмяВременногоФайла(расш);
	    ДвоичныеДанные.Записать(ИмяВременногоФайлаХар); 
		возврат ИмяВременногоФайлаХар;	
КонецФункции

Кроме того, чтобы мы могли передать результат в обработку по завершению фоновой работы, нам необходимо при запуске фонового задания передать в него некоторые параметры, а именно:

  • имя созданного временного файла
  • колонки/строки откуда брать данные из эксель файла
  • адрес временного хранилища, куда поместить результат работы фонового задания
&НаКлиенте
Процедура ПослеЗагрузкиФайлаЛС (ОписаниеФайла, ДопПараметры) Экспорт
	Этаформа.Элементы.ПояснениеКЗагрузкеЛС.Заголовок="Файл загружен, обрабатываю..";
	этаформа.ИндикаторЗагрузкиЛС=0;				
	инф=Новый Структура("ВременныйФайл,Расширение,ЛС_начало,ЛС_лс,ЛС_то,ЛС_дата_установки_пу,АдресВременногХранилища");
	инф.ВременныйФайл=СохранитьФайлНаСервере(ОписаниеФайла.адрес,ОписаниеФайла.ссылканафайл.расширение);
	инф.Расширение=ОписаниеФайла.ссылканафайл.расширение;
	инф.ЛС_начало=объект.ЛС_начало;
	инф.ЛС_лс=объект.ЛС_лс;
	инф.ЛС_то=объект.ЛС_то;
	инф.ЛС_дата_установки_пу=объект.ЛС_дата_установки_пу;
	инф.АдресВременногХранилища=объект.ВрХранилищеФормы;	
КонецПроцедуры	

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	объект.ВрХранилищеФормы=ПоместитьВоВременноеХранилище(0);
	ЗапуститьФЗЗагрузкиЛС(инф);	
ПодключитьОбработчикОжидания("ИндикаторВыполненияЗагрузкиФайловЛС",1,ложь);				
КонецПроцедуры

Функция которая будет работать фоново, должна размещаться в общем модуле. Это небольшой недостаток внешних обработок — фоново запускаются только процедуры-функции созданные внутри конфигурации. Но! до этого нам нужно опять же написать «обвязку» фонового задания, дабы мы имели возможность знать, работает или нет оно, а так-же на каком этапе. При запуске фонового задания, мы получаем идентификатор этого задания:

	Функция ЗапуститьФЗЗагрузкиЛС(Параметры)		
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить(Параметры);
	ФЗ = ФоновыеЗадания.Выполнить("СК_ГР_ДлительныеОперации.ЗагрузитьФайлыЛС",МассивПараметров);	
	объект.ЛС_ФЗ = ФЗ.УникальныйИдентификатор;					
КонецФункции  

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

&НаКлиенте
Процедура ИндикаторВыполненияЗагрузкиФайловЛС() Экспорт  
	пр=КакДелаУФЗЗагрузкиФайловЛС();   	
	если пр=неопределено тогда  
		этаформа.ИндикаторЗагрузкиЛС=100;
		ОтключитьОбработчикОжидания("ИндикаторВыполненияЗагрузкиФайловЛС");
		Этаформа.Элементы.ПояснениеКЗагрузкеЛС.Заголовок="Файлы обработаны";
	иначе
		этаформа.ИндикаторЗагрузкиЛС=пр;         		
	конецесли;
КонецПроцедуры	 
&НаСервере
Функция КакДелаУФЗЗагрузкиФайловЛС()
	ФЗ = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(объект.идФЗ);
	если ФЗ=Неопределено тогда		
		возврат неопределено;
	иначе	                                                                                                    
		если ФЗ.Состояние=СостояниеФоновогоЗадания.Завершено тогда
			возврат неопределено;
		конецесли;	   
		если ФЗ.Состояние=СостояниеФоновогоЗадания.ЗавершеноАварийно тогда
			Сообщить("Ошибка:"+ФЗ.ИнформацияОбОшибке.Описание);
			возврат неопределено;
		конецесли;										
	конецесли;	
	возврат 0;
конецфункции

Как видим, тут отслеживается состояние фонового задания (запущен, работает, завершен, завершен с ошибкой), но не отслеживается этап выполнения работ. Есть на самом деле два способа получения хода работы фонового задания:

  • перехват вывода функции Сообщить() на сервере, и парсинг данных из него. Например в фоновом задании можно с какой-то периодичностью выводить что-то вроде: Сообщить(«12.3%загружаю»);, а получив на клиенте эту запись показывать индикацию 12.3% и соответствующее пояснение.
  • Можно во время работы фонового задания ложить данные во временно хранилище, и читать их из клиента. НО! данный способ работает только в случай файловой БД. Циатата из справки 1С: «Данные, помещенные во временное хранилище в фоновом задании, не будут доступны из родительского сеанса до момента завершения фонового задания»

Посему остаётся таки отлавливать сообщения сервера по известному идентификатору фонового задания:

&НаСервере
Функция ПолучитьСообщенияФЗ(ФЗ, Состояние = Неопределено, УдалятьСообщения = Ложь) Экспорт
	Если Состояние = Неопределено Тогда
		Состояние = ФЗ.Состояние;
	КонецЕсли;
	МассивСообщений = Новый Массив;
	Сообщения = ФЗ.ПолучитьСообщенияПользователю(УдалятьСообщения);
	Если Сообщения <> Неопределено Тогда
		Для Каждого Сообщение Из Сообщения Цикл
			МассивСообщений.Добавить(Сообщение.Текст);
		КонецЦикла;
	КонецЕсли;
	Возврат МассивСообщений;
КонецФункции

А в самом фоновом здании, городить огород с выводом сообщений:

// На входе:
//	парам.ВременныйФайл
//	парам.Расширение
//	парам.ЛС_начало
//	парам.ЛС_лс
//	парам.ЛС_то
//	парам.ЛС_дата_установки_пу
//	парам.АдресВременногХранилища
Функция ЗагрузитьФайлыЛСРасширенно(парам) экспорт    
	Сообщить("0%читаю файл на сервере");
	ТабличныйДокументХар = Новый ТабличныйДокумент; 
	ТабличныйДокументХар.Прочитать(парам.ВременныйФайл,СпособЧтенияЗначенийТабличногоДокумента.Значение);
	стар=0;
	Для Каждого ОбластьТД ИЗ ТабличныйДокументХар.Области Цикл         		     
	    ОбластьФайла = ТабличныйДокументХар.ПолучитьОбласть(ОбластьТД.Имя);
	    КолВоСтрокФайла = ОбластьФайла.ПолучитьРазмерОбластиДанныхПоВертикали();
	    КолВоКолонокФайла = ОбластьФайла.ПолучитьРазмерОбластиДанныхПоГоризонтали();

		НачСтрока=парам.ЛС_начало;КонСтрока=0;
	    НачСтрока = ?(НачСтрока = 0, 2, НачСтрока);
	    КонСтрока = ?(КонСтрока = 0, КолвоСтрокФайла, КонСтрока);
					
		//перебираем все строки без первой строки            
		Для нСтрокаТФ = НачСтрока ПО КонСтрока Цикл      				
			если стар<>Окр(нСтрокаТФ*100/КонСтрока) тогда
				Сообщить(Строка(Окр(нСтрокаТФ*100/КонСтрока))+"%обрабатываю файл");
				стар=Окр(нСтрокаТФ*100/КонСтрока);
			конецесли;				
		конеццикла;		
	конеццикла						
конецфункции	

Посему модифицируем и обработчик ожидания, добавив парсинг сообщений сервера:

&НаКлиенте
Процедура ИндикаторВыполненияЗагрузкиФайловЛС() Экспорт  
	пр=КакДелаУФЗЗагрузкиФайловЛС();   	
	если пр=неопределено тогда  
		этаформа.ИндикаторЗагрузкиЛС=100;
		ОтключитьОбработчикОжидания("ИндикаторВыполненияЗагрузкиФайловЛС");
		Этаформа.Элементы.ПояснениеКЗагрузкеЛС.Заголовок="Файлы обработаны";
	иначе  
		если пр.Количество()>0 тогда
			этаформа.ИндикаторЗагрузкиЛС=пр[0];         		
			Этаформа.Элементы.ПояснениеКЗагрузкеЛС.Заголовок=пр[1];         		
		конецесли;
	конецесли;
КонецПроцедуры	 
&НаСервере
Функция КакДелаУФЗЗагрузкиФайловЛС()
	ФЗ = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(объект.ЛС_ФЗ);
	если ФЗ=Неопределено тогда		
		возврат неопределено;      
	иначе	                                                                                                    
		если ФЗ.Состояние=СостояниеФоновогоЗадания.Завершено тогда
			возврат неопределено;
		конецесли;	   
		если ФЗ.Состояние=СостояниеФоновогоЗадания.ЗавершеноАварийно тогда
			Сообщить("Ошибка:"+ФЗ.ИнформацияОбОшибке.Описание);
			возврат неопределено;
		конецесли;										
		ФСообщения=СК_ГР_ДлительныеОперации.ПолучитьСообщенияФЗ(ФЗ,,истина);
		Если ФСообщения.Количество() > 0 Тогда                  
			Для Каждого Сообщение Из ФСообщения Цикл				
				Если СтрНайти(Сообщение,"%")>0 тогда
					возврат СтрРазделить(Сообщение,"%");
				конецесли;	
			КонецЦикла;
		КонецЕсли;			
		
	конецесли;	
	возврат Новый Массив();                    
конецфункции

1С: работа с регистром «АдресныйОбъект»

Намедни прилетела интересная задача: создать визуальный построитель адреса доставки счёта клиента согласно данным ФИАС в древней не обновляемой конфигурации 1С. Первоначально подумал покопать в сторону сервиса https://fias-public-service.nalog.ru/api/spas/v2.0/swagger/index.html, написал заявку на генерацию ключа API для доступа, отправил её на указанную электронную почту…и тишина. Тащить самому адреса ФИАС и файлов и создавать для этого обвязку в конфигурараторе — трудоёмко. Но неожиданно возникла идея — а есть же обновляемая регулярно конфигурация 1С «Бухгалтерия», где этот справочник вполне используется и регулярно обновляется. Следовательно мы можем просто создать..ну например WEB сервис, при помощи которого будем тянуть данные для построения адреса из Бухгалтерии. Можно данные тянуть из регистров АдресныйОбъект, ДополнительныеАдресныеСведения, ИерархияАдресов и т.д, а можно покопать БСП, найти все нужные функции. За сим и оформил сервис:

&НаСервере
Функция ПолучитьПрокси()	
	Определение = Новый WSОпределения(
							Константы.СК_БУХURLВебСервиса.Получить(),
							Константы.СК_БУХИмяПользователя.Получить(),
							Константы.СК_БУХПароль.Получить()
							//,ИнтернетПрокси
						);
    
    Прокси = Новый WSПрокси(
						Определение,
						Константы.СК_БУХURIПространстваИмен.Получить(),
						"sk_SOAP_Services",
						"sk_SOAP_ServicesSoap"
						);
	Прокси.Пользователь = Константы.СК_БУХИмяПользователя.Получить();
	Прокси.Пароль = Константы.СК_БУХПароль.Получить();
	
	Возврат Прокси;
КонецФункции

Функция sk_gr_fias_exchange(request, params)  
	params=JSONВСтруктуру(params);
	МассивДляВозврата=Новый Массив();
	if (request="GetAdresses") тогда       
		//Parent,Level,TypeAddress,Counts,Poz,FindStr
		ДополнительныеПараметры=Новый Структура("КоличествоЗаписей,Позиция,СтрокаПоиска",params.Counts,params.Poz,params.FindStr);
		ТЗ=АдресныйКлассификаторСлужебный.АдресаДляИнтерактивногоВыбора(Новый УникальныйИдентификатор(params.Parent), params.Level, params.TypeAddress, ДополнительныеПараметры);		
		МассивДляВозврата=Новый Массив();
		для каждого стр из ТЗ.Данные цикл
			инф=Новый Структура("Идентификатор,Представление",Строка(стр.Идентификатор),Строка(стр.Представление));
			МассивДляВозврата.Добавить(инф);	
		конеццикла;					
	конецесли;	
	if (request="GetHomes") тогда       	
		ТЗ=АдресныйКлассификаторСлужебный.СписокДомов(Новый УникальныйИдентификатор(params.Parent),params.FindStr,params.Counts);		
		МассивДляВозврата=Новый Массив();
		для каждого стр из ТЗ цикл
			инф=Новый Структура("Идентификатор,Представление,Индекс",Строка(стр.Идентификатор),Строка(стр.Представление),Строка(стр.Значение.Индекс));
			МассивДляВозврата.Добавить(инф);	
		конеццикла;						
	конецесли;	
	
	Возврат СтруктураВСтрокуJSON(МассивДляВозврата);
КонецФункции

На целевой конфигурации, остаётся только дергать вызовы:

&НаСервере                                                  
Функция ПолучитьСписокАдресов(Родитель,Уровень)
// Уровень: 1- регион,2 - район, 3 - муниципальный район, 4-поселение, 5-город, 6 -нс, 7 - территория, 8 - улица
		Прокси=ПолучитьПрокси();		
			params=Новый Структура("Parent,Level,TypeAddress,Counts,Poz,FindStr");
			params.Parent=Строка(Родитель);
			params.Level=Уровень;
			params.TypeAddress="Административно-территориальный";
			params.Counts=500;
			params.FindStr="";
			Результат=Прокси.sk_gr_fias_exchange("GetAdresses",СтруктураВСтрокуJSON(params)); 
			//сообщить(Результат);
		возврат JSONВСтруктуру(Результат);

КонецФункции
&НаСервере                                                  
Функция ПолучитьСписокДомов(Родитель)
		Прокси=ПолучитьПрокси();		
			params=Новый Структура("Parent,Level,TypeAddress,Counts,Poz,FindStr");
			params.Parent=Строка(Родитель);
			params.Counts=500;
			params.FindStr="";
			Результат=Прокси.sk_gr_fias_exchange("GetHomes",СтруктураВСтрокуJSON(params)); 
			//сообщить(Результат);
		возврат JSONВСтруктуру(Результат);	
КонецФункции

И визуализировать всё подобным образом:

1 4 5 6 7 8 50