8.х Помогите оптимизировать обработку

Тема в разделе "Отчеты и обработки для "1С:Предприятие 8"", создана пользователем sgirg, 1 окт 2010.

  1. TopicStarter Overlay
    sgirg
    Offline

    sgirg Опытный в 1С

    Регистрация:
    25 дек 2008
    Сообщения:
    126
    Симпатии:
    0
    Баллы:
    26
    Требуется оптимизировать обработку в сторону увеличения быстродействия.
    Код:
    Процедура ОсновныеСредства() Экспорт;
    
    Выборка = Справочники.ОсновныеСредства.Выбрать();
    Пока Выборка.Следующий() Цикл
    
    Состояние("Обрабатывается объект справочника ""Основные средства"" " + Выборка);
    
    Код = Выборка.Код;
    СсылкаОсновныеСредства = Справочники.ОсновныеСредства.НайтиПоКоду(Код);
    
    Если СсылкаОсновныеСредства = Неопределено Тогда 
    Возврат
    
    КонецЕсли;
    
    МассивСсылок = Новый Массив;
    МассивСсылок.Добавить(СсылкаОсновныеСредства);
    
    Ссылка = НайтиПоСсылкам(МассивСсылок);
    
    Если Ссылка.Количество() = 0 Тогда 
    
    Если Выборка.ПометкаУдаления = Истина Тогда
    
    Сообщить("Справочник ""Основные средства"" " + Строка(Код) + " " + Выборка + "   !!! Объект помечен на удаление", СтатусСообщения.Внимание);
    
    Иначе
    
    Сообщить("Справочник ""Основные средства"" " + Строка(Код) + " " + Выборка, СтатусСообщения.Информация);	
    
    КонецЕсли;	
    
    КонецЕсли;
    
    КонецЦикла;		
    
    КонецПроцедуры
    
    
    Львиную долю занимает НайтиПоСсылкам, под 90% времени работы обработки
  2. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Ммм... Вот это у вас что:
    Код:
    Код = Выборка.Код;
    СсылкаОсновныеСредства = Справочники.ОсновныеСредства.НайтиПоКоду(Код);
    
    Если СсылкаОсновныеСредства = Неопределено Тогда 
    Возврат
    
    КонецЕсли;
    
    
    
    
    
    
    ?

    Вобщем для начала как-то так:
    Код:
    Процедура ОсновныеСредства() Экспорт;
    
    МассивСсылок = Новый Массив;
    Выборка = Справочники.ОсновныеСредства.Выбрать();
    Пока Выборка.Следующий() Цикл
    Состояние("Обрабатывается объект справочника ""Основные средства"" " + Строка(Выборка));
    МассивСсылок.Добавить(Выборка.Ссылка);
    КонецЦикла;        
    
    ТабСсылок = НайтиПоСсылкам(МассивСсылок);
    
    Для Каждого Ссылка из ТабСсылок Цикл
    Сообщить("" + "Справочник ""Основные средства""" + Строка(Ссылка[0].Код));
    КонецЦикла;
    КонецПроцедуры        
    
    
    
    писал прям здесь, поэтому оно может не заработать, а если заработает - то не так как вы хотите. Вы конечный результат напишите, что оно должно делать?
  3. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Ну там насколько я понимаю, после строки
    Код:
    ТабСсылок = НайтиПоСсылкам(МассивСсылок);
    
    надо будет добавить в ТабСсылок колонку.
    Потом в цикле проходите по строкам ТабСсылок, и если Ссылка[1] не равно "Неопределено", записываете во вновь добавленый столбец 1, иначе 0.
    Потом сворачиваете ТабСсылок, по 1-му столбцу (суммируете по вновь добавленому).
    И вот в этом цикле:
    Код:
    Для Каждого Ссылка из ТабСсылок Цикл
    Сообщить("" + "Справочник ""Основные средства""" + Строка(Ссылка[0].Код));
    КонецЦикла;
    
    уже смотрите, если сума во вновь добавленном столбце > 0 значит ссылки на Объект были, выводите код, признак пометку удаления. Если = 0, то значит не было, ну тоже пишите чтовам там надо.
  4. TopicStarter Overlay
    sgirg
    Offline

    sgirg Опытный в 1С

    Регистрация:
    25 дек 2008
    Сообщения:
    126
    Симпатии:
    0
    Баллы:
    26
    Код:
    Код = Выборка.Код;  //Беру из справочника код
    
    СсылкаОсновныеСредства = Справочники.ОсновныеСредства.НайтиПоКоду(Код);
    //Ухожу от типа "СправочникВыборка" к типу "СправочникСсылка", чтоб в дальнейшем использовать вот здесь:
    НайтиПоСсылкам(МассивСсылок)
    
    Если СсылкаОсновныеСредства = Неопределено Тогда     //записки сумасшедшего))
    Возврат    
    КонецЕсли;
    
    
  5. GRFru
    Offline

    GRFru Опытный в 1С

    Регистрация:
    22 июл 2008
    Сообщения:
    54
    Симпатии:
    0
    Баллы:
    26
    Начало как у shurikvz
    Код:
    Процедура ОсновныеСредства() Экспорт;
    
    МассивСсылок = Новый Массив;
    Выборка = Справочники.ОсновныеСредства.Выбрать();
    Пока Выборка.Следующий() Цикл
    Состояние("Обрабатывается объект справочника ""Основные средства"" " + Строка(Выборка));
    МассивСсылок.Добавить(Выборка.Ссылка);
    КонецЦикла;        
    
    ТабСсылок = НайтиПоСсылкам(МассивСсылок);
    
    Выборка = Справочники.ОсновныеСредства.Выбрать();
    Пока Выборка.Следующий() Цикл
    НайденныйЭлемент = ТабСсылок.Найти(Выборка);
    Если НайденныйЭлемент = Неопределено Тогда 
    Если Выборка.ПометкаУдаления = Истина Тогда
    Сообщить("Справочник ""Основные средства"" " + Строка(Код) + " " + Выборка + "   !!! Объект помечен на удаление", СтатусСообщения.Внимание);
    
    Иначе
    
    Сообщить("Справочник ""Основные средства"" " + Строка(Код) + " " + Выборка, СтатусСообщения.Информация);	
    
    КонецЕсли;
    КонецЕсли;
    КонецЦикла;
    КонецПроцедуры
    
    Ни знаю на сколько быстрее, но хотя бы каждый раз не будет искать в цикле ссылку.
  6. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    GRFru, небольшие поправки:
    Код:
    НайденныйЭлемент = ТабСсылок.Найти(Выборка);
    
    так не заработает. Во-первых "Выборка.Ссылка", во вторых, там должно по хорошему быть как бы 2 аргумента (2-й наименование столбца) (хотя можно и так оставить, поиск по всей таблице тогда идти будет), ну и в-третьих (самое главное) я не смотрел что возвращает функция "НайтиПоСсылкам", но если она возращает в 1-м столбце массив всех переданных ссылок, а во втором при отсутствие ссылки, просто Неопределено, то тогда ваш код не сработает (по скольку Выборка.Ссылка будет найдена в любом случае), ну а если возвращает только те элементы, на которые есть ссылка, тогда да, можно. (Тогда и мой последний пост можно чуть переделать: не добавлять дополнительное поле, 0 и 1, а просто сразу свернуть по первому столбцу).

    SGIRG в любом случае НайтиПоСсылкам будет занимать больше всего времени.
  7. GRFru
    Offline

    GRFru Опытный в 1С

    Регистрация:
    22 июл 2008
    Сообщения:
    54
    Симпатии:
    0
    Баллы:
    26
    Вот так надо по идее
    Код:
    НайденныйЭлемент = ТабСсылок.Найти(Выборка.Ссылка, "Ссылка");
    
    Посмотрел что возвращает НайтиПоСсылкам.
    Если ничего не найдено, то возвращает пустую таблицу значений.
  8. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Это если вообще ничего не найдено? А если передать массив ссылок, для одних есть для других ничего нет, в ТЗ, те ссылки для которых ничего не найдено возвращаются?
  9. TopicStarter Overlay
    sgirg
    Offline

    sgirg Опытный в 1С

    Регистрация:
    25 дек 2008
    Сообщения:
    126
    Симпатии:
    0
    Баллы:
    26
    GRFru
    shurikvz
    Спасибо вам огромное

    Код:
    НайденныйЭлемент = ТабСсылок.Найти(Выборка.Ссылка, "Ссылка");
    
    то, что надо))
    я этой обработкой проверял несколько справочников... не только ОС... И, к примеру, обработка справочника "Номенклатура" сократилась с 2 минут 30 секунд до 10 секунд!
  10. TopicStarter Overlay
    sgirg
    Offline

    sgirg Опытный в 1С

    Регистрация:
    25 дек 2008
    Сообщения:
    126
    Симпатии:
    0
    Баллы:
    26
    Код:
    Выборка = Справочники.Номенклатура.Выбрать();    
    Пока Выборка.Следующий() Цикл    
    
    НайденныйЭлемент = ТабСсылок.Найти(Выборка.Ссылка, "Ссылка");        
    Если  НайденныйЭлемент = Неопределено Тогда      
    
    
    Что то все же в этом коде не совсем гуд...
    на обработку справочника с 500 позициями уходит 6-8 секунд, а на обработку справочника с 13000 позициями далеко больше часа (примерно столько же, что и мой самый первый вариант...)
    И, как я понял по служебным сообщениям, выдаваемым при работе обработки, НайтиПоСсылкам(МассивСсылок) работает с достаточно терпимой скоростью... и много времени также ушло на поиск из ТабСсылок...
    В понедельник приду на работу и сделаю замер производительности для полной уверенности...
  11. Itsys
    Offline

    Itsys Опытный в 1С

    Регистрация:
    3 янв 2010
    Сообщения:
    1.394
    Симпатии:
    0
    Баллы:
    26
    Может быть проще для увеличения производительности попробовать сделать большой запрос, в котором учесть все возможные связи (если требуется обработка конкретного справочника)
    Это будет работать быстрее, в результате запроса сразу можно отобрать только объекты на которые нет ссылок, обработка будет производиться на сервере, что тоже добавит производительности, но для каждого объекта надо писать свой запрос.

    ЗЫ Хотя если сильно подумать и пробежаться по метаданным, то можно и запрос составить автоматически.
  12. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
  13. baskar12
    Offline

    baskar12

    Регистрация:
    2 ноя 2010
    Сообщения:
    3
    Симпатии:
    0
    Баллы:
    1
    Используй инталевскую аналитику для 1С. И не нужно будет парится с оптимизацией кода в большиенстве случаев, ибо эта приблуда ускоряет построение отчетов в разы! И гланове есть беслптаная версия без ограничений по времени.

    См. http://ka.intalev.ru

Поделиться этой страницей