Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
22 ноя 2024, 11:10

Подскажите как можно оптимизировать код?

Автор Yamuna, 16 июн 2019, 10:48

0 Пользователей и 1 гость просматривают эту тему.

Yamuna

Запросом получаем данные и потом их обрабатываем и если много уже записей в справочнике,то долго записывает, пока там все проверки пройдет, подскажите как можно оптимизировать код.
Процедура ПроверяемПереходНаВторойУровень()


Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(Спр.Ссылка) КАК КолПодчиненных,
| Спр.Родитель КАК Ссылка
|ПОМЕСТИТЬ Таб1
|ИЗ
| Справочник.УчастникиПервогоУровня КАК Спр
|ГДЕ
| НЕ Спр.ПометкаУдаления
| И НЕ Спр.Родитель = ЗНАЧЕНИЕ(Справочник.УчастникиПервогоУровня.ПустаяСсылка)
|
|СГРУППИРОВАТЬ ПО
| Спр.Родитель
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Таб1.КолПодчиненных КАК КолПодчиненных,
| Таб1.Ссылка КАК Ссылка
|ПОМЕСТИТЬ Таб2
|ИЗ
| Таб1 КАК Таб1
|ГДЕ
| Таб1.КолПодчиненных >= 5
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| КОЛИЧЕСТВО(Спр.Ссылка) КАК КолПодчиненных,
| Спр.Родитель КАК Ссылка
|ИЗ
| Таб2 КАК Таб2
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.УчастникиПервогоУровня КАК Спр
| ПО Таб2.Ссылка = Спр.Ссылка
|ГДЕ
| НЕ Спр.ПометкаУдаления
| И НЕ Спр.Родитель = ЗНАЧЕНИЕ(Справочник.УчастникиПервогоУровня.ПустаяСсылка)
|
|СГРУППИРОВАТЬ ПО
| Спр.Родитель";

РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Для каждого Стр Из РезультатЗапроса Цикл
Если Стр.КолПодчиненных>=5 Тогда
ЭлСсылка = Справочники.УчастникиПервогоУровня.НайтиПоНаименованию(Стр.Ссылка);
СпрОб = ЭлСсылка.ПолучитьОбъект();
Если СпрОб.СтатусУчастника = Перечисления.СтатусУчастника.Активирован Тогда
СпрОб.СтатусУчастника = Перечисления.СтатусУчастника.Уровень2;
СпрОб.Записать();
Сообщить(Строка(Стр.Ссылка)+ " Перешел на 2-ой Уровень");

//Сообщаем директору
СпрСообщениеДиректору = Справочники.СообщениеДиректору.СоздатьЭлемент();
СпрСообщениеДиректору.Наименование = Строка(Стр.Ссылка)+"  на Втором уровне";
СпрСообщениеДиректору.Сообщение  = Строка(Стр.Ссылка)+" - Перешел на Второй Уровень. "+Формат(ТекущаяДата(),"ДЛФ=DD");
СпрСообщениеДиректору.Записать();
КонецЕсли;
ИначеЕсли Стр.КолПодчиненных<5 Тогда
ЭлСсылка = Справочники.УчастникиПервогоУровня.НайтиПоНаименованию(Стр.Ссылка);
СпрОб = ЭлСсылка.ПолучитьОбъект();
Если СпрОб.СтатусУчастника = Перечисления.СтатусУчастника.Уровень2 Тогда
СпрОб.СтатусУчастника = Перечисления.СтатусУчастника.Активирован;
СпрОб.Записать();
Сообщить(Строка(Стр.Ссылка)+ " Ушел на 1-ый");

//Удаляем сообщение при откате
СпрСообщениеДиректору = Справочники.СообщениеДиректору.НайтиПоНаименованию(Строка(Стр.Ссылка)+"  на Втором уровне");
Если ЗначениеЗаполнено(СпрСообщениеДиректору) Тогда
   СообщОб = СпрСообщениеДиректору.ПолучитьОбъект();
   СообщОб.Удалить();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры


bsn-chita


ЭлСсылка = Справочники.УчастникиПервогоУровня.НайтиПоНаименованию(Стр.Ссылка);

Получение Ссылки от Ссылки. У вас в запросе получается Ссылка на элемент справочника, затем в коде вы делаете совершенно лишнее вычисление. Не явно система получаете от Ссылки текстовое представление и потом по этому представлению ищет элемент. А если представить что наименование не обязано быть уникальным, то не ясно как себя будет вести код если это самое наименование будет одинаковым хотя бы у 2 элементов. Уже вам говорили ранее что использовать НайтиПоНаименованию не желательно.

Строка(Стр.Ссылка)

В запросе изначально представление взять чтобы не вычислять от Ссылки.
В транзакцию все обернуть наверное стоит. Меняете или удаляете данные в 2 справочниках. Ну а как красиво реализовать саму логику задачи на 1С даже не представляю.

antoneus

Процедура ПроверяемПереходНаВторойУровень()
   
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Спр.Ссылка) КАК КолПодчиненных,
    |    Спр.Родитель КАК Ссылка
    |ПОМЕСТИТЬ Таб1
    |ИЗ
    |    Справочник.УчастникиПервогоУровня КАК Спр
    |ГДЕ
    |    НЕ Спр.ПометкаУдаления
    |    И Спр.Родитель <> ЗНАЧЕНИЕ(Справочник.УчастникиПервогоУровня.ПустаяСсылка)
    |
    |СГРУППИРОВАТЬ ПО
    |    Спр.Родитель
    |ИМЕЮЩИЕ
    |    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Спр.Ссылка) >= 5
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Спр.Ссылка) КАК КолПодчиненных,
    |    Спр.Родитель КАК Ссылка,
    |    Спр.СтатусУчастника
    |ИЗ
    |    Таб1 КАК Таб1
    |ЛЕВОЕ СОЕДИНЕНИЕ Справочник.УчастникиПервогоУровня КАК Спр
    |    ПО Таб1.Ссылка = Спр.Ссылка
    |ГДЕ
    |    НЕ Спр.ПометкаУдаления
    |    И Спр.Родитель <> ЗНАЧЕНИЕ(Справочник.УчастникиПервогоУровня.ПустаяСсылка)
    |
    |СГРУППИРОВАТЬ ПО
    |    Спр.Родитель,
    |    Спр.СтатусУчастника
    |";
   
    Выборка = Запрос.Выполнить().Выбрать();

    //переменные надо кэшировать
    Активирован = Перечисления.СтатусУчастника.Активирован;
    Уровень2 = Перечисления.СтатусУчастника.Уровень2;
   
    Пока Выборка.Следующий() Цикл
        Если Выборка.КолПодчиненных >= 5 Тогда       
            Если Выборка.СтатусУчастника = Активирован Тогда//только тогда получаем объект
                СпрОб = Выборка.Ссылка.ПолучитьОбъект();
                СпрОб.СтатусУчастника = Уровень2;
                СпрОб.Записать();
                Сообщить(Строка(Выборка.Ссылка)+ " Перешел на 2-ой Уровень");
               
                //Сообщаем директору
                СпрСообщениеДиректору = Справочники.СообщениеДиректору.СоздатьЭлемент();
                СпрСообщениеДиректору.Наименование = Строка(Выборка.Ссылка)+"  на Втором уровне";
                СпрСообщениеДиректору.Сообщение  = Строка(Выборка.Ссылка)+" - Перешел на Второй Уровень. "+Формат(ТекущаяДата(),"ДЛФ=DD");
                СпрСообщениеДиректору.Записать();           
            КонецЕсли;
        Иначе
            Если Выборка.СтатусУчастника = Уровень2 Тогда
                СпрОб = Выборка.Ссылка.ПолучитьОбъект();
                СпрОб.СтатусУчастника = Активирован;
                СпрОб.Записать();
                Сообщить(Строка(Выборка.Ссылка)+ " Ушел на 1-ый");
               
                //Удаляем сообщение при откате
                СпрСообщениеДиректору = Справочники.СообщениеДиректору.НайтиПоНаименованию(Строка(Выборка.Ссылка)+"  на Втором уровне");
                Если ЗначениеЗаполнено(СпрСообщениеДиректору) Тогда
                   СообщОб = СпрСообщениеДиректору.ПолучитьОбъект();
                   СообщОб.Удалить();
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;   
    КонецЦикла;

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

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск