Страница 1 из 1

Быстродействие интерфейса

Добавлено: 08 ноя 2007, 13:06
Olga T
Сделала интерфейс по созданию документа, данные считываются из файла. При запуске его в Галактике через Утилиты (Запуск внешнего интерфейса), скорость чтения и обработки данных из файла в 3 раза медленнее, чем если запускать его через Support из компилятора интерфейсов (запуск окна не модально). Лицензии на Support нет, так что придется работать в Галактике через утилиты. С чем связана такая временная разница при запуске? Как улучшить быстродействие при запуске интрефейса из Галактики?

Добавлено: 08 ноя 2007, 14:05
edward_K
много зависит от логической таблицы. фейс в студию - тыды мож кто что и подскажет. а в сапорте табл меньше открыто, да и функционал попроще, да проверки по контурам нет и так далее.

Добавлено: 08 ноя 2007, 14:21
Olga T
Содержание *.vip файла такое:
.form spisok
.fields
.endfields
Сведения об импорте данных из файла
.{
^
.}
.endform

Interface Уценка 'Импорт данных для создания акта уценки' DoAccept,EscClose,cyan;
! show at (11,4,71,21) - здесь задаем координаты вывода
show at (20,4,70,11);
Var
Hkadr :longint; kz,i, mode,pr,nal :integer; RzSpDocNrec, Post:Comp; Data:Date; Nomer:String[10]; KolItog:Double; KolItog2:Double; RezMove:Boolean;
Table struct Ucenka
( ddoc:Date, ndoc:string, Kol:Double, MC:string, McNrec:comp, CGROUPMC:comp, PRICEP:Double, PRICED:Double, ced:comp, Nalog:Double, SNacenP:Double, RoznPriceP:Double, SNALOGP:Double, PNACENP:Double, PostParty :Comp, KolFak:Double, RZKUTPRIH_nrec:comp, RZKUTPRIH_ZKPRICE:word, RZKUTPRIH_FPRICE:Double, RZKUTPRIH_CVALUT:Comp, RZKUTPRIH_VCURSE:Double, RZKUTPRIH_PRICE:Double, RZKUTPRIH_VPRICE:Double,RZKUTPRIH_CVAL:Comp, RZKUTPRIH_RPRICE:Double,RZKUTPRIH_SNACEN:Double,
RZKUTPRIH_PNACEN:Double,RZKUTPRIH_SNALOG:Double, RZKUTPRIH_PPRICE:Double,RZKUTPRIH_KOL:Double, RZKUTPRIH_COTPED:Comp, RZKUTPRIH_OSTATOK:Double, RZKUTPRIH_SELL:Boolean,RZKUTPRIH_CAN:Boolean, RZKUTPRIH_CPARTY:comp
);

Create View pp
As Select KatMC.Name,KatMC.Nrec,KatMC.CGROUPMC From KatMC;

!определение последнего номера акта уценки
Create View Nomer
as select RzDoc.Ndoc from Rzdoc
where
((
913 == RZDOC.TYPEMOVE //тип акта уценки
));

Create View prih As Select *
From RZKUTPRIH
//только приходы, по которым есть остаток
where (( root == RZKUTPRIH.NREC and
(40004728C7E3F919h = RZKUTPRIH.CPODR and (RZKUTPRIH.OSTATOK >= 1)) )) order by RZKUTPRIH.DDOC;

!выбираем данные из каталога партий для определения поставщика
Create View part As Select KATPARTY.CORGPAR,KATPARTY.Nrec
From KatParty;

!форма для вывода служебных сообщений
form spisok('ucenka.out');

! Передаваемые параметры формы
parameters data;

procedure NameMC(Nam:string);
!выбираем данные из katmc по имени МЦ из файла
var stroka:string;
{
if pp.getfirst katmc=tsok
then do
{
if (nam = pp.katmc.name)
{
ucenka.mcnrec := pp.katmc.nrec;
ucenka.CGROUPMC := pp.katmc.CGROUPMC;
}
}
while pp.getnext katmc=tsok;
}

!Определение процента налога с продаж
function NalogP(SumNal:Double;Price:Double):double;
var k:double;
{
k:=0;
k:=SumNal/Price;
if (k>0.02) and (k<0.07) then
{
NalogP := 5;
}
else
if (k>0.10) and (k<0.2) Then
{
NalogP :=15;
}
else NalogP := 0;
}

!определение поставщика партии МЦ
function PartyPost(Party:comp):comp;
{ if part.getfirst katparty = tsok
then do
{ if (Party = part.katparty.nrec)
{
PartyPost := part.KATPARTY.CORGPAR;
}
}
while part.getnext katparty=tsok;
}

!определения данных прихода
procedure RzPrih(McNrec:comp;Price:Double;Kolvo:Double);//выбираем данные из RzKutPrih
Var Kol:Double; Kol2:double;
{
Kol:=Kolvo;
Kol2:=kolvo; //Для вывода в список ошибок

! перебор всех записей таблицы
if prih.getfirst RZKUTPRIH = tsok then do
{ //начало тела цикла
//выбираем позиции с совпадающим МЦ, продажной ценой и подразделением из приходов с остатками
if (McNrec = prih.RZKUTPRIH.CMC)and(prih.RZKUTPRIH.PPRICE = Price)//and(prih.RZKUTPRIH.CPodr=podr)
//делаем проверку если в файле кол-во 4, а в приходе 3, чтобы циклом пройтись по записям дважды
{
if Kol <= prih.RZKUTPRIH.OSTATOK
{
ucenka.RZKUTPRIH_nrec := prih.RZKUTPRIH.nrec;
ucenka.RZKUTPRIH_SNACEN := prih.RZKUTPRIH.SNACEN; //Сумма наценки
.........
ucenka.KolFak := Kol;
Kol2 := Kol2-Kol; //для вывода в список ошибок
KolItog := KolItog+Kol; //подсчитываем общее кол-во в акте
break; // переход к следующему циклу, т.к. приход найден
}
//кол-во в приходе меньше, чем в файле
else
{ //открываем цикл по else, когда кол-во в приходе меньше, чем в файле
ucenka.RZKUTPRIH_nrec := prih.RZKUTPRIH.nrec;
..............
ucenka.KolFak := prih.RZKUTPRIH.OSTATOK;

!промежуточные расчеты
!определяем налог с продажи
Nal := NalogP(ucenka.RZKUTPRIH_SNALOG,ucenka.RZKUTPRIH_PPRICE);
Ucenka.Nalog := Nal;
Post := PartyPost(ucenka.RZKUTPRIH_CPARTY);
!поставщик из таблицы партий
Ucenka.PostParty := Post;
!сумма налога на продажу к ед.МЦ после переоценки
Ucenka.SNALOGP := Ucenka.PRICEP*Ucenka.Nalog/(Ucenka.Nalog+100);
!розничная цена после переоценки
Ucenka.RoznPriceP := Ucenka.PRICEP-Ucenka.SNALOGP;//Ucenka.SNacenP;
!сумма наценки после переоценки
Ucenka.SNacenP := Ucenka.RoznPriceP-Ucenka.RoznPriceP*18/118-ucenka.RZKUTPRIH_PRICE;
!процент наценки после переоценки
Ucenka.PNACENP := Ucenka.SNACENP/ucenka.RZKUTPRIH_FPRICE*100;
!вставляем запись в конце, потому что могут быть разные приходы
Insert current Ucenka;

!чтобы осуществялась проверка на несоответствие цены
ucenka.RZKUTPRIH_nrec := 0;
!следующее кол-во для цикла
kol := kolvo-prih.RZKUTPRIH.OSTATOK;
! кол-во для вывода в список ошибок
Kol2 := Kol2-prih.RZKUTPRIH.OSTATOK; //для вывода в список ошибок
KolItog := KolItog+ucenka.KolFak; //подсчитываем общее кол-во в акте
!переход к след.записи
prih.getnext RZKUTPRIH;
} //закрываем цикл по else, когда кол-во в приходе меньше, чем в файле
}
} //конец тела цикла
while prih.getnext RZKUTPRIH = tsok; //условие продолжения цикла

if ucenka.RZKUTPRIH_nrec=0 Then
{
Spisok.Write('Нет прихода: '+ucenka.mc+' по цене:'+Price+' в кол-ве:'+kol2);
KolItog2 :=KolItog2+Kol2; //суммируем кол-во, которое не попадет в акт уценки
}
else
{
!промежуточные расчеты
!определяем налог с продажи
Nal := NalogP(ucenka.RZKUTPRIH_SNALOG,ucenka.RZKUTPRIH_PPRICE);
Ucenka.Nalog := Nal;
Post := PartyPost(ucenka.RZKUTPRIH_CPARTY);
!поставщик из таблицы партий
Ucenka.PostParty := Post;
!сумма налога на продажу к ед.МЦ после переоценки
Ucenka.SNALOGP := Ucenka.PRICEP*Ucenka.Nalog/(Ucenka.Nalog+100);
!розничная цена после переоценки
Ucenka.RoznPriceP := Ucenka.PRICEP-Ucenka.SNALOGP;
!сумма наценки после переоценки
Ucenka.SNacenP := Ucenka.RoznPriceP-Ucenka.RoznPriceP*18/118-ucenka.RZKUTPRIH_PRICE;
!процент наценки после переоценки
Ucenka.PNACENP := Ucenka.SNACENP/ucenka.RZKUTPRIH_FPRICE*100;
!вставляем запись в конце, потому что могут быть разные приходы
Insert current Ucenka;

!чтобы осуществялась проверка на несоответствие цены
ucenka.RZKUTPRIH_nrec := 0;
}
}

screen forma
show at(,,,6);
fields
data :[12],Noprotect ;
buttons
cmRead; cmIns; cmExtt;
<<

Выберите дату акта:.@@@@@@@@@@@

<. Прочитать данные из файла .>

<. Создать акт уценки .>


<. ВЫХОД .>

>>
end;

HandleEvent
cmInit:
{
data:=Cur_Date;
}
cmRead:
{
mode:=15648;
Hkadr:=DBFOpen('c:\obmen\ucen.dbf',mode);

//проверяем, чтобы файл находился в нужной папке
If Hkadr=0 Then Message('Файл данных отсутствует по пути c:\obmen\')
else
{
kz:=DBFGetFirst(Hkadr);
If kz<>0 Then message('Файл данных пуст!');
!номер документа
if nomer.getlast RZDoc = tsok Then
Ucenka.ndoc := NextNumStr(nomer.RzDoc.ndoc)
else
Ucenka.ndoc := '555';
KolItog :=0; KolItog2 :=0;

!начинаем визуализацию процесса чтения данных из файлов
StartNewVisual(vtRotateVisual, vfTimer+vfBreak+vfConfirm,' Идет чтение данных из файла. Ждите...',kz);
while kz=0 do
{
Ucenka.ddoc := data;
Ucenka.kol := DBFGetFieldValue(Hkadr,'KOL');
Ucenka.MC := DBFGetFieldValue(Hkadr,'MC');
Ucenka.PRICEP := DBFGetFieldValue(Hkadr,'PRICEP'); //цена после
Ucenka.PRICED := DBFGetFieldValue(Hkadr,'PRICED'); //цена до
NameMC(ucenka.mc); //находим nrec по name

If ucenka.mcnrec=0 then
{
Spisok.Write('Не найдена МЦ: '+ucenka.MC);
KolItog2:=KolItog2+ Ucenka.kol;
}
else
{
RzPrih(ucenka.mcnrec,Ucenka.PRICED,Ucenka.kol); //Находим данные о партии
ucenka.mcnrec:=0;
}
kz:=DBFGetNext(Hkadr);
};
DBFClose(Hkadr);

StopVisual('',0); //Останавливаем процесс визуализации
Message('Данные из файла импортированы!');

!Выводим на экран файл со списком ошибок
Spisok.Write('');
If KolItog<>0 Then Spisok.Write('Общее количество МЦ в создаваемом акте : '+KolItog);
If KolItog2<>0 Then Spisok.Write('Общее количество МЦ не попадающих в акт: '+KolItog2);
// Spisok.PutEvent(feBreak);
Spisok.ShowFile('');
}
}

cmIns:
{
Insert RzDoc set
//шапка документа
rzdoc.ddoc := data,
...............
rzdoc.CMOLTO := 400090185A74E3E2h;
rzdoc.TYPEMOVE := 913;
// insert current rzdoc;
if modifier getfirst ucenka = tsok Then do
{
//0-приход спецификация документа
Insert RzSpDoc set
RzSpDoc.CMC := ucenka.mcnrec,
RzSpDoc.DDOC := data,
RzSpDoc.CORG := Ucenka.PostParty,
.............
RzSpDocNrec := RzSpDoc.nrec;

//1-расход
Insert RzSpDoc set
RzSpDoc.CMC := ucenka.mcnrec,
RzSpDoc.DDOC := data,
...............
RzSpDoc.OSTATOK := ucenka.RZKUTPRIH_OSTATOK, //Текущее количество
}
while modifier getnext ucenka = tsok;
message('Акт уценки №'+rzdoc.ndoc+' создан!');

!перемещаем файл
RezMove:= CopyMoveFile('c:\obmen\ucen.dbf','c:\ucen.dbf',True);
If RezMove <> True Message('Файл данных невозможно переместить!');
}

!Закрытие интерфейса
cmExtt:
{
CloseInterface(cmDefault);
}
end; // HandleEvent
end. // interface

Добавлено: 08 ноя 2007, 14:22
Olga T
Может лучше запускать интерфейс через Ard отчет?

Добавлено: 08 ноя 2007, 15:09
edward_K
попробуйте так
Create View prih As Select RZKUTPRIH.DDOC
From RZKUTPRIH
//только приходы, по которым есть остаток
where (( 40004728C7E3F919h == RZKUTPRIH.CPODR and 1<<=(RZKUTPRIH.OSTATOK(noindex) )) order by RZKUTPRIH.DDOC;
в 1 вьюхе на katmc нет фильтров - значит вся табла загрузиться. Лучше отфильтровать по какой то переменной(вроде вы ищете по katmc.name) - это тоже ускорит загрузку, да и работу процентов на 50 . NameMC - тоже не прибавляет быстродействия. Зачем всю katmc пробегать? есть же индекс.

Добавлено: 08 ноя 2007, 15:36
Olga T
"NameMC - тоже не прибавляет быстродействия. Зачем всю katmc пробегать? есть же индекс."
А как написать, используя индекс?

Добавлено: 09 ноя 2007, 10:09
edward_K
create view vvv
var nmmc :string ;
as select katmc.name from katmc where (( nmmc == katmc.name )) ;
...
function namemc(wnmmc :string ) :boolean ;
{ set vvv.nmmc:=wnmmc ;
namemc:=(vvv.getfirst fastfirstrow katmc=0) ;
}

Добавлено: 12 ноя 2007, 18:54
Olga T
Большое спасибо за код с индексом и советы. Так все и сделала, быстродействия улучшилось в 2 раза

Добавлено: 13 ноя 2007, 10:41
edward_K
как я угадал с процентами :)

Добавлено: 13 ноя 2007, 10:56
san
вместо конструкции getfirst ..getnext лучше использовать _loop...
на скл платформах еще *6 раз быстрее, на битриве не знаю есть ли разница.

Добавлено: 13 ноя 2007, 11:11
edward_K
ну тогда еще
"вьюха._loop fullcache таблица" и никаких getfirst по той же вьюхе в пределах этого loop. Тогда вообще все залетает. Но вопрос стоял о скорости загрузки фейса.

Добавлено: 13 ноя 2007, 12:48
san
edward_K писал(а):Но вопрос стоял о скорости загрузки фейса.
А мне показалось что писали именно о работе самого интерфейса, а не его загрузке:
"При запуске его в Галактике через Утилиты (Запуск внешнего интерфейса), скорость чтения и обработки данных из файла в 3 раза медленнее, чем если запускать его через Support из компилятора интерфейсов (запуск окна не модально)."

Добавлено: 14 ноя 2007, 12:19
Olga T
Вопрос стоит о работе интерфейса