Вход | Регистрация

1С:Предприятие ::

Метки:

Результаты тестов по Серийникам: Справочник vs Документы

Я
   Львенок
 
16.02.04 - 17:59
Выполняю обещания данные на http://www.forum.mista.ru/topic.php?forum=1c&id=1561

На самом деле мне лень приводить результаты всех тестов (а я проделал три вещи Запрос к документам, запрос к справочнику, метод НайтиПоРеквизиту в справочнике), скажу лишь, что Рупор оказался прав. Запрос к документам обеспечивает должную производительность и удобство. Остановлюсь только на этом тесте.
Итак в тестовой базе создавался справочник Номенклатура (Только код и наименование) и Документ ГарантийныйТалон с полями в табличной части Номенклатуру (Справочник.Номенклатура), Серийник1 (Строка 20), Серийник2 (Строка 20), Серийник3 (Строка 20), Гарантия (Число 2.0). Ручками занес десять позиций номенклатуры. Программно создал 28000 (хотел 100000 но не дождался) документов в разных датах, с произвольным числом строчек внутри, с произвольными товарами внутри и случайными серийниками. Обработка такая:

Перем Случай;
Функция Ранд(Парам=0)
    Если Парам<>0 Тогда
        Случай=Парам;
    КонецЕсли;
    Если Число(Случай)=0 Тогда
        Случай=Число(СтрЗаменить(""+ТекущееВремя(),":",""));
        Случай=(16807*Случай)%2147483647;
    КонецЕсли;
    Случай=(16807*Случай)%2147483647;
    Случай=макс(Случай,-Случай);
    Возврат(Случай/2147483647);
КонецФункции

Процедура Выполнить()
    Док=СоздатьОбъект("Документ.ГарантийныйТалон");
    Спр=СоздатьОбъект("Справочник.Номенклатура");
    Дата1='08.01.01';
    Для К=1 по 100000 Цикл
        Если Цел(Ранд()*20)=15 Тогда Дата1=Дата1+1; КонецЕсли;
        Док.Новый(); Док.ДатаДок=Дата1;
        
        О=10+Цел(Ранд()*10);
        Для Н=1 По О Цикл
            Док.НоваяСтрока();
            М=10+Цел(Ранд()*10); Сер="";
            Для Л=1 По М Цикл
                Сер=Сер+Цел(Ранд()*10);
            КонецЦикла;
            М=10+Цел(Ранд()*10); Сер1="";
            Для Л=1 По М Цикл
                Сер1=Сер1+Цел(Ранд()*10);
            КонецЦикла;  
            М=10+Цел(Ранд()*10); Сер2="";
            Для Л=1 По М Цикл
                Сер2=Сер2+Цел(Ранд()*10);
            КонецЦикла;
                                                 
            Спр.НайтиПоКоду((1+Цел(Ранд()*10)));
            Док.Гарантия=1+Цел(Ранд()*24);
            Док.Серийник1=Сер;
            Док.Серийник2=Сер1;
            Док.Серийник3=Сер2;
            Док.Номенклатура=Спр.ТекущийЭлемент();
        КонецЦикла;  
        Док.Записать();
    КонецЦикла;
КонецПроцедуры

Зачем три реквизита Серийник? Просто на товарах бывает наклеено много лэйблов спразу и трудно понять что есть штрих-код товара, партии, а что его уникальный С/Н. Решили забивать все, какие найдутся, если не уверен.

Итого 28000 документов, разбросанных в периоде 3-года, в среднем по 15 строк в каждом.

Далее написал отчет. На форме стандартный выбор периода, который по умолчания не заполняется (а значит в запросе будет поиск по всей базе), И поля ввода ВыбНоменклатура (Справочник.Номенклатура), ВыбСерийник1 (Строка 20), ВыбСерийник2 (Строка 20), ВыбСерийник3 (Строка 20). Модуль отчета такой:

Процедура Сформировать()
    Перем Запрос, ТекстЗапроса, Таб;
    
    СписСер=СоздатьОбъект("СписокЗначений");
    Если СокрЛП(ВыбСерийник1)>"" Тогда
        СписСер.ДобавитьЗначение(ВыбСерийник1);
    КонецЕсли;
    Если СокрЛП(ВыбСерийник2)>"" Тогда
        СписСер.ДобавитьЗначение(ВыбСерийник2);
    КонецЕсли;
    Если СокрЛП(ВыбСерийник3)>"" Тогда
        СписСер.ДобавитьЗначение(ВыбСерийник3);
    КонецЕсли;
    
   //Создание объекта типа Запрос

    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса = 
    "//{{ЗАПРОС(Сформировать)

    |Период с НачДата по КонДата;
    |Обрабатывать НеПомеченныеНаУдаление;
    |Без итогов;
    |ГарантийныйТалон = Документ.ГарантийныйТалон.ТекущийДокумент;
    |Номенклатура = Документ.ГарантийныйТалон.Номенклатура;
    |Серийник1 = Документ.ГарантийныйТалон.Серийник1;
    |Серийник2 = Документ.ГарантийныйТалон.Серийник2;
    |Серийник3 = Документ.ГарантийныйТалон.Серийник3;
    |Гарантия = Документ.ГарантийныйТалон.Гарантия;
    |Группировка ГарантийныйТалон;
    |Группировка Номенклатура;
    |Условие((Серийник1 в СписСер) ИЛИ (Серийник2 в СписСер) ИЛИ (Серийник3 в СписСер));
    |Условие(Номенклатура в ВыбНом);
    |//}}ЗАПРОС

    ;
   // Если ошибка в запросе, то выход из процедуры

    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
        Возврат;
    КонецЕсли;

   // Подготовка к заполнению выходных форм данными запроса

    Таб = СоздатьОбъект("Таблица");
    Таб.ИсходнаяТаблица("Сформировать");
   // Заполнение полей "Заголовок"

    Таб.ВывестиСекцию("Заголовок");
    Состояние("Заполнение выходной таблицы...");
    Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);
    Пока Запрос.Группировка() = 1 Цикл
       // Заполнение полей Сформировать

        Таб.ВывестиСекцию("Сформировать");
    КонецЦикла;                           
    Таб.ВывестиСекцию("Подвал");
   // Вывод заполненной формы

    Таб.ТолькоПросмотр(1);
    Таб.Показать("Сформировать", "");
КонецПроцедуры

Таблица примерно такая:
Шапка (Все является текстом):                        
   ГарантийныйТалон    Дата    Номенклатура    S/N №1    S/N №2    S/N №3    Гарантия    До
Сформировать (Все является Выражениями):

   Запрос.ГарантийныйТалон    Запрос.ГарантийныйТалон.ДатаДок    Запрос.ЗначениеУпорядочивания(2)    Запрос.Серийник1    Запрос.Серийник2    Запрос.Серийник3    Запрос.Гарантия    ДобавитьМесяц(Запрос.ГарантийныйТалон.ДатаДок,Запрос.Гарантия)
                   
Так вот поиск любого серийника по все базе в пределах 10-20 секунд на Athlon 2000 XP.

Подводные камни - не может быть пустых серийников в документах. Если в какой-то строке документа поле серийник не заполнено, эта строка в любом случае попадает в отчет (особенность оператора "в"), поэтому при записи документа ГарантийныйТалон все незаполненные Серийник1, Серийник2, Серийник3, предлагаю заменять автоматом не слово "нет".
___
Искренне Ваш, Львенок.
 
  Рекламное место пустует
   Bzzzzz
 
1 - 16.02.04 - 18:10
Спб, будем знать.
А ты пробывал искать в справочнике не запросом, а просто в форме списка набирая серийку (для 3-х конечно это не пропрет) в соответствующем столбце?


Список тем форума
Рекламное место пустует   Рекламное место пустует
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство.
Фредерик Брукс-младший
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует