Имя: Пароль:
1C
1С v8
Табличная часть и запрос.
0 Eugeneer
 
14.05.13
21:44
Занимаюсь оптимизацией одного из модулей.
Сегодня впервые загрузил прайс с 328 000 строк из экселя.
Грузится 2 минуты.
Вопрос с синхронизацией. Хочу добится приемлемого результата в несколько минут.

Итак что происходит.

1) Все данные файла считываются из экселя в ТЗ.
2) после заполнения распознания колонок я выполняю синхронизацию.
Делается это у меня одним большим запросом. А именно эта вся ТЗ запихивается во временную таблицу целиком.
Эту временную таблицу левым соединением со справочником номенклатуры по необходимым полям поиска я получаю результат запроса.

Это получается ТЗ в которой есть данные импорта и номенклатура из 1С.

Весь этот результат я помещаю опять в ТЗ, которая уже выводится на форму с результатами.

3) Что тут происходит. В результате запроса у меня появляется выборка которую я обхожу и через цикл по ключу строки таблицы заполняю в ней результат поиска номенклатуры.
Это естественно происходит в цикле.
И вот тут вопрос. Как это ускорить. Результирующую таблицу я не могу загружать в нужную мне таблицу - так там множество других данны, которые я не передаю в запрос.
1 Eugeneer
 
14.05.13
21:45
Вообще есть ли в 1С методы которыми можно в запрос поместить объект таблицы и прямо там сделать заполнение.
2 Fragster
 
гуру
14.05.13
21:45
замер на чем основное время показывает - его и устраняй
3 Fragster
 
гуру
14.05.13
21:46
(1) у ТЧ есть Выгрузить/Загрузить
4 Fragster
 
гуру
14.05.13
21:47
ну и да - при наличии критерия ускорения, окружения и самой обработки - могу попробовать помочь за не очень большие, по меркам (0), деньги
5 Fragster
 
гуру
14.05.13
21:47
критерия выполнения результата
6 Fragster
 
гуру
14.05.13
21:48
или достижения результата...
7 Eugeneer
 
14.05.13
21:48
(2) нечего ускорять. уже дальше некуда.
Я всю синхронизацию сделал одним запросом без циклов.
Получил результат. Теперь я его обхожу циклом чтобы заполнить по строкам номенклатуру.

Вот тут и затык.
Каким образом избавится от этого цикла.
Можно ли в 1С сразу заполнить нужную мне таблицу, которая является реквизитом обработки.


Короче говоря если бы у вас был док с табличной частью. Как сделать заполнение этой табличной част ив запроса. без выгрузок.
8 Fragster
 
гуру
14.05.13
21:49
ТЧ.Загрузить(Запрос.Выполнить.Выгрузить)
9 Eugeneer
 
14.05.13
21:49
(3) не катит. ладно еще посмотрю
Таблица которую я передаю запрос помещается туда не вся.
У меня там хренова куча данных - более 40 колонок.
В запросе я только 2-3 колонки передаю. чтобы по ним найти номенклатуру.
10 France
 
14.05.13
21:50
скд?
11 Fragster
 
гуру
14.05.13
21:50
(9)->(4)
12 France
 
14.05.13
21:50
2 - в запросе сформируй нужные данные, все сорок колонок, и загружай в тз
13 Eugeneer
 
14.05.13
21:51
(12) думаешь это будет разумно?
14 France
 
14.05.13
21:52
(13) когда мне лениво было перебирать строки, так и сделал.. и не раз
а что неразумного?
15 ДенисЧ
 
14.05.13
21:53
Маня опять лажает
16 Eugeneer
 
14.05.13
21:53
(14) попробую так...
17 Eugeneer
 
14.05.13
21:54
да пилять.... не получится) вспомнил..
18 France
 
14.05.13
21:54
(17) почему?
19 Eugeneer
 
14.05.13
21:54
в таблице есть строки которые не учавствуют в поиске или могут не подходит. я их в запросе фильтрую.
20 Eugeneer
 
14.05.13
21:55
а в таблице они нужны все равно.
21 France
 
14.05.13
21:55
а как они потом  в цикле в таблицу попадают?
22 Eugeneer
 
14.05.13
21:56
Процедура СинхронизацияСправочникАртикул(ТабличнаяЧасть) Экспорт
   
   Партнер                  = ПрайсПартнера.Партнер;
   ПроизводительПоУмолчанию = ПрайсПартнера.ПроизводительПоУмолчанию;
   
   ДанныеПоиска  = ТабличнаяЧасть.Выгрузить();
   
   ТектЗапроса =
   "ВЫБРАТЬ
   |    ВременнаяДанныеПоиска.КлючСтроки КАК КлючСтроки,
   |    ВременнаяДанныеПоиска.Поле_Артикул КАК Поле_Артикул    
   |ПОМЕСТИТЬ ВременнаяДанныеПоиска
   |ИЗ
   |    &ДанныеПоиска КАК ВременнаяДанныеПоиска
   |ГДЕ
   |    ВременнаяДанныеПоиска.Номенклатура = &ПустаяСсылка
   |    И ВременнаяДанныеПоиска.Поле_Артикул <> """"
   |    И ВременнаяДанныеПоиска.ЭтоГруппа = ЛОЖЬ
   |
   |ИНДЕКСИРОВАТЬ ПО
   |    КлючСтроки,
   |    Поле_Артикул
   |;
   |
   |////////////////////////////////////////////////////////////////////////////////
   |ВЫБРАТЬ
   |    ВременнаяДанныеПоиска.КлючСтроки КАК КлючСТроки,
   |    СпрНоменклатура.Ссылка КАК Номенклатура,
   |    СпрНоменклатура.Артикул КАК АртикулСсылка
   |ИЗ
   |    ВременнаяДанныеПоиска КАК ВременнаяДанныеПоиска
   |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
   |        ПО ВременнаяДанныеПоиска.Поле_Артикул = СпрНоменклатура.Артикул";
                         
   
   Запрос = Новый Запрос();
   Запрос.Текст = ТектЗапроса;
   Запрос.УстановитьПараметр("ДанныеПоиска", ДанныеПоиска);
   Запрос.УстановитьПараметр("ПустаяСсылка", ПустаяСсылка);
   
   РезультатЗапроса = Запрос.Выполнить();
   КолСовпадений = 0;
   
   ФормаИндикатора.КомментарийОбработкиДанных  = "Синхронизация номенклатуры...";
   ФормаИндикатора.МаксимальноеЗначение = ТабличнаяЧасть.Количество();
   ФормаИндикатора.Значение = 0;
   
   Выборка = РезультатЗапроса.Выбрать();    
   Пока Выборка.Следующий() Цикл    
       ОбработкаПрерыванияПользователя();
       ФормаИндикатора.Значение = ФормаИндикатора.Значение + 1;

       КолСовпадений = КолСовпадений + 1;

       Если НЕ ЗначениеЗаполнено(Выборка.Номенклатура) Тогда
           Продолжить;
       КонецЕсли;

       СтрТаблицыСинхронизации = НайтиСтрокуТаблицыОбработки(ТабличнаяЧасть,Выборка.КлючСтроки);
       
       ЗаполнитьЗначенияСвойств(СтрТаблицыСинхронизации,Выборка,"Номенклатура,АртикулСсылка");
       Мегапрайс.ПриИзмененииНоменклатуры(СтрТаблицыСинхронизации);
       СтрТаблицыСинхронизации.Пометка = Истина;
   КонецЦикла
   
КонецПроцедуры
23 Eugeneer
 
14.05.13
21:59
(21) ТЗ уже вся заполнена данными импорта.

Вот смотри еще раз.

Я заполнил таблицу - в ней все что из импорта - все данные.
в (22) одна из процедур.

1) Я эту таблиу выгружаю.
2) в запросе ее юзаю всего несколько полей.
3) Нахожу номенклатуру
4) Получаю результат
5) Делаю обход результата с поиском по ключу строки дополняю ее номенклатурой. тут получается что дополняются только те строки где номенклатура была найдена.
А также в запросе фильтруются сразу те строки которые мне не нужны.
Например где пустые артикулы, строки с граппами и там где номенклатура уже заполнена.
24 mikecool
 
14.05.13
22:01
"Я всю синхронизацию сделал одним запросом без циклов.
Получил результат. Теперь я его обхожу циклом чтобы заполнить по строкам номенклатуру. "
если уже есть синхронизация - что ты еще заполняешь?
25 Eugeneer
 
14.05.13
22:01
И у меня таких 12 процедур. Причем все они могут работать последовательно.
Например чел выбрал пять вариантов поиска которые запускаются последовательно.

Причем каждый дополняет предидущий.

Например поиски по артикулам - один алгоритм. дополнилд таблицу. далее идет след процедура которая обрабатывает необработанное. и так далее.
Короче говоря таблица эта работает с кучей дополняющих друг друга.
26 Eugeneer
 
14.05.13
22:02
(24) снова первую большую таблицу, которую теперь нужно дополнить . и все это учитывая (25)
27 mikecool
 
14.05.13
22:03
(25) что то имхается мне - это можно сделать пакетом запросов
28 Eugeneer
 
14.05.13
22:03
Начинаем потихоньку думать писать внешнюю базу на MySQL.
29 France
 
14.05.13
22:03
к таблице синхронизации левым соединение отфильтрованную таблицу?? и соединять до тех пор, пока все условия поиска не отработаны...
30 Eugeneer
 
14.05.13
22:04
(27) это почти и есть пакет запросов. Разные варианты поиска.
31 MaxS
 
14.05.13
22:05
Нельзя ли во временную таблицу записать всю табл часть обработки?
Создать другую ВТ с условиями как в (22)
Левыми соединениями найти что угодно, прицепить к исходной проной ИТ и выгрузить загрузить обратно в табл часть.
32 Eugeneer
 
14.05.13
22:07
(27) просто в разных процедурах. тк для скорости каждый из вызванных запросов накладывает фильтр по уже отработанному.
33 France
 
14.05.13
22:07
(31) баянист))
34 mistеr
 
14.05.13
22:16
(23) Можно попробовать построить некий индекс по ТЧ. Например Соответствие со значениями типа СтрокаТабличнойЧасти. Это ускорит поиск нужной строки для изменения. Но не факт что сильно повлияет на общий результат.

Заполнить что-либо одним запросом не получится. 1С к сожалению не умеет DML совсем.
35 France
 
14.05.13
22:22
(34) 1с только и умеет, что DML немного..
36 Eugeneer
 
14.05.13
22:23
Вот теперь и думаем из за проблем делать все в базу mySQL
Софтину которая работая из 1С будет загружать все во внешку и работать с ней. Включая справочник номенклатуры и тд

Ведь это только одна мелочь.
Представте себе следующих шаг когда в 1С надо загрузить эти 300 000 строк в регистрацию цен.....
37 Eugeneer
 
14.05.13
22:23
и провести его.
38 France
 
14.05.13
22:25
(36) подумаешь, мелочь какая... 300 тыщ..
дроби...
кстати, разве длина номера строки тч не 5?? раньше, по крайней мере, более 99 999 позиций в тч нельзя было..
39 Eugeneer
 
14.05.13
22:25
Прошелся по всей типовой УТ11 где есть примеры связей таблиц значений. Везде все через выборки, цикл, поиск строк. дополнение их.
40 Eugeneer
 
14.05.13
22:26
(38) поэтому у меня и есть реквизит КлючСтроки тип число. длина 10.
41 France
 
14.05.13
22:28
(39) ну, типовая не истина в последней инстанции... вся эта возня с запросами, выгрузка, загрузками сильно время выполнения увеличивают.. лучше все в запросе получить... и затем загрузить в тч..
42 mistеr
 
14.05.13
22:31
(36) И что прям все 300К каждый раз меняются?

Тут попахивает ущербностью всего подхода.
43 Eugeneer
 
14.05.13
22:31
Пока что оптимизирую то что есть. тк уже все эти наработки сделаны в 1С для 1С.
Но уже в принципе решено создание внешней базы. Впрочем мы уже в подобных условиях и работаем.
Есть внешняя база клиента на mySQL с 30 миллионами записей в которую ежедневно порядка 100 поставщиков заливаются прайсы цены и прочая информация. Прайсы от 10 до 100 тысяч строк.

База летает. Написали кучу модулей для работы с ней в 1С. И тут я и решил делать такую же базу....
Выхода нет. Все замечательно для небольших объемов. Но все больше клиентов на рынке у которых большие потребности с большими данными.
44 France
 
14.05.13
22:32
прайс на 300 тысяч... чем торгует компания, интересно?
45 Eugeneer
 
14.05.13
22:33
(42) поставщик запчастей для мотоциклов.
Это один из прайсов одного производителя Yamaha
Например полный каталог запчастей мерса это 3 миллиона.

Да меняются постоянно. каждый день. Причем во внешних базах все автоматом по рассписанию.
46 mistеr
 
14.05.13
22:35
(43) Ё... оказывается все не так плохо. Даже единая база есть. И в чем проблема записать туда еще и 1С-овскую ссылку? Вместо того, чтобы по 5 алгоритмов прогонять каждый раз, да еще под присмотром человека.
47 Eugeneer
 
14.05.13
22:35
У нас сайт на базе тредсофта. На сайте порядка 8 миллионов номенклатуры на данный момент. в 1Сину льется только рабочая номенклатура.
Мы написали планирование закупок для нужд розницы которая собирает инфо из нашей 1Ски по отработанной номенклатуре, статистике продаж и так далее и прямыми запросами к базе сайта - куда ежедневно и ежечасно заливается все
получаем мгновенными запросами данные.
48 mistеr
 
14.05.13
22:36
(46) Или наоборот, в справочник добавить Part No.
49 Drac0
 
14.05.13
22:37
Почему бы не использовать менеджер временных таблиц и не передавать его из процедуры в процедуру? Тогда исходная таблица будет всегда в памяти, в конце присоединяем полученные данные к ней, а потом это выгружаем/загружаем.
50 Eugeneer
 
14.05.13
22:37
Это я говорю про ту котнтору где я на проекте.
А у меня еще есть сотни клиентов у которых таже самая фигня, но у них ничего нет.
Грубо говоря люди купили 1Сину, сайт на битриксе ....)))) гы гы и хотят типа того же что у нас.
Чтобы гразить все автоматом по сотне тысяч, обмениватся с сайтом и так далее.

Например чтобы сделать сайт на трейдсофте и все это наладить надо пару лямов. Сразу же. Чтобы еще с 1Синой интегрировать еще пять лямов.
У клиентов таких денег нет)))))) Но все хотят.
51 mistеr
 
14.05.13
22:39
(50) А, другое дело. За малые деньги пусть ждут, пока циклы крутятся. Справедливо. :)
52 France
 
14.05.13
22:41
(50) ничего что есть EDI, и его поддержка в 1С?? через него заходи..
53 Eugeneer
 
14.05.13
22:41
(46) у меня две работы.
Одна - это проект где я работаю в крутой фирме с мега-автоматизацией. Где еще до меня много чего было.

Второе это решения которые я делаю на 1С для типовых и клиенты по ним. Вот по большей части я вожусь с решениями для 1С для них.
То что у меня на проекте - из этого решений я не делаю.
Трейд-софт не потянут и 99 процентов клиентов. Бабла не хватит.
54 Eugeneer
 
14.05.13
22:44
(51) планируем написать внешнюю базы для работы.
Загнать туда справочник 1С добавить таблицы номенклатуры контрагентов и тд
туда же цены и все остальное связанное.
Модули загрузки с регламентными.
И под это базу потом подстроить работу в 1С на прямых запросах.
Под универсализацию. Думаю спрос будет.
55 Reaper_1c
 
14.05.13
22:51
(22) Обновление данных в индикаторе сделай не чаще чем раз в 5 секунд - сильно удивишься...
56 Eugeneer
 
14.05.13
22:51
(55) да то фигня убрать можно - я в курсе что оно еще больше вешает))). у меня это решение на УТ11 там без индикаторов.
57 France
 
14.05.13
23:09
да, между делом: вся эта чудо функциональность замещается обожаемой мной обработкой загрузки табличных частей...
58 Eugeneer
 
14.05.13
23:14
(57) :))))) да да) она поиск по номенклатуре поставщиков умеет делать?)
И кстати о птичках - обожаемая загрузка в цикле по каждой строке запросик то лепит))
на линуксе работает?)
59 France
 
15.05.13
12:13
(58) номенклатура поставщика то не с неба валится... и имеет артикул... по артикулу и ищи...
если расскажешь для чего по каждой строке запросик - еще идею дам..
только не забудь - процент от продаж мне перечислять..
60 France
 
15.05.13
12:45
в тему, думаю... смотрю отчет Выполнение условий по договорам контрагента - так и хочется чьи-нибудь руки вырвать за то количество ТЗ, которые в этом отчете используются..
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший