![]() |
|
| Правила Форума редакция от 22.06.2020 |
|
|||||||
|
|
Окажите посильную поддержку, мы очень надеемся на вас. Реквизиты для переводов ниже. |
|
|
|
Опции темы | Опции просмотра |
Language
|
|
|
#1
|
|
1. Имеем 1С, в нем справочник ТМЦ порядка 20 тыс. наименований, из них порядка 800 - группы.
2. Имеем БД фаербирд с таблицами: а) Группы товаров (2 колонки - ид группы и наименование группы, ид группы праймари кей, значение ид группы равно значению кода в 1С) б) Товары (9 колонок, ид товара равно коду товара в 1С) в) Цены (4 колонки - ид цены /ставится через тригер БИ + генератор/, ид товара /значение код а товара из таблицы Товары/,Дата цены, значение цены на дату). Задача: перебросить группы товаров, товары и цены товаров из 1С в фаирбирдовскую таблицу, а также, отслеживать изменения наименований, реквизитов и цен и проводить синхронизацию по этим изменениям. Моя реализация: 1. Подключаюсь к 1С через ОЛЕ 2. Методом перебора справочника товара в 1С выгребаю группы и передаю нужные значения в процедуру добавления в фаербирд -- Spr.selectitems(1); while Spr.GetItem(1) > 0 do Begin Progress.StepBy(1); if Spr.IsGroup('')=0 then Continue; Group_Code:=Spr.getAttrib('Код'); Group_Lvl:=OLE1C.EvalExpr('ПолучитьУровеньГруппы(' +IntToStr(Group_Code)+')'); Group_Rod:=0; if Group_Lvl<>1 then Group_Rod:=OLE1C.EvalExpr('ПолучитьРодителяГруппы( '+IntToStr(Group_Code)+')'); if Length(Spr.getAttrib('Наименование'))>24 then Group_Name:=Copy(Spr.getAttrib('Наименование'),1,2 4) Else Group_Name:=Spr.getAttrib('Наименование'); Add_Group(Group_Code ,Group_Name,Group_Rod); -- , где ид:=Group_Code,Group_Name - имя группы, Group_Rod - код родительской группы для подгрупп. 3. процедурка Add_Group -- procedure TMain_Form.Add_Group(G_Code:Integer;G_Name:String; G_Rod:Integer); Var Need_Upd:Boolean; BEgin Need_Upd:=False; Proc.StoredProcName:=''; Sel.Close; Sel.SQL.Text:='Select * from SPR_TMC_G where ID_GROUP='+IntToStr(G_Code); Sel.Open; Sel.FetchAll; if Sel.RecordCount=0 then Begin Need_Upd:=True; Proc.StoredProcName:='SPR_TMC_G_INS'; end Else Begin Sel.First; if trim(Sel.FieldByName('name_group').AsString)<>trim (G_Name) then Need_Upd:=True; if Sel.FieldByName('rod_group').AsInteger<>G_Rod then Need_Upd:=True; end; if Need_Upd=True then Begin if Proc.StoredProcName<>'SPR_TMC_G_INS' then Proc.StoredProcName:='SPR_TMC_G_UPD'; Tr_Proc.StartTransaction; Proc.ParamByName('id_group').AsInteger:=G_Code; Proc.ParamByName('name_group').AsString:=G_Name; Proc.ParamByName('rod_group').AsInteger:=G_Rod; Proc.ExecProc; Tr_Proc.Commit; End; -- На этом этапе в принципе все норм, при 20К позиций в справочнике за минуту -две идет оновление БД файербирда. 4. Дальше тем же перебором отбираю именно элементы справочника товаров в 1С -- Tr_Proc.StartTransaction; Str_Sost.Caption:='Синхронізація елементів товарів...'; Progress.Min:=0; Progress.Max:=OLE1C.EvalExpr('ПолучитьКоличествоЭл ементов()'); Progress.Position:=0; Main_Form.Refresh; Spr.selectitems(1); while Spr.GetItem(1) > 0 do Begin Progress.StepBy(1); if Spr.IsGroup('')=1 then Continue; //Если розничной цены нету - нафиг такой товар Cena_R:=OLE1C.EvalExpr('ПолучитьРЦену('+Spr.getAtt rib('Код')+')'); IF Cena_R=0 Then Continue; Group_Code:=Spr.getAttrib('Код'); Group_Lvl:=OLE1C.EvalExpr('ПолучитьУровеньГруппы(' +IntToStr(Group_Code)+')'); Group_Rod:=0; if Group_Lvl<>1 then Group_Rod:=OLE1C.EvalExpr('ПолучитьРодителяГруппы( '+IntToStr(Group_Code)+')'); if Length(Spr.getAttrib('Наименование'))>128 then Group_Name:=Copy(Spr.getAttrib('Наименование'),1,1 28) Else Group_Name:=Spr.getAttrib('Наименование'); Add_Tovar(Group_Code,Group_Name,Group_Rod,Spr.getA ttrib('Штрихкод'),Cena_R); end; Tr_Proc.Commit; -- Отличия от предыдущей процедурки для груп - транзакцию всунул тут ибо, имхо, лучше фиксировать транзакцию после выполнения встроеных процедур 5. Процедура Add_Tovar имеет следующий вид: - procedure TMain_Form.Add_Tovar(T_Code:Integer;T_Name:String; T_Rod:Integer;T_Shtrihcode:String;T_Cena:Real); var Need_Set_Cena:Integer; Need_upd:Boolean; BEgin Need_upd:=False; Proc.StoredProcName:=''; Sel.Close; Sel.SQL.Text:='Select * from SPR_TMC where ID_TMC='+IntToStr(T_Code); Sel.Open; Sel.FetchAll; if Sel.RecordCount=0 then Begin Need_upd:=True; Proc.StoredProcName:='SPR_TMC_INS'; end Else Begin Sel.First; if trim(Sel.FieldByName('name').AsString)<>Trim(T_Nam e) Then Need_upd:=True; if trim(Sel.FieldByName('shtrihkod').AsString)<>Trim( T_Shtrihcode) Then Need_upd:=True; if Sel.FieldByName('id_group').AsInteger<>T_Rod Then Need_upd:=True; end; if Need_upd=True then Begin if Proc.StoredProcName<>'SPR_TMC_INS' then Proc.StoredProcName:='SPR_TMC_UPD'; Proc.ParamByName('id_tmc').AsInteger:=T_Code; Proc.ParamByName('name').AsString:=T_Name; Proc.ParamByName('vid_tmc').AsInteger:=0; Proc.ParamByName('art').AsString:=''; Proc.ParamByName('shtrihkod').AsString:=T_Shtrihco de; Proc.ParamByName('id_group').AsInteger:=T_Rod; Proc.ParamByName('dop_name').AsString:=LowerRCase( T_Name); Proc.ParamByName('skidka').AsInteger:=0; Proc.ParamByName('Edit_Ceny').AsInteger:=0; Proc.ExecProc; end; Need_Set_Cena:=1; Sel.Close; Sel.SQL.Text:='Select * from SPR_CENY where ID_TMC='+IntToStr(T_Code); Sel.Open; Sel.FetchAll; Sel.First; while not Sel.Eof do Begin if sel.FieldByName('DATE_CENA').AsDateTime=Now then Begin if sel.FieldByName('CENA').AsFloat<>T_Cena then Begin Proc.StoredProcName:='SPR_CENY_UPD'; Proc.ParamByName('id_cena').AsInteger:=Sel.FieldBy Name('id_Cena').AsInteger; Proc.ParamByName('id_tmc').AsInteger:=T_Code; Proc.ParamByName('date_cena').AsDate:=Now; Proc.ParamByName('cena').AsFloat:=T_Cena; Proc.ExecProc; Need_Set_Cena:=0; end; Break; end; Sel.Next; end; if Need_Set_Cena=1 then Begin Proc.StoredProcName:='SPR_CENY_INS'; Proc.ParamByName('id_tmc').AsInteger:=T_Code; Proc.ParamByName('date_cena').AsDate:=Now; Proc.ParamByName('cena').AsFloat:=T_Cena; Proc.ExecProc; end; end; -- Где в указаном болдом тексте происходит проверка/вставка/апдейт цены. и собственно, проблема: При отключении проверки/вставки/апдейта цен время выполнения (имею ввиду именно синхронизация элементов справочника) около 15-18 мин, с ценами - минут 30-40. Присоветуйте коллективным разумом - может возможен другой алгоритм проверок/апдейтов? З.Ы. Думал, может селект на ИД товара/цены делать не на каждый элемент из справочника, а в общем, и потом искать по готовому набору записей, но вариант 20К раз перебирать набор записей в 20К не кажется более быстрым.... |
|
|
|
|
Похожие темы
|
||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| Подскажите плиз коммуникатор с хорошим звуком | APEXik | КПК | 5 | 11.10.2010 17:52 |
| Подскажите плиз что за индикатор Renault Kangoo | deamon_t | Автосервис | 2 | 11.05.2009 09:35 |
| Подскажите,плиз!!! | васька59 | Ноутбуки, Нетбуки, Планшеты | 23 | 13.06.2008 10:08 |
| подскажите плиз ! | Bimbo | PHP | 2 | 22.08.2007 07:10 |
| Софт для видеокарты с ТВ-тюнером: подскажите, плиз! | LeXXiK | Архив | 7 | 13.02.2007 19:31 |
|
|