Уже не однократно поднимал в своём блоге вопрос о методе сортировки массива структур по какому то ключу. В конце концов остановился на самом медленном, но зато самом менее трудоёмком методе. Для нескольких тысяч записей пойдет. Для нескольких десятков тысяч записей уже нет, ибо памяти не хватит. Общая методика такова:
Преобразуем массив структур в таблицу значений
Отсортируем штатными средствами таблицу значений по ключевому полю
Далее используем еже не массив структур, а именно таблицу значений, чтобы уменьшить накладные расходы на обратные преобразования
Функция ПреобразованиеМассивВТаблицуЗначений(Массив) экспорт
ТЗ = Новый ТаблицаЗначений;
Для Каждого СтрокаМассива Из Массив Цикл
Если ТЗ.Колонки.Количество() = 0 Тогда
Для Каждого ЭлементМассива Из СтрокаМассива Цикл
ТЗ.Колонки.Добавить(ЭлементМассива.Ключ);
КонецЦикла;
КонецЕсли;
НоваяСтрока = ТЗ.Добавить();
Для Каждого ЭлементМассива Из СтрокаМассива Цикл
НоваяСтрока[ЭлементМассива.Ключ] = ЭлементМассива.Значение;
КонецЦикла;
КонецЦикла;
Возврат ТЗ;
КонецФункции
Использование:
ТЗ_ЛС=ПреобразованиеМассивВТаблицуЗначений(список_лс.result.responseObject);
ТЗ_ЛС.Сортировать("room Возр");
...
для каждого стр из ТЗ_ЛС цикл
....
конеццикла
Перейдя с Windows на Linux, теряется возможность управлять сервером 1С Предприятие через консоль администрирования, через оснастку. Но! оказывается довольно давно уже в платформе зашита подобная же утилита, которая доступна через «Функции для технического специалиста»: Стандартные -> Управление серверами.
При запуске будет практически аналогичная функциональность доступная ранее через консоль:
Задача: распаралелить медленную вставку записей в БД 1С, при чтении файла Excel
Как ни странно, но такая возможность есть и работает начиная с версии платформы 8.3.8. Т.е. можно запустить фоновое задание внутри фонового задания….ну например по вставке в БД большого количества записей, которая выполняется весьма медленно. Полноценно этот процесс распаралелить можно например как-то так:
Функция СделатьЗаписьвБДПДЗФоново(парам) экспорт
...
// делаем медленную запись в БД
...
конецфункции
// Просматриваем массив с идентификаторами фоновых заданий и удаляем те которые завершились
Функция ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий) экспорт
для каждого ФЗМ из МассивФоновыхЗаданий цикл
ФЗ = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ФЗМ);
если ФЗ.Состояние<>СостояниеФоновогоЗадания.Активно тогда
МассивФоновыхЗаданий.Удалить(МассивФоновыхЗаданий.Найти(ФЗМ));
конецесли;
конеццикла;
возврат МассивФоновыхЗаданий;
конецфункции
// выполняем загрузку построчно файла Excel, запуская запись данных в БД
// отдельным потоком. Количество потоков ограничивам 10 штуками
Функция ВыполнитьЗагрузку(парам) экспорт
МассивФоновыхЗаданий=Новый Массив();
МаксимумЗаданий=10;
...
Для нСтрокаТФ = 2 ПО КолВоСтрокФайла Цикл
....
МассивПараметров = Новый Массив;
Параметры=Новый Структура("aa,bb,cc",
1,
2,
3,
);
МассивПараметров.Добавить(Параметры);
ФЗ = ФоновыеЗадания.Выполнить("ДлительныеОперации.СделатьЗаписьвБДПДЗФоново",МассивПараметров);
МассивФоновыхЗаданий.Добавить(ФЗ.УникальныйИдентификатор);
МассивФоновыхЗаданий=ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий);
// ждём пока завершаться запущеные потоки, если их больше 10
пока МассивФоновыхЗаданий.Количество()>МаксимумЗаданий цикл
МассивФоновыхЗаданий=ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий);
конеццикла;
....
конеццикла;
конецфункции
В ниже приведённом каркасе кода, фоново выполняется функция ВыполнитьЗагрузку(), которая читает большой файл Excel, затем каждый цикл вставки записи в БД запускает в свою очередь фоново, ограничивая в данном случае количество фоновых заданий 10 штуками.
Иногда удаётся найти подводные камни там, где совсем не ждешь от 1С. Оказывается в запросах 1С, сложение столбцов а+б даёт в сумме null, если одно из значений равно null. даже если чётко укажешь преобразовать значение в строку, например так:
ВЫБОР
КОГДА 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
КОНЕЦ
ИЗ
...