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

Ошибка при выполнении алгоритма

Добавлено: 21 окт 2014, 18:55
Руслан
Сделал свой алгоритм по обновлению цены в межцеховых накладных согласно прайсу. Скомпилировался без ошибок, только после подключения при выполнении вылазит ошибка:
"в графе реляционных отношений таблица зависит от самой себя" и потом "OldlmmChildren<>nil", после этого вылетает по рантайму.

Re: Ошибка при выполнении алгоритма

Добавлено: 22 окт 2014, 08:52
edward_K
Ну да все тут экстрасенцы и могут по обрывам мыслей сказать в чем дело. Код где? Либо действительно зависит, либо в update set используются поля-массивы или данные другой view. Logstrtofile универсальное решение для поиска ошибок. Ну или отладчик VIP но эт сложней.

Re: Ошибка при выполнении алгоритма

Добавлено: 22 окт 2014, 11:14
Руслан
Alg_5100:

Код: Выделить всё

CONST
#include galnet.csc    // константы статус-строк Галактики
#include fldcolor.inc  // цвета в Галактике
#include GLOCONST.INC
#include KauConst.inc
#include mnplan.inc
end;


#include galnet.ccm;   // константы пользовательских команд

end;

#include uAlgor.vih
#include oAlgSetup.vih

#component "M_Mnplan"

VipInterface Algoritm_5100 Implements oAlgoritm_Sys;
Interface Algoritm_5100 '' (,hcNoContext,) EscClose, Cyan;

Create View
Var
  CurSoprDoc : comp;
  cWorkFormPl : Comp;
  fPreTuneOk, fVis : Boolean;
  wEvnCode : Word;
  sEvnLine : String;
  iSetup      : oAlgoritmSetup;
As Select
 *
From
  KatSopr (readonly),
  SpSopr,                      // основная накладная
  KlPrice (readonly),
  Prices (readonly),
  FormPl (ReadOnly)

Where
((
      CurSoprDoc         == KatSopr.Nrec          // позиционирование на основную накладную
  and CurSoprDoc         == SpSopr.cSopr
  and SpSopr.cPriceList  == KlPrice.NRec
  and Prices.cKlPrice    == Prices.Nrec
  and cWorkFormPl        == FormPl.NRec
));

Exception ExUser1, ExUser2, ExUser3, ExUser4, ExUser5;

//============================================================================
Window wnTuneGeneral 'Основные параметры настройки' (,, sci1Esc) EscClose;
//============================================================================
//  Show at (,,45,7);
Embedded scTuneGeneral Interface iSetup;
End;
End;  //'window

//=======================================================================
Procedure OnCloseParentWindow( wFlag:Word );
//-----------------------------------------------------------------------
{
 fPreTuneOk := True;
 CloseWindow(wnTuneGeneral);
}

//=======================================================================
Function GetNum : word;
//-----------------------------------------------------------------------
{
 GetNum := 5100;
}

//=======================================================================
function GetName : string;
//-----------------------------------------------------------------------
{
 GetName := 'VIP-алгоритм обновления цены в накладных на приход ГП';
}

//=======================================================================
Function GetMemo ( st:oSteckCommonString ) : Boolean;
//-----------------------------------------------------------------------
{
 GetMemo := True;

 st.push(string(''));
 st.push(string(''));
 st.push(string(''));
}

//=======================================================================
Function GetNameInter : String;
//-----------------------------------------------------------------------
{
 GetNameInter := 'Algoritm_5100' ;
}

//=======================================================================
Function GetNameInterPr : String;
//-----------------------------------------------------------------------
{
 GetNameInterPr := 'AlgoritmSetup_5100' ;
}

//=======================================================================
// 'ИНИЦИАЛИЗАЦИЯ АЛГОРИТМА'
//-----------------------------------------------------------------------
//'коды ситуаций - до 49 включительно
Function InitInter( Var pt:TRecAcc ) : Boolean;
{
_try
{
 InitInter := False;

 pt.Visua    := Word(0);
 pt.MessEnd  := Word(0);

 if ((pt.FlagRun and 16) > 0)
 {
  FormPl.Buffer := Type$FormPl(pt.stFormPl);
  cWorkFormPl := Comp(0);
 }
 else
 {
  cWorkFormPl := pt.cFormPl;
  if (GetFirst FormPl <> tsOk)
  {
   wEvnCode := 1;
   sEvnLine := 'Пользовательский алгоритм не найден (скорее всего, он был удален)';
   _raise ExUser2;
  }
 }

 if ((FormPl.ResWord[3] and 1) > 0)
 {
  //---------------------------------'Подтверждение параметров'
  if (Not LoadVipRef (iSetup, 'AlgoritmSetup_5100'))
  {
   wEvnCode := 5;
   sEvnLine := 'Системная ошибка !!!'#13' '+
               'Не загружен интерфейс <' + 'AlgoritmSetup_53' + '>';
   _raise ExUser2;
  }

  if (Not iSetup.asInitInter(cWorkFormPl))
   Exit;

  BindEvent(OnCloseParentWindow, iSetup.asCloseParentWindow);

  fPreTuneOk := False;
  RunWindowModal(wnTuneGeneral);
  if (Not fPreTuneOk)
   Exit;
  ReReadRecord(#FormPl);
  //-----------------------------------------------------------
 }

 InitInter := True;
}  //'_try

_except
 on ExUser1:
  pt.Error := 1;

 on ExUser2:
 {
  Message(''#3 + String(wEvnCode) + ' ' + sEvnLine, Error);
 }

_finally
{
 //'
}
}

//=======================================================================
// 'ЗАВЕРШЕНИЕ РАБОТЫ С ИНТЕРФЕЙСОМ'
//-----------------------------------------------------------------------
Function DoneInter( Var pt:TRecAcc ) : Boolean;
{
 DoneInter := True;

 if (Not NullVipRef(iSetup))
 {
  iSetup.asDoneInter();
  FreeVipInterface(iSetup);
 }
}

//=======================================================================
Function RunInter( wflag:Word; Var pt:TRecAcc ) : Boolean;
{
    var ttn_sum : double;
    var ttn_ves : double;
    var exchange_ttn : double;
    var act_sum : double;
    var common_ttn_sum : double;
    var ttn_act_sum : double;
    var order_nrec : comp;
    var pr_rub : double;
    var okr_pr_rub : double;
    var pr_val : double;
    var okr_pr_val : double;
    var sumOrder : double;
    var sumOrderVal : double;
    var sumOrderOkr : double;
    var sumOrderOkrVal : double;
    var type_mc : double;

    var kod_mc : string;
    var koef_akt : double;

    _try
    {
	RunInter := False;
	fVis := (pt.Visua = Word(0));

	CurSoprDoc := pt.cpNrec;

	if (getFirst Katsopr where (('505' == katsopr.vidsopr )) = tsOk)
	{
		_loop SpSopr where ((0001000000003566h == SpSopr.cPriceList))
		{
			if (getFirst Prices where ((comp('0001000000003566h') == Prices.cKlPrice and SpSopr.cMcUsl == Prices.cThing)) = tsOk )
			{
				update SpSopr set SpSopr.Price = Prices.Price;
			}
		}
	}

	RunInter := True;
    }

    _except
	on ExUser1:
	    pt.Error := 1;

	on ExUser2:
	{
	    Message(''#3 + String(wEvnCode) + ' ' + sEvnLine, Error);
	}

    _finally
    {
	DoneInter(pt);
    }
}
End.
Setup_5100:

Код: Выделить всё

CONST
#include galnet.csc    // константы статус-строк Галактики
#include fldcolor.inc  // цвета в Галактике
#include GLOCONST.INC 
#include KauConst.inc
#include mnplan.inc
end;

!#include galnet.ccm end;   // константы пользовательских команд
#include galnet.ccm;   // константы пользовательских команд

end;

#include oAlgSetup.vih

#component "M_Mnplan" 

VipInterface AlgoritmSetup_5100 Implements oAlgoritmSetup;
Interface AlgoritmSetup_5100 '' (,hcNoContext,) EscClose;
Show at (,,,50);

#include constpl.vpp

Procedure FieldAccess; Forward;
Procedure MySetTitle; Forward;
Procedure SetTunes; Forward;

//Var
 //'------------------------------------------------'объекты
 //comAlg         : oCommonFunAlg;

Create View
Var
 cFormPl : Comp;
 //
 //: Word;
 //
 //: String;
 fSimplyTune
 : Boolean;
As Select
 if (FormPl.ResWord[1] = toZClient, Indent.NoInd, MnPlan.Name)
  (FieldName = fDocName),

 FormPl.*,
 MnPlan.*,
 Indent.*,
 WayAccou.*
From
 FormPl,
 MnPlan                     (ReadOnly),
 Indent                     (ReadOnly),
 WayAccou                   (ReadOnly)
Where ((
        cFormPl                 == FormPl.NRec                 and
        FormPl.ResComp[1]       == WayAccou.NRec               and
        FormPl.ResComp[2]       == MnPlan.NRec                 and
        FormPl.ResComp[2]       == Indent.NRec
      ))
;

//'Last .ResWord = 3

Parameters
 cFormPl

TabbedSheet bottom tsTunning;
Show At (,,,44);

Screen ScrFormPl_Source 'Документ' (,,sci1Esc);
Table FormPl;
Fields
 FormPl.ResWord[1] ('Тип документа',,sci13Esc) :
  [List
   toPlan     'Производственный план',
   toNeedMt   'Потребность в материалах',
   toNeedTr   'Потребность в трудовых ресурсах',
   toNeedEq   'Потребность в оборудовании',
   toPlanSb   'План сбыта',
   toPlanSnab 'План снабжения',
   toMnfZakaz 'Производственный заказ',
 #ifdef PlanOper
   toPlanOper      'Пооперационный план',
 #end
   toCorpoNeed     'Корпоративная потребность',
   toCorpoDelivery 'Корпоративный план поставок',
   toCorpoManuf    'Корпоративный план производства',
   toCorpoBalance  'Баланс движения продукции',
   toZClient  'Заявка'
  ], Protect;
 WayAccou.Name ('Наименование шаблона',,sci13Esc) : Protect, PickButton;
 FormPl.ResWord[2] ('Документ',,) : NoProtect;
 fDocName ('Наименование документа',,sci13Esc) : Protect, PickButton,
  {Font = {BackColor = if( (FormPl.ResWord[2] = 1) and ((Not IsValid(tnMnPlan)) and (Not IsValid(tnIndent))), ColorNeed, 0)}};
<<

`Тип документа`.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
`Шаблон`       .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
`Документ:`
  (.) Текущий на момент запуска алгоритма`
  (.) Другой`                              .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>>
End;  //'screen

Screen ScrFormPl_Calc 'Расчет' (,,sci1Esc);
Table FormPl;
Fields
 FormPl.ResWord[3] ('Разные параметры',,) : NoProtect;
<<

  [.] Подтвердить настройку перед запуском алгоритма`
>>
End;  //'screen
End;  //'ts

Screen ScrForButtons;
Show At (,45,,);
Buttons
   cmOk, Default,, 'Сохранить настройки и закрыть окно',,;
   cmCancel,,, 'Закрыть окно',,;
<<
                   <. Сохранить .>       <. Отменить .>
>>
End;  //'screen

Screen ScrForButtons_;
Show At (,45,,);
Buttons
   cmOk, Default,, 'Сохранить настройки и запустить алгоритм',,;
   cmCancel,,, 'Закрыть окно',,;
<<
                   <. Расчет .>       <. Отменить .>
>>
End;  //'screen

//=======================================================================
Procedure FieldAccess;
//-----------------------------------------------------------------------
{
 //'Документ
 if (FormPl.ResWord[1] = toZClient)
  ClearFieldOption(#WayAccou.Name, ofSelectable);
 else
  SetFieldOption(#WayAccou.Name, ofSelectable);

 //'Документ
 if (FormPl.ResWord[2] = 1)
  SetFieldOption(#fDocName, ofSelectable);
 else
  ClearFieldOption(#fDocName, ofSelectable);
}

//=======================================================================
// 'ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ ПРИ УСТАНОВКЕ ШАБЛОНА'
//-----------------------------------------------------------------------
Procedure OnInsertWayAccou( p_cWayAccou:Comp; p_fInside:Boolean );
{
 Var cFormPlDef : Comp;

 Set FormPl.ResComp[1]  := p_cWayAccou;

 if (GetFirst WayAccou <> tsOk)
  Exit;

 Set FormPl.ResWord[1] := WayAccou.TypeObj;

 if (p_fInside)
 {
  //'
 }
 else
 {
  Update Current FormPl;
 }
}

//=======================================================================
// 'ПРОВЕРКА КОРРЕКТНОСТИ НАСТРОЙКИ'
//-----------------------------------------------------------------------
Function CheckTune : Boolean;
{
 CheckTune := False;

 if ( (FormPl.ResWord[2] = 1) and ((Not IsValid(tnMnPlan)) and (Not IsValid(tnIndent))))
 {
  if ( Message(''#3'Без указания документа алгоритм работать не будет,'#13#3+
              'закрыть окно настройки ?', YesNo) = cmNo )
  {
   SetFormat(ScrFormPl_Source);
   SelectFormat(ScrFormPl_Source);
   SelectField(#fDocName);
   Exit;
  }
 }

 CheckTune := True;
}

//=======================================================================
Function InitInter( p_cFormPl:Comp; p_fSimplyTune:Boolean ) : Boolean;
//-----------------------------------------------------------------------
{
 InitInter := False;

 fSimplyTune := p_fSimplyTune;

 if (Not fSimplyTune)
  cFormPl := p_cFormPl;

 if (GetFirst FormPl <> tsOk)
 {
  Message(''#3'Ошибка поиска в таблице FormPl:'#13#3+
          'Записи FormPl.NRec = ' + Trim(String(cFormPl)) + ' не существует'
          ,Error+CancelButton);
  Exit;
 }

 //==========================='загружаем интерфейсы'=====================
 //if (Not LoadVipRef (comAlg, 'CommonFunAlg'))
 //{
 // Message('Системная ошибка !!!'+
 //         'Не загружен интерфейс <' + 'CommonFunAlg' + '>', Error+CancelButton);
 // Exit;
 //}
 //======================================================================

 SetTunes;
 FieldAccess;
 MySetTitle;

 InitInter := True;
}

//=======================================================================
Function DoneInter : Boolean;
//-----------------------------------------------------------------------
{
 DoneInter := True;

 //if (Not NullVipRef(comAlg))
  //FreeVipInterface(comAlg);
}

//=======================================================================
// 'ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ ПРИ СОЗДАНИИ НОВОЙ ЗАПИСИ'
//-----------------------------------------------------------------------
Procedure OnSetDefault;
{
 Set FormPl.ResWord[1] := toPlan;

 Update Current FormPl;
}

//=======================================================================
//'ИНИЦИАЛИЗАЦИЯ ИНТЕРФЕЙСА
//-----------------------------------------------------------------------
Function asInitInter( p_cFormPl:Comp ) : Boolean;
{
 asInitInter := InitInter(p_cFormPl, False);
}

//=======================================================================
//'ЗАВЕРШЕНИЕ РАБОТЫ С ИНТЕРФЕЙСОМ
//-----------------------------------------------------------------------
Function asDoneInter : Boolean;
{
 asDoneInter := DoneInter();
}

//=======================================================================
//'ПО КОМАНДЕ CMSETDEFAULT
//-----------------------------------------------------------------------
Procedure asOnCmSetDefault;
{
 OnSetDefault;
}

//=======================================================================
//'ПРИ ВСТАВКЕ НАСТРОЙКИ В ШАБЛОН
//-----------------------------------------------------------------------
Procedure asOnSetWayAccou( p_cWayAccou:Comp );
{
 OnInsertWayAccou(p_cWayAccou, False);
}

//=======================================================================
// 'ЗАГОЛОВОК ОКНА'
//-----------------------------------------------------------------------
Procedure MySetTitle;
{
 Var sTuneName : String;

 sTuneName := 'Настройка алгоритма "' + FormPl.Name + '"';

 if (FormPl.ResWord[40] > 0)
  sTuneName := sTuneName + '. Включена отладочная информация';

 SetWindowTitle(wnMainWindow, sTuneName);
}

//=======================================================================
Procedure SetTunes;
//-----------------------------------------------------------------------
{
 if (fSimplyTune)
 {
  SetFormat(ScrForButtons);
 }
 else
 {
  //'закрываемые элементы для подтверждения настройки
  //SetFormatEnabled(ScrFormPl_Calc, False);
  //ClearFieldOption(#FormPl.ResWord[2], ofSelectable);
  //ClearFieldOption(#FormPl.ResWord[8], ofSelectable);
  //ClearFieldOption(#FormPl.ResWord[9], ofSelectable);
  SetFormat(ScrForButtons_);
 }
}

Panel pnFormPl;
Table FormPl;
//=======================================================================
HandleEvent  //'panel
//-----------------------------------------------------------------------
cmCheckField:
{
 Case CurField of
  #FormPl.ResWord[2],  //'переключатель документа
  #FormPl.ResWord[1]   //'тип документа
  :
  {
   if (CurField = #FormPl.ResWord[1])
    if (Word(OldFieldValue) <> FormPl.ResWord[1])
    {
     Set FormPl.ResComp[1] := Comp(0);
     Set FormPl.ResComp[2] := Comp(0);
    }

   FieldAccess;
  }
 End;  //'case
}
End;  //'he panel
End;  //'panel

//=======================================================================
HandleEvent  //'he interface
//-----------------------------------------------------------------------
cmInit:
{
 if (Not InitInter(cFormPl, True))
 {
  Abort;
  Exit;
 }
}

cmOk:
{
 Update Current FormPl;
 if (CheckTune())
 {
  if (fSimplyTune)
   CloseInterface(cmOk);
  else
   asCloseParentWindow(Word(0));
 }
}

cmPick:
{
 Case CurField of
  #fDocName:  //'документ-предложение
  {
   if (FormPl.ResWord[1] = toZClient)
   {
    if ( RunInterface('Bookings', 1, FormPl.ResComp[2], -1) = cmOk ) {};
   }
   else
    if (RunInterface('GetMnPlan', Word(1), FormPl.ResWord[1], FormPl.ResComp[2], FormPl.ResComp[1]) != cmCancel) {};
  }

  #WayAccou.Name:
  {
   Var cWay : Comp;

   cWay := FormPl.ResComp[1]
   if (RunInterface('NastrPl', FormPl.ResWord[1], cWay, Word(1)) != cmCancel)
   {
    OnInsertWayAccou(cWay, True);
   }
  }
 End;  //'case
}

cmDelOnProtect:
{
 Case CurField of
  #WayAccou.Name:
  {
   if (FormPl.ResComp[1] != Comp(0))
    Set FormPl.ResComp[1]  := Comp(0);
   Stop;
  }

  #fDocName:
  {
   if (FormPl.ResComp[2] != Comp(0))
    Set FormPl.ResComp[2] := Comp(0);
   Stop;
  }
 End;  //'case
}

cmDone:
{
 DoneInter();
}

cmNal:
{
 if (FormPl.ResWord[40] = 0)
  Set FormPl.ResWord[40] := 1;
 else
  Set FormPl.ResWord[40] := 0;
 MySetTitle;
}
End;  //'he interface
End.  //'interface

Re: Ошибка при выполнении алгоритма

Добавлено: 22 окт 2014, 11:27
edward_K
and Prices.cKlPrice == Prices.Nrec
Вы тут ничего не попутали?
наверное хотели написать
and Klprice.nrec == Prices.cKlPrice
В логе компиляции наверняка получили предупреждение.

Re: Ошибка при выполнении алгоритма

Добавлено: 22 окт 2014, 11:36
Руслан
edward_K писал(а):and Prices.cKlPrice == Prices.Nrec
Вы тут ничего не попутали?
наверное хотели написать
and Klprice.nrec == Prices.cKlPrice
В логе компиляции наверняка получили предупреждение.
В логе ничего не было. Исправил, алгоритм отрабатывает без ошибок, но цену из прайса не апдейтит...

Re: Ошибка при выполнении алгоритма

Добавлено: 22 окт 2014, 11:43
edward_K
Ну дальше ищите сами.
Вот сие добавьте в начало основного фейса.

Код: Выделить всё

var logfilenm:string;
Procedure MyLog(w:string);
{ if logfilenm=''
  { logfilenm:=GetStringParameter('Files','OutputFilesDirectory',0)
                               +'!ALG_5000.log'
    if fileexist(logfilenm) deletefile(logfilenm)
  }
  logstrtofile(logfilenm,_DateTimeToStr(_CurDateTime,'DD/MM/YYYY HH:NN:SS ') +w)
}
И юзайте по коду с понятным вам и не только сообщениями.
Вообще дурной тон прописывать явно nrec.