Имя: Пароль:
1C
1С v8
Оптимизация скорости загрузки из таблицы значений при создании документов
,
0 dborovsky
 
04.06.13
11:39
Добрый день

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


Из нее я сравниваю строки с датой и поставщиком, если совпадает, тогда создаю новый документ прейскурант цен поставщика и загоняю туда товары из совпавших строк. Создал для этого обработку(см. ниже). Она работает, но очень медленно создаются новые документы. 11 документов за 10 мин. С таким успехом 2 суток будут создаваться документы. Как можно оптимизировать обработку, чтобы увеличить скорость?  Подскажите пожалуйста. Заранее спасибо за ответ.
Код привожу ниже:

ТЗДата = тзТекстФайл.Скопировать();
   ТЗДата.Свернуть("Дата");
   
   тзКонтрагентКод = тзТекстФайл.Скопировать();
   тзКонтрагентКод.Свернуть("КонтрагентКод");

сч = 0;
   Для Каждого строкаДата Из ТЗДата Цикл
                       
       Для Каждого строкаКодКонтрагент Из тзКонтрагентКод Цикл
           тзРезультат = ПоискНоменклатуры(строкаДата.Дата, строкаКодКонтрагент.КонтрагентКод, тзТекстФайл);
           Если тзРезультат.Количество() > 0 Тогда
               НовыйДокумент = Документы.ПрейскурантЦенПоставщиков.СоздатьДокумент();
               Попытка
                   НовыйДокумент.Дата = Дата(строкаДата.Дата);
               Исключение
                   Продолжить;
               КонецПопытки;
                                 
               контрагент = Справочники.Контрагенты.НайтиПоКоду(строкаКодКонтрагент.КонтрагентКод);
               Если Не контрагент.Пустая() Тогда
                   НовыйДокумент.Поставщик = контрагент;
               КонецЕсли;
                               
               валюта = Справочники.Валюты.НайтиПоНаименованию(тзРезультат[0].Валюта);
               Если Не валюта.Пустая() Тогда
                   НовыйДокумент.Валюта = валюта;
               КонецЕсли;
               
               НовыйДокумент.Организация = Справочники.Организации.НайтиПоКоду("000000001");
                           
                   
               Для Каждого стр Из тзРезультат Цикл    
                   товар = НовыйДокумент.Товары.Добавить();
                   товар.Товар = Справочники.Номенклатура.НайтиПоКоду(стр.НоменклатураКод);
                   товар.Цена = стр.Цена;    
               КонецЦикла;
               НовыйДокумент.Записать();
               Сообщить("Документ сохранен - "+сч);
               сч = сч + 1;
               
           КонецЕсли;
       КонецЦикла;
   КонецЦикла;
   
   
   Для Каждого текСтрока Из тзТекстФайл Цикл
                   
   КонецЦикла;

Функция ПоискНоменклатуры(парам1, парам2, тз)
   Запрос3 = Новый Запрос;
   МенеджерВТ = Новый МенеджерВременныхТаблиц;
   Запрос3.МенеджерВременныхТаблиц = МенеджерВТ;
   Запрос3.Текст = "ВЫБРАТЬ
                    | Выразить(ТЗ.НоменклатураКод КАК СТРОКА(100)) КАК НоменклатураКод,
                    |  Выразить(ТЗ.Цена КАК ЧИСЛО(10)) КАК Цена,
                    |    Выразить(ТЗ.Валюта КАК СТРОКА(6)) КАК Валюта
                    | ПОМЕСТИТЬ ВТ
                    |ИЗ
                    |    &Данные КАК ТЗ
                    |ГДЕ
                      | Выразить(ТЗ.Дата КАК СТРОКА(100)) = &дата
                    | И Выразить(ТЗ.КонтрагентКод КАК СТРОКА(100)) = &код";
   Запрос3.УстановитьПараметр("Данные", тз);
   Запрос3.УстановитьПараметр("дата", парам1);
   Запрос3.УстановитьПараметр("код", парам2);
   Результат = Запрос3.Выполнить();
   
   Запрос4 = Новый Запрос;
   Запрос4.МенеджерВременныхТаблиц = МенеджерВТ;
   Запрос4.Текст = "ВЫБРАТЬ
                    | ВТ.НоменклатураКод КАК НоменклатураКод,
                    |  ВТ.Цена КАК Цена,
                    |    ВТ.Валюта КАК Валюта
                    |ИЗ
                    |    ВТ";

   Результат = Запрос4.Выполнить().Выгрузить();
   Возврат Результат;
КонецФункции
1 H A D G E H O G s
 
04.06.13
11:45
Разбираться в этом говнокоде?

http://www.youtube.com/watch?v=HcfHBgUTn7I
2 H A D G E H O G s
 
04.06.13
11:46
Мне вот просто интересно, Откуда у человека приходят такие мысли, что они реализуются вот вот в это (0)?
3 H A D G E H O G s
 
04.06.13
11:47
Ладно там сложная система, не все можно спрогнозировать и ТЗ написано на салфйетке в пивбаре - но тут то "2 кнопочки в дельфишнике создать", очевидно же.
4 Rovan
 
гуру
04.06.13
11:47
(0) почему Дата и Валюта - типа строка ?

открой для себя Индексирование ТаблицыЗначений !
5 Ненавижу 1С
 
гуру
04.06.13
11:49
запросы в цикле, нах нах
6 Галахад
 
гуру
04.06.13
11:51
2 суток? Номана. Пусть заказчик видит какая 1С тормозная. :-)
7 Rovan
 
гуру
04.06.13
11:52
(+4) и метод НайтиСтроки() у ТаблицыЗначений
8 salvator
 
04.06.13
11:54
Ухтыжёёё!
9 Smallrat
 
04.06.13
11:55
Запрос3 и Запрос4 мне напоминают одну картинку:
http://cf.broadsheet.ie/wp-content/uploads/2010/10/124pigs.jpg
10 Славен
 
04.06.13
11:57
(2)пилять я сейчас сижу перепиливаю обработку где дохрена запросов в цикле и прочей фуеты, много приходится оставлять потому что тупо времени нет переделать правильно
11 H A D G E H O G s
 
04.06.13
12:00
(10) Дадада
12 Славен
 
04.06.13
12:02
(11)что дада, 12 тыров строк кода, надо перепилить из бп в ут, срок до послезавтра, она рабочая в бп, но долго, самые затыки конечно убираю, но приходится что-то и на потом бросать
13 Alex375
 
04.06.13
12:11
Может быть легче убить все и в начале подумать головой? Глядишь алгоритм нормальный придумаешь и тогда все быстрее будет работать. Например, почему в исходную таблицу не помечать объекты вместо текста?
14 dborovsky
 
04.06.13
12:16
ну так я спрашиваю как лучше сделать. Я же не прошу код писать! А в общих словах что и как лучше. Если не можете ничего добавить, не надо и комментировать здесь.
15 Галахад
 
гуру
04.06.13
12:25
(14) Ты просишь код читать. А не всегда приятно.

Лучше опеши словами чего хочешь.
16 dborovsky
 
04.06.13
12:28
в первом сообщении указал
17 H A D G E H O G s
 
04.06.13
12:28
(14) Убрать к херам
Функция ПоискНоменклатуры(парам1, парам2, тз)

Ты че этой функцией делаешь то? Типы приводишь, штоле?
18 H A D G E H O G s
 
04.06.13
12:28
ППЦ лютый.
19 Uzumaki
 
04.06.13
12:32
С кодом все нормально. Нужен мощный сервер.
20 Галахад
 
гуру
04.06.13
12:32
(16) Молоток.

1. "Сообщение один".
2. Если вам не охота читать "сообщение один", переходите к пункту 1.
21 Smallrat
 
04.06.13
12:32
(19) этапять!!
22 H A D G E H O G s
 
04.06.13
12:34
ТаблицаКодовКонтрагентов=тзТекстФайл.Скопировать(,"КонтрагентКод");
   ТаблицаКодовКонтрагентов.Свернуть("КонтрагентКод");
   ТаблицаКодовКонтрагентов.Колонки.Добавить("Контрагент");
   ТаблицаКодовКонтрагентов.Индексы.Добавить("КонтрагентКод");
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ
   |    Контрагенты.Ссылка,
   |    Контрагенты.Код
   |ИЗ
   |    Справочник.Контрагенты КАК Контрагенты
   |ГДЕ
   |    Контрагенты.Код В(&МассивКодов)";
   Запрос.УстановитьПараметр("МассивКодов",ТаблицаКодовКонтрагентов.ВыгрузитьКолонку("КонтрагентКод"));
   Выборка=Запрос.Выполнить().Выбрать();
   Пока Выборка.Следующий() Цикл
       СтрокаТаблицы=ТаблицаКодовКонтрагентов.Найти(Выборка.Код,"КонтрагентКод");
       Если СтрокаТаблицы<>Неопределено Тогда
           СтрокаТаблицы.Контрагент=Выборка.Ссылка;
       КонецЕсли;
   КонецЦикла;


Итого - у тебя ТЗ с колонками КонтрагентКод и Контрагент, по которой ты ищещ в цикле.

Аналогично с номенклатурой.
23 dborovsky
 
04.06.13
12:46
thank you
24 Uzumaki
 
04.06.13
12:49
(0) Скажи честно, это ведь прикол?
25 zladenuw
 
04.06.13
12:53
а не лучше все слепить в 1 тз, а потом 1 циклом создавать документы ? а не выполняться поиск по мере создание документов. и можно будет загружать в табличную часть товары. по идее должно быть все быстрее
26 H A D G E H O G s
 
04.06.13
12:54
(25) **зевает
27 dborovsky
 
04.06.13
12:55
Прикол что?
28 H A D G E H O G s
 
04.06.13
12:57
(27) Ну как бы ты такую чушь кодом в (0) нес, что народ не верит, что это серьезно ты.
29 dborovsky
 
04.06.13
13:00
т.е. ты уже через месяц работы с 1с и с программированием клепал такие обработки с закрытыми глазами. Я рад за тебя!
30 Uzumaki
 
04.06.13
13:00
(28) Спасибо.
(0) От себя добавлю, если
               НовыйДокумент.Организация = Справочники.Организации.НайтиПоКоду("000000001");

вынести за цикл, то 11 документов будут загружаться за 9 минут и 59 секунд
31 Uzumaki
 
04.06.13
13:04
(29) Нет, первый месяц я ковырял паскаль и у меня было больше времени, чем у тебя на подумать, ведь это было еще в школе.
32 dborovsky
 
04.06.13
13:05
я не тебе пишу
33 zva
 
04.06.13
13:35
Я может задачи не понял, но почему нельзя ТЗ загрузить во временную таблицу, запросом упорядочить по дате и контрагенту и сгруппировать, далее один раз обойти результат запроса по группировакам и создать документы?
34 hhhh
 
04.06.13
13:48
(33) ну чел организацию не может запомнить. Десятки тысяч раз ищет организацию в базе. Какие таблицы?
35 ptiz
 
04.06.13
13:50
(0) Запусти замер производительности, сам всё увидишь.
36 Паланик
 
04.06.13
13:54
Ну очевидно, что ТС в (0) в одном куске кода наступил на все мыслимые и не мыслимые грабли, на которые все наверное наступали. В книге знаний нет статьи никакой для начинающих, по оптимизации и быстродействию кода? Автор хотя бы по 2 запроса в двойном цикле не будет делать, и то хлеб.)
AdBlock убивает бесплатный контент. 1Сергей