Hi All,
I have a job Queue tha execute a code unit. The code unit contain some variable of dialog user interface. when NAS try to execute the job it log the following error:
You cannot use C/AL variables of type DIALOG when running the Application Server for Microsoft Dynamics NAV Classic.
The code unit is a standard 5044076 PCF Engine
Haw can I excute this code unit from NAS?
Thanks for help.
0
Comments
<EDIT> Sorry bbrown..Did not see your post..
-Mohana
http://mohana-dynamicsnav.blogspot.in/
https://www.facebook.com/MohanaDynamicsNav
*************************************************************************
POLARIS TT-30468
Created
22.03.2009
RHJ
*************************************************************************
[Functions]
Bool : ExecutePFC_COMMIT(PFCNo)
Bool : ReservePFC_COMMIT(PFCNo)
Bool : ReleasePFC_COMMIT(PFCNo)
Bool : PostPFC_COMMIT(PFCNo)
Bool : SetStatus_COMMIT(PFCNo, LineNo, Status)
Bool : RetryPFCLine_COMMIT(PFCNo, PFCLineNo, UseDialog);
Text[1024] : GetError()
*************************************************************************
POLARIS TT-33561
08/12/2009
Only Post PFC that are at least 1 minute old.
MBH
*************************************************************************
POLARIS TT-33992
16/12/2009
Carriage Return in PFC description
MBH
*************************************************************************
TB-ALG TT35971
RTC adaptation
//**************************************************************************
// Project : TOPNET-Billing
// Réf du FOB : Mis à jour du référentiel
// Description :
// Date de création : 12/04/2010
// Auteur : z.gharsallaoui
// Version : V1.0
//**************************************************************************
// Historique des modifications
// ***********************
// Date ! Par ! Ref FOB ! Objet de la modification
//**************************************************************************
// 11/11/2011 ! ZDE ! LOT0.LIV0 ! Scheduler(): désactiver l'affichage de Window.
// 00/00/9999 ! ZDE ! LOT0.LIV0 !
// 00/00/9999 ! ZDE ! LOT0.LIV0 !
//
//
OnRun(VAR Rec : Record "Job Queue Entry")
CLEAR(ErrorMsg);
CLEARLASTERROR;
CASE RunType OF
RunType::Scheduler,
RunType::Execute,
RunType::SetStatus :
BEGIN
IF Setup."PFC Nos." = '' THEN
Setup.GET();
END;
END;
CASE RunType OF
RunType::Scheduler : Scheduler();
RunType::ReservePFC : ReservePFC();
RunType::Execute : ExecutePFC();
RunType::ExecuteLine : ExecutePFCLine();
RunType::ExecuteAction : ExecuteAction();
RunType::FinalisePFC : FinalisePFC();
RunType::SetLineStatus : SetLineStatus();
RunType::SetStatus : SetStatus();
RunType::PostPFC : PostPFC();
END;
ExecutePFC_COMMIT(PFCNo : Code[20]) : Boolean
//
// Execute PFC
//
// After successfull execution, the PFC will be owned by either:
// [Status] [Owned by]
// Ready|Done Scheduler
// Waiting Apropriate interface
// Error GUI or other
//
CLEAR(ErrorMsg);
CLEARLASTERROR;
COMMIT;
SELECTLATESTVERSION;
ExecuteOK := TRUE;
// Lock PFC by setting status to ::Executing
PFCEngine._SetVars(RunType::ReservePFC, PFCNo, 0, PFCHeaderRec.ExecuteStatus::Executing, '');
IF PFCEngine.RUN THEN BEGIN
// Execute the PFC.
PFCEngine._SetVars(RunType::Execute, PFCNo, 0, 0, '');
IF NOT PFCEngine.RUN THEN BEGIN
ExecuteOK := FALSE;
ErrorMsg := PFCEngine.GetError();
END;
// New status is determined by the execute function but applied by Finalise function.
PFCEngine._GetLastExecuteStatus(PFCExecuteStatus);
// Finalise PFC, by setting control vars
PFCEngine._SetVars(RunType::FinalisePFC, PFCNo, 0, PFCExecuteStatus, '');
IF NOT PFCEngine.RUN THEN BEGIN
ExecuteOK := FALSE;
ErrorMsg := PFCEngine.GetError();
END;
END ELSE BEGIN
ExecuteOK := FALSE;
ErrorMsg := PFCEngine.GetError();
END;
COMMIT;
EXIT(ExecuteOK);
ReservePFC_COMMIT(PFCNo : Code[20]) : Boolean
//
// Reserve PFC
//
CLEAR(ErrorMsg);
CLEARLASTERROR;
COMMIT;
SELECTLATESTVERSION;
IF NOT PFCHeaderRec.GET(PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, PFCNo);
EXIT(FALSE);
END;
IF NOT (PFCHeaderRec.ExecuteStatus IN [PFCHeaderRec.ExecuteStatus::Waiting,
PFCHeaderRec.ExecuteStatus::Error]) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_NotStatusWaitingErr);
EXIT(FALSE);
END;
PFCEngine._SetVars(RunType::ReservePFC, PFCNo, 0, 0, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
EXIT(FALSE);
END;
EXIT(TRUE);
ReleasePFC_COMMIT(PFCNo : Code[20]) : Boolean
//
// Release PFC
//
CLEAR(ErrorMsg);
CLEARLASTERROR;
COMMIT;
SELECTLATESTVERSION;
IF NOT PFCHeaderRec.GET(PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, PFCNo);
EXIT(FALSE);
END;
// If PFC is New, a Release means ready for execution
IF PFCHeaderRec.ExecuteStatus = PFCHeaderRec.ExecuteStatus::New THEN
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;
PFCEngine._SetVars(RunType::FinalisePFC, PFCNo, 0, PFCHeaderRec.ExecuteStatus, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
EXIT(FALSE);
END;
EXIT(TRUE);
PostPFC_COMMIT(PFCNo : Code[20]) : Boolean
CLEAR(ErrorMsg);
CLEARLASTERROR;
COMMIT;
SELECTLATESTVERSION;
PFCEngine._SetVars(RunType::PostPFC, PFCNo, 0, 0, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
EXIT(FALSE);
END;
EXIT(TRUE);
SetStatus_COMMIT(PFCNo : Code[20];LineNo : Integer;Status : Text[250]) : Boolean
CLEAR(ErrorMsg);
CLEARLASTERROR;
COMMIT;
SELECTLATESTVERSION;
PFCEngine._SetVars(RunType::SetStatus, PFCNo, LineNo, 0, Status);
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
EXIT(FALSE);
END;
COMMIT;
EXIT(TRUE);
RetryPFCLine_COMMIT(PFCHeaderNo : Code[20];PFCLineNo : Integer;UseDialog : Boolean) : Boolean
CLEAR(ErrorMsg);
CLEARLASTERROR;
COMMIT;
SELECTLATESTVERSION;
PFCSetup.GET;
IF NOT PFCLineRec.GET(PFCHeaderNo, PFCLineNo) THEN
EXIT(FALSE);
IF PFCLineRec.ExecuteStatus = PFCLineRec.ExecuteStatus::Error THEN BEGIN
IF TransmissionRec.HasLineTransactions(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.") THEN BEGIN
//HBR
UseDialog:=FALSE;
IF UseDialog THEN BEGIN
TransmissionAction := STRMENU(TXT_HandleTransactions);
IF (NOT TransmissionRec.HasErrorTransactions(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr."))
AND (TransmissionAction = TransmissionAction::Resend) THEN
;
//ERROR(ERR_NoErrorTransaction);
IF TransmissionAction = TransmissionAction::None THEN
;
// ERROR('');
END ELSE
TransmissionAction := TransmissionAction::Resend;
END;
IF UseDialog THEN BEGIN
IF TransmissionAction <> TransmissionAction::Resend THEN
;
// IF NOT CONFIRM(TXT_WarningInconsistence) THEN
// ERROR('');
END;
IF NOT PFCEngine.ReservePFC_COMMIT(PFCHeaderNo) THEN
IF UseDialog THEN
;
// ERROR(PFCEngine.GetError())
//ELSE
//EXIT(FALSE);
PFCHeaderRec.GET(PFCHeaderNo);
IF TransmissionAction = TransmissionAction::Resend THEN BEGIN
PFCLineRec.MODIFYWait();
CLEAR(PFCHeaderRec."Status Description");
PFCHeaderRec.VALIDATE(StatusCode, PFCSetup.WaitingStatus);
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Waiting;
PFCHeaderRec.MODIFY();
END ELSE BEGIN
IF TransmissionAction = TransmissionAction::Retry THEN
TransmissionRec.CancelTransactions(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.");
PFCLineRec.MODIFYRetry(0DT);
CLEAR(PFCHeaderRec."Status Description");
PFCHeaderRec.VALIDATE(StatusCode, PFCSetup.ReadyStatus);
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;
PFCHeaderRec.MODIFY();
END;
IF UseDialog THEN BEGIN
{ Window.OPEN(STRSUBSTNO(TXT_ExecutingPFC + '''%1''\#2##########################', PFCHeaderNo),
PFCHeaderNo, PFCHeaderRec.Description); }
IF NOT PFCEngine.ExecutePFC_COMMIT(PFCHeaderNo) THEN
;
//ERROR(PFCEngine.GetError());
//Window.CLOSE;
END ELSE BEGIN
PFCEngine.ReleasePFC_COMMIT(PFCHeaderNo);
END;
IF TransmissionAction = TransmissionAction::Resend THEN
TransmissionRec.RetryErrors(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.");
EXIT(TRUE);
END ELSE
IF UseDialog THEN
;
//ERROR(STRSUBSTNO(ERR_PFCLineNotInStatus, PFCLineRec.ExecuteStatus::Error));
GetError() : Text[1024]
IF ErrorMsg = '' THEN
ErrorMsg := GETLASTERRORTEXT;
//TT-33992 16/12/09 MBH >>>>
CRLF := 13;
SPACE := 32;
ErrorMsg := CONVERTSTR(ErrorMsg,FORMAT(CRLF),FORMAT(SPACE));
//TT-33992 16/12/09 MBH <<<<
EXIT(ErrorMsg);
-- Local Functions --()
Scheduler()
//message('%1',PFCHeaderRec."PFC Nr.");
StartTime := Now();
// Check for PFCs with Max Locktime exceeded.
//
CheckLockTimeout();
COMMIT;
// Check for Idle PFCs
//
CheckMaxIdle();
COMMIT;
// Execute ready PFCs.
//
PFCHeaderRec.RESET;
PFCHeaderRec.SETCURRENTKEY(ExecuteStatus, ExecutePriority, "Next Execution DateTime");
// ZDE OLD PFCHeaderRec.SETRANGE(ExecuteStatus, PFCHeaderRec.ExecuteStatus::Ready);
PFCHeaderRec.SETRANGE(ExecuteStatus, PFCHeaderRec.ExecuteStatus::New,PFCHeaderRec.ExecuteStatus::Ready);
PFCHeaderRec.SETFILTER("Next Execution DateTime", '..%1', StartTime);
PFCHeaderRec.SETFILTER("Latest Execution", '..%1', StartTime);
IF PFCHeaderRec.FINDFIRST() THEN BEGIN
MaxCount := PFCHeaderRec.COUNT;
{Progress.OPEN(TXT_ExecutingPFC + '\'+
TXT_ExecTime + ' #1######\'+
'#2#### '+TXT_Of+' #3######\'+
'#4#####################\' +
'@\',
ExecTime, Counter, MaxCount, PFCHeaderRec.Description); }
// Loop the ready PFCs, always keeping highest prio records first.
WHILE PFCHeaderRec.FINDFIRST AND (NOT MaxTimeExceeded) DO BEGIN
Counter += 1;
TmpInt := Now() - StartTime;
ExecTime := 000000T + TmpInt;
//zde
// Progress.UPDATE;
//zde
// Progress.UPDATE(5, (Counter/10000)*9999 DIV (MaxCount/10000));
IF NOT ExecutePFC_COMMIT(PFCHeaderRec."PFC Nr.") THEN
LastError := ErrorMsg;
SELECTLATESTVERSION;
// Check if we have been running too long
MaxTimeExceeded := ( Setup.MaxRuntime > 0 )
AND (Now() >= (StartTime + ( Setup.MaxRuntime * 60000 ) ));
END;
// Progress.CLOSE();
END;
IF MaxTimeExceeded THEN
EXIT;
COMMIT;
// Post PFCs
PFCHeaderRec.RESET;
PFCHeaderRec.SETCURRENTKEY(ExecuteStatus, ExecutePriority, "Next Execution DateTime");
PFCHeaderRec.SETRANGE(ExecuteStatus, PFCHeaderRec.ExecuteStatus::Done);
PFCHeaderRec.SETFILTER(PFCHeaderRec."Latest Execution",'<%1|%2',CREATEDATETIME(TODAY,TIME - (60*1000)),0DT); //TT-33561
IF PFCHeaderRec.FINDFIRST THEN BEGIN
MaxCount := PFCHeaderRec.COUNT;
CLEAR(Counter);
{ Progress.OPEN(TXT_PostingPFC + '\'+
TXT_ExecTime + ' #1######\'+
'#2#### '+TXT_Of+' #3######\'+
'#4#####################\' +
'@\',
ExecTime, Counter, MaxCount, PFCHeaderRec.Description); }
IF PFCHeaderRec.FINDSET(FALSE, FALSE) THEN REPEAT
Counter += 1;
TmpInt := Now() - StartTime;
ExecTime := 000000T + TmpInt;
//zde
// Progress.UPDATE;
//zde
// Progress.UPDATE(5, (Counter/10000)*9999 DIV (MaxCount/10000));
PFCEngine._SetVars(RunType::PostPFC, PFCHeaderRec."PFC Nr.", 0, 0, '');
IF NOT PFCEngine.RUN THEN BEGIN
IF PFCHeaderRec2.GET(PFCHeaderRec."PFC Nr.") THEN BEGIN
PFCHeaderRec2.VALIDATE(StatusCode, Setup.ErrorStatus);
PFCHeaderRec2."Status Description" := DELSTR(TXT_PostingError + ':' + PFCFunctions.GetError(),
MAXSTRLEN(PFCHeaderRec2."Status Description")+1);
PFCHeaderRec2.MODIFY(FALSE);
COMMIT;
PFCEngine._SetVars(RunType::FinalisePFC, PFCHeaderRec."PFC Nr.", 0, PFCHeaderRec.ExecuteStatus::Error, '');
IF NOT PFCEngine.RUN() THEN
LastError := PFCEngine.GetError();
END;
END;
// Check if we have been running too long
MaxTimeExceeded := ( Setup.MaxRuntime > 0 )
AND (Now() >= (StartTime + ( Setup.MaxRuntime * 60000 ) ));
UNTIL MaxTimeExceeded
OR (PFCHeaderRec.NEXT = 0);
END;
ReservePFC()
//
// Reserve PFC (for execution)
//
SELECTLATESTVERSION;
ErrorMsg := STRSUBSTNO(ERR_UnableToLockPFC, _PFCNo);
PFCHeaderRec.LOCKTABLE;
IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
//ERROR(ErrorMsg);
END;
IF NOT GetMySession(SessionRec) THEN
;
// ERROR(ErrorMsg);
// Exit if someone else has a lock on this.
IF (PFCHeaderRec.LockUser <> '')
OR (PFCHeaderRec.LockSession > 0) THEN BEGIN
IF (PFCHeaderRec.LockUser <> UPPERCASE(USERID))
OR (PFCHeaderRec.LockSession <> SessionRec."Connection ID") THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_LockedBy, _PFCNo, PFCHeaderRec.LockUser, PFCHeaderRec.LockSession);
// ERROR(ErrorMsg);
END;
END;
// Make sure we are the only ones executing it
//IF _StatusOption <> 0 THEN //TB-ALG TT35971
IF _Status <> 0 THEN
PFCHeaderRec.ExecuteStatus := _Status;
//PFCHeaderRec.ExecuteStatus := _StatusOption; //TB-ALG TT35971
// Update lock information
PFCHeaderRec.LockUser := USERID;
PFCHeaderRec.LockSession := SessionRec."Connection ID";
PFCHeaderRec.LockTime := Now();
ErrorMsg := STRSUBSTNO(ERR_ModifyPFCFailed, _PFCNo);
PFCHeaderRec.MODIFY(FALSE);
COMMIT;
CLEAR(ErrorMsg);
FinalisePFC()
//
// Finalise PFC execution / Release PFC
// Calculating priority, setting status etc.
//
SELECTLATESTVERSION;
ErrorMsg := STRSUBSTNO(ERR_UnableToLockPFC, _PFCNo);
PFCHeaderRec.LOCKTABLE;
PFCHeaderRec.GET(_PFCNo);
// Set executiondate to atleast NOW, to prevent race in the scheduler FINDFIRST()
IF PFCHeaderRec."Next Execution DateTime" < Now() THEN
PFCHeaderRec.VALIDATE("Next Execution DateTime", Now());
// 0 signals a general update, we should not touch the status
//IF _StatusOption > 0 THEN //TB-ALG TT35971
// PFCHeaderRec.ExecuteStatus := _StatusOption; //TB-ALG TT35971
IF _Status > 0 THEN
PFCHeaderRec.ExecuteStatus := _Status;
PFCHeaderRec."Latest Execution" := Now();
PFCHeaderRec."Executed By" := USERID;
CLEAR(PFCHeaderRec.LockUser);
CLEAR(PFCHeaderRec.LockSession);
CLEAR(PFCHeaderRec.LockTime);
ErrorMsg := STRSUBSTNO(ERR_ModifyPFCFailed, _PFCNo);
PFCHeaderRec.MODIFY(FALSE);
COMMIT;
CLEAR(ErrorMsg);
ExecutePFC()
//
// Execute the PFC.
//
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
Continue := TRUE;
//
// Execute Ready PFC lines
//
PFCLineRec.SETCURRENTKEY("PFC Nr.", "Line Nr.");
PFCLineRec.SETRANGE("PFC Nr.", _PFCNo);
PFCLineRec.SETRANGE("Line Nr.", 0, 999999998);
PFCLineRec.SETFILTER(ExecuteStatus, '<>%1&<>%2', // all interesting lines.
PFCLineRec.ExecuteStatus::Ok,
PFCLineRec.ExecuteStatus::Skipped);
WHILE PFCLineRec.FINDFIRST
AND (Continue) DO BEGIN
// Calculate line execution date
IF PFCLineRec."Execution Date" = 0D THEN
PFCLineRec."Execution Date" := WORKDATE;
NextExecuteDate := CREATEDATETIME(PFCLineRec."Execution Date", PFCLineRec."Execution Time");
Continue := PFCLineRec.ExecuteStatus = PFCLineRec.ExecuteStatus::New;
Continue := Continue AND (NextExecuteDate <= Now());
IF (Continue) THEN BEGIN
PFCEngine._SetVars(RunType::ExecuteLine, PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.", 0, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
IF ErrorMsg = '' THEN
ErrorMsg := STRSUBSTNO(ERR_UnknownErrorExecutingLine, PFCLineRec."Line Nr.");
Continue := FALSE;
END;
END;
SELECTLATESTVERSION;
END;
IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
// ERROR(ErrorMsg);
END;
IF ErrorMsg <> '' THEN BEGIN
// If PFC is (or should be) in error, ErrorMsg is already set.
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
END ELSE BEGIN
// Else determine status of the PFC
IF PFCLineRec.FINDFIRST THEN BEGIN
IF PFCLineRec."Execution Date" = 0D THEN
PFCLineRec."Execution Date" := WORKDATE;
NextExecuteDate := CREATEDATETIME(PFCLineRec."Execution Date", PFCLineRec."Execution Time");
CASE PFCLineRec.ExecuteStatus OF
PFCLineRec.ExecuteStatus::New :
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;
PFCLineRec.ExecuteStatus::Waiting :
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Waiting;
// If the pfc and line was already in Error state
// it is not executed and we should not overwrite the error message
PFCLineRec.ExecuteStatus::Error :
BEGIN
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
IF ErrorMsg = '' THEN
// use previous error from header.
ErrorMsg := PFCHeaderRec."Status Description";
IF ErrorMsg = '' THEN
// Undefined error
ErrorMsg := STRSUBSTNO(ERR_UnknownErrorExecutingLine, PFCLineRec."Line Nr.");;
END;
PFCLineRec.ExecuteStatus::StopPFC :
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Done;
ELSE BEGIN
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
ErrorMsg := STRSUBSTNO(ERR_UnexpectedStatus,
PFCLineRec.ExecuteStatus,
PFCLineRec."Line Nr.");
END;
END;
END ELSE BEGIN
// No more lines to execute
_ExecuteStatus := PFCHeaderRec.ExecuteStatus::Done;
END;
END;
// Update Header status codes and description
//
// On Error, ErrorMsg always contains the error description (returned from Action OR scheduler functions)
//
IF _ExecuteStatus = PFCHeaderRec.ExecuteStatus::Error THEN BEGIN
PFCHeaderRec.VALIDATE(StatusCode, Setup.ErrorStatus);
PFCHeaderRec."Status Description" := DELSTR(ErrorMsg, MAXSTRLEN(PFCHeaderRec."Status Description")+1);
END ELSE IF PFCHeaderRec.StatusCode = '' THEN BEGIN
// No status set by return code, revert to default.
CASE _ExecuteStatus OF
PFCHeaderRec.ExecuteStatus::Waiting :
PFCHeaderRec.VALIDATE(StatusCode, Setup.WaitingStatus);
PFCHeaderRec.ExecuteStatus::Ready :
PFCHeaderRec.VALIDATE(StatusCode, Setup.ReadyStatus);
PFCHeaderRec.ExecuteStatus::Done :
PFCHeaderRec.VALIDATE(StatusCode, Setup.DoneStatus);
END;
END;
IF PFCHeaderRec."A-Number" = '' THEN
PFCHeaderRec."A-Number" := PFCHeaderRec.ShowAnr;
// Set general execution parms.
PFCHeaderRec.VALIDATE("Next Execution DateTime", NextExecuteDate);
IF PFCHeaderRec."Max Idle Time" > 0 THEN
CalculateMaxIdle(PFCHeaderRec);
PFCHeaderRec.MODIFY;
COMMIT;
CLEAR(ErrorMsg);
ExecutePFCLine()
//
// Execute a single PFC Line.
//
CLEAR(ResultPFCLine);
// set line = inprogress (and clear control vars)
PFCEngine._SetVars(RunType::SetLineStatus, _PFCNo, _PFCLineNo, ResultPFCLine.ExecuteStatus::Initiated, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
// ERROR(ErrorMsg);
END;
// Reset header status code each time we execute a new line.
ErrorMsg := STRSUBSTNO(ERR_UnableToLockPFC, _PFCNo);
IF PFCHeaderRec.GET(_PFCNo) THEN BEGIN
CLEAR(PFCHeaderRec.StatusCode);
CLEAR(PFCHeaderRec."Status Description");
ErrorMsg := STRSUBSTNO(ERR_ModifyPFCFailed, _PFCNo);
PFCHeaderRec.MODIFY(FALSE);
COMMIT;
END ELSE BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
//ERROR(ErrorMsg);
END;
CLEAR(ErrorMsg);
// Execute Action
//
PFCEngine._SetVars(RunType::ExecuteAction, _PFCNo, _PFCLineNo, 0, '');
IF NOT PFCEngine.RUN THEN BEGIN
// Action codeunit reported back an error
// (or function Crash)
ErrorMsg := PFCEngine.GetError();
ResultPFCLine.ExecuteStatus := ResultPFCLine.ExecuteStatus::Error;
END ELSE BEGIN
// Line OK or Return value set.
// Query Line for current status
SELECTLATESTVERSION;
ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
IF NOT ResultPFCLine.GET(_PFCNo, _PFCLineNo) THEN
// ERROR(ErrorMsg);
// If line still Inprogress, we should check the return code parameters
IF ResultPFCLine.ExecuteStatus = ResultPFCLine.ExecuteStatus::Initiated THEN BEGIN
IF ParseReturnCode(ResultPFCLine) THEN
COMMIT;
// No status reported by action (manual or return values)
IF ResultPFCLine.ExecuteStatus = ResultPFCLine.ExecuteStatus::Initiated THEN
ResultPFCLine.ExecuteStatus := ResultPFCLine.ExecuteStatus::Waiting;
END;
END;
PFCEngine._SetVars(RunType::SetLineStatus, _PFCNo, _PFCLineNo, ResultPFCLine.ExecuteStatus, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
// ERROR(ErrorMsg);
END;
IF ResultPFCLine.ExecuteStatus IN [ResultPFCLine.ExecuteStatus::Error] THEN
;
// ERROR(ErrorMsg);
CLEAR(ErrorMsg);
ExecuteAction()
//
// Execute PFC line Action.
//
ErrorMsg := STRSUBSTNO(ERR_ExecutingLine, _PFCLineNo);
IF NOT PFCLineRec.GET(_PFCNo, _PFCLineNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
// ERROR(ErrorMsg);
END;
IF NOT PFCActionRec.GET(PFCLineRec."Action ID") THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_ActionNotFound, PFCLineRec."PFC Nr.");
// ERROR(ErrorMsg);
END;
CLEAR(ErrorMsg);
CASE PFCActionRec.Type OF
PFCActionRec.Type::"Function" : CODEUNIT.RUN(PFCActionRec."Object ID", PFCLineRec);
PFCActionRec.Type::Report : REPORT.RUN(PFCActionRec."Object ID", FALSE, FALSE, PFCLineRec);
PFCActionRec.Type::Dataport : IF NOT ISSERVICETIER THEN //TB-ALG TT35971
DATAPORT.RUN(PFCActionRec."Object ID", FALSE, PFCLineRec);
END;
SetStatus()
CLEAR(ErrorMsg);
SELECTLATESTVERSION;
IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
// ERROR(ErrorMsg);
END;
IF NOT PFCLineRec.GET(_PFCNo, _PFCLineNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
// ERROR(ErrorMsg);
END;
//
// Inserting a return code is only allowed when the PFC is in Status::Waiting
// OR
// If the pfc is locked by the current process and in
// Status::Executing (when called from action)
// Status::Error (general update of the PFC error description)
IF NOT ((PFCLineRec.ExecuteStatus IN [PFCLineRec.ExecuteStatus::Waiting,
PFCLineRec.ExecuteStatus::Error])
OR (PFCHeaderRec.ExecuteStatus = PFCHeaderRec.ExecuteStatus::Executing)) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_CantInsertRC, PFCLineRec.ExecuteStatus);
//ERROR(ErrorMsg);
END;
// IF PFC not waiting, current process must be the owner.
IF PFCHeaderRec.ExecuteStatus <> PFCHeaderRec.ExecuteStatus::Waiting THEN BEGIN
IF NOT GetMySession(SessionRec) THEN
;
// ERROR(ErrorMsg);
IF (PFCHeaderRec.LockUser = '')
OR (PFCHeaderRec.LockSession = 0) THEN BEGIN
ErrorMsg := ERR_NotLocked;
// ERROR(ErrorMsg);
END;
IF (PFCHeaderRec.LockUser <> UPPERCASE(USERID))
OR (PFCHeaderRec.LockSession <> SessionRec."Connection ID") THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_LockedBy, _PFCNo, PFCHeaderRec.LockUser, PFCHeaderRec.LockSession);
// ERROR(ErrorMsg);
END;
END ELSE BEGIN
// Reserve the PFC before we do any modifications.
IF NOT PFCEngine.ReservePFC_COMMIT(_PFCNo) THEN BEGIN
ErrorMsg := PFCEngine.GetError();
// ERROR(ErrorMsg);
END;
END;
// Insert the status code on the PFC line
PFCParameterRec."PFC Nr." := _PFCNo;
PFCParameterRec."PFC Line Nr." := _PFCLineNo;
PFCParameterRec."Entry Nr." := PFCParameterRec.GetNewEntryNr();
PFCParameterRec.Parameter := 'STATUSCODE';
PFCParameterRec.Value := DELSTR(_StatusValue, MAXSTRLEN(PFCParameterRec.Value)+1);
PFCParameterRec.Modified := TRUE;
PFCParameterRec.INSERT;
COMMIT;
// If PFC is currently executing,
// We don't need to act on the status code yet (This will be done by ExecutePFCLine())
IF PFCHeaderRec.ExecuteStatus = PFCHeaderRec.ExecuteStatus::Executing THEN
EXIT;
// Determine PFC line status.
IF ParseReturnCode(PFCLineRec) THEN
COMMIT;
// Update PFC line
PFCEngine._SetVars(RunType::SetLineStatus, _PFCNo, _PFCLineNo, PFCLineRec.ExecuteStatus, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
// ERROR(ErrorMsg);
END;
// Update PFC header
CASE PFCLineRec.ExecuteStatus OF
PFCLineRec.ExecuteStatus::Ok :
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;
PFCLineRec.ExecuteStatus::Waiting :
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Waiting;
PFCLineRec.ExecuteStatus::StopPFC :
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Done;
PFCLineRec.ExecuteStatus::Error :
BEGIN
PFCHeaderRec.VALIDATE(StatusCode, Setup.ErrorStatus);
PFCHeaderRec."Status Description" := DELSTR(ErrorMsg, MAXSTRLEN(PFCHeaderRec."Status Description")+1);
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
PFCHeaderRec.MODIFY();
COMMIT;
END;
END;
// Release the PFC
PFCEngine._SetVars(RunType::FinalisePFC, _PFCNo, _PFCLineNo, PFCHeaderRec.ExecuteStatus, '');
IF NOT PFCEngine.RUN THEN BEGIN
ErrorMsg := PFCEngine.GetError();
// ERROR(ErrorMsg);
END;
COMMIT;
SetLineStatus()
//
// Sets the Status option of the line
//
SELECTLATESTVERSION;
ErrorMsg := STRSUBSTNO(ERR_UnableToLockLine, _PFCLineNo);
PFCLineRec.LOCKTABLE;
IF NOT PFCLineRec.GET(_PFCNo, _PFCLineNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
// ERROR(ErrorMsg);
END;
ErrorMsg := STRSUBSTNO(ERR_LineStatusFailed, _PFCLineNo);
CLEAR(PFCLineRec.ExecuteError);
//PFCLineRec.ExecuteStatus := _StatusOption; //TB-ALG TT35971
PFCLineRec.ExecuteStatus := _Status;
PFCLineRec.MODIFY;
COMMIT;
CLEAR(ErrorMsg);
ParseReturnCode(VAR PFCLineRec : Record "PFC Line") DataModified : Boolean
//
// Parses Return code values on the PFC line.
//
// Return DataModified = true if any data was modified in the db
CLEAR(ErrorMsg);
SELECTLATESTVERSION;
PFCParameterRec.SETRANGE("PFC Nr.", PFCLineRec."PFC Nr.");
PFCParameterRec.SETRANGE("PFC Line Nr.", PFCLineRec."Line Nr.");
ReturnCodesRec.SETRANGE("PFC No.", PFCLineRec."PFC Nr.");
ReturnCodesRec.SETRANGE("PFC Line No.", PFCLineRec."Line Nr.");
IF ReturnCodesRec.ISEMPTY THEN BEGIN
// No return codes specified, check for an error StatusCode.
PFCParameterRec.SETRANGE(Parameter, 'STATUSCODE');
IF PFCParameterRec.FINDLAST THEN BEGIN
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
ErrorMsg := PFCParameterRec.Value;
END ELSE
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Waiting;
EXIT(DataModified);
END;
// 1. If a return code is mandatory, check if we have received one.
ReturnCodesRec.SETRANGE("Value Requirement", ReturnCodesRec."Value Requirement"::Mandatory);
//ReturnCodesRec.ASCENDING(TRUE);
IF NOT ReturnCodesRec.ISEMPTY THEN BEGIN
IF ReturnCodesRec.FINDSET(FALSE, FALSE) THEN REPEAT
IF ReturnCodesRec."Return Value" <> '' THEN
PFCParameterRec.SETRANGE(Value, ReturnCodesRec."Return Value");
IF PFCParameterRec.FINDLAST THEN
ReturnCodeFound := TRUE;
UNTIL (ReturnCodesRec.NEXT = 0) OR ReturnCodeFound;
END;
// 2. do a general return code check
IF NOT ReturnCodeFound THEN BEGIN
ReturnCodesRec.SETRANGE("Value Requirement");
PFCParameterRec.SETRANGE(Parameter); // ??
PFCParameterRec.SETRANGE(Value); // ??
// Find last inserted parameter.
IF PFCParameterRec.FIND('+') THEN REPEAT
// Check if parameter is a return code
ReturnCodesRec.SETRANGE("Return Value");
ReturnCodesRec.SETRANGE(Parameter, PFCParameterRec.Parameter);
IF ReturnCodesRec.FINDFIRST THEN BEGIN
// Return code match
ReturnCodesRec.SETRANGE("Return Value", DELSTR(PFCParameterRec.Value, MAXSTRLEN(ReturnCodesRec."Return Value")+1));
IF ReturnCodesRec.FINDFIRST THEN BEGIN
// Exact match
ReturnCodeFound := TRUE;
END ELSE BEGIN
// Generic match
ReturnCodesRec.SETFILTER("Return Value", '''''');
IF ReturnCodesRec.FINDFIRST THEN BEGIN
ReturnCodeFound := TRUE;
END ELSE BEGIN
// Unknown - unknown values should be treated as error.
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
ErrorMsg := PFCParameterRec.Value;
EXIT(DataModified);
END;
END;
END;
UNTIL ReturnCodeFound
OR (PFCParameterRec.NEXT(-1) = 0);
END;
IF NOT ReturnCodeFound THEN
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Waiting
ELSE BEGIN
CASE ReturnCodesRec.LineExecuteStatus OF
ReturnCodesRec.LineExecuteStatus::Ok :
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Ok;
ReturnCodesRec.LineExecuteStatus::Error :
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
ReturnCodesRec.LineExecuteStatus::Waiting :
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Waiting;
END;
// Only allow decisions when in OK state.
IF (ReturnCodesRec.LineExecuteStatus = ReturnCodesRec.LineExecuteStatus::Ok)
OR (ReturnCodesRec.Decision = ReturnCodesRec.Decision::"Create New PFC") THEN
CASE ReturnCodesRec.Decision OF
ReturnCodesRec.Decision::"Go to Step" :
BEGIN
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
IF (NOT EVALUATE(SkipValue, ReturnCodesRec."Decision Value"))
OR (SkipValue - 1 <= PFCLineRec."Line Nr.") THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_InvalidSkipValue, ReturnCodesRec."Decision Value");
EXIT(DataModified);
END;
IF NOT PFCLineRecLoop.GET(PFCLineRec."PFC Nr.", SkipValue) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_SkipFailed, SkipValue);
EXIT(DataModified);
END;
PFCLineRecLoop.SETRANGE("PFC Nr.", PFCLineRec."PFC Nr.");
PFCLineRecLoop.SETRANGE("Line Nr.", PFCLineRec."Line Nr." + 1, SkipValue - 1);
IF PFCLineRecLoop.FINDSET(TRUE, FALSE) THEN REPEAT
IF PFCLineRecSkip.GET(PFCLineRecLoop."PFC Nr.", PFCLineRecLoop."Line Nr.") THEN BEGIN
PFCLineRecSkip.ExecuteStatus := PFCLineRecSkip.ExecuteStatus::Skipped;
PFCLineRecSkip.MODIFY;
END;
UNTIL PFCLineRecLoop.NEXT = 0;
DataModified := TRUE;
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Ok;
END;
ReturnCodesRec.Decision::"Stop PFC" :
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::StopPFC;
// Create a new PFC, and set ready to execute.
ReturnCodesRec.Decision::"Stop PFC & Create New",
ReturnCodesRec.Decision::"Create New PFC" :
BEGIN
IF NOT PFCHeaderRec.GET(PFCLineRec."PFC Nr.") THEN
CLEAR(PFCHeaderRec);
IF NOT PFCFunctions.GetParameter(DATABASE::"Wholesale Partner", 10, WP, PFCLineRec."PFC Nr.", 0) THEN
CLEAR(WP);
NewPFCNo := PFCFunctions.CreatePFC_COMMIT(ReturnCodesRec."Decision Value", PFCHeaderRec."Customer No.",
PFCHeaderRec."Contract No.", DELSTR(WP, 21), FALSE);
IF NewPFCNo <> '' THEN
PFCEngine.ReleasePFC_COMMIT(NewPFCNo)
ELSE BEGIN
DataModified := TRUE;
ErrorMsg := PFCFunctions.GetError();
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
EXIT(DataModified);
END;
IF ReturnCodesRec.Decision = ReturnCodesRec.Decision::"Stop PFC & Create New" THEN
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::StopPFC
ELSE
PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Ok;
END;
END;
IF ReturnCodesRec."Change Header Status To" <> '' THEN
IF PFCHeaderRec.GET(PFCLineRec."PFC Nr.") THEN BEGIN
PFCHeaderRec.VALIDATE(StatusCode, ReturnCodesRec."Change Header Status To");
IF PFCLineRec.ExecuteStatus = PFCLineRec.ExecuteStatus::Error THEN BEGIN
IF ErrorMsg = '' THEN
ErrorMsg := PFCParameterRec.Value;
PFCHeaderRec."Status Description" := DELSTR(ErrorMsg, MAXSTRLEN(PFCHeaderRec."Status Description")+1);
END;
PFCHeaderRec.MODIFY(FALSE);
DataModified := TRUE;
END;
END;
EXIT(DataModified);
PostPFC() : Boolean
CLEAR(ErrorMsg);
CLEARLASTERROR;
SELECTLATESTVERSION;
IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
// ERROR(ErrorMsg);
END;
IF PFCHeaderRec.ExecuteStatus <> PFCHeaderRec.ExecuteStatus::Done THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCNotReadyToPost, _PFCNo);
// ERROR(ErrorMsg);
END;
IF TransmissionRec.HasOpenTransactions(_PFCNo) THEN BEGIN
ErrorMsg := STRSUBSTNO(ERR_PFCHasTransactions, _PFCNo);
//ERROR(ErrorMsg);
END;
CLEAR(PostedPFCRec);
PostedPFCRec.TRANSFERFIELDS(PFCHeaderRec);
IF PostedPFCRec."A-Number" = '' THEN
PostedPFCRec."A-Number" := PFCHeaderRec.ShowAnr();
PostedPFCRec.INSERT;
PFCLineRec.SETRANGE("PFC Nr.", _PFCNo);
PFCParameterRec.SETRANGE("PFC Nr.", _PFCNo);
PFCRVRec.SETRANGE("PFC No.", _PFCNo);
PFCFilterRec.SETRANGE("PFC Nr.", _PFCNo);
IF PFCHeaderRec."Delete Details" = FALSE THEN BEGIN
PFCLineRec.SETRANGE("Line Nr.", 0, 999999998);
IF PFCLineRec.FINDSET(FALSE, FALSE) THEN REPEAT
CLEAR(PostedLineRec);
PostedLineRec.TRANSFERFIELDS(PFCLineRec);
PostedLineRec.INSERT(FALSE);
UNTIL PFCLineRec.NEXT = 0;
PFCParameterRec.SETRANGE("PFC Line Nr.", 0, 999999998);
IF PFCParameterRec.FINDSET(FALSE, FALSE) THEN REPEAT
IF (PFCParameterRec.Value <> '') OR (PFCParameterRec.Modified) THEN BEGIN
CLEAR(PostedParameterRec);
PostedParameterRec.TRANSFERFIELDS(PFCParameterRec);
PostedParameterRec.INSERT(FALSE);
END;
UNTIL PFCParameterRec.NEXT = 0;
PFCLineRec.SETRANGE("Line Nr.");
PFCParameterRec.SETRANGE("PFC Line Nr.");
END;
SimCardPoolRec.CleanUpSimPoolStatus(PFCHeaderRec."PFC Nr.", PFCHeaderRec."Customer No.");
ANumberPoolRec.CleanUpANoPoolStatus(PFCHeaderRec."PFC Nr.", PFCHeaderRec."Customer No.");
PFCLineRec.DELETEALL;
PFCParameterRec.DELETEALL;
PFCRVRec.DELETEALL;
PFCFilterRec.DELETEALL;
PFCHeaderRec.DELETE;
COMMIT;
GetMySession(VAR SessionRec : Record Session) : Boolean
SessionRec.SETRANGE("My Session", TRUE);
IF NOT SessionRec.FINDFIRST THEN BEGIN
;
// ErrorMsg := ERR_SessionIDError;
//EXIT(FALSE);
END;
EXIT(TRUE);
CalculateMaxIdle(VAR PFCHeaderRec : Record "PFC Header")
CLEAR(PFCHeaderRec.IdleAt);
IF PFCHeaderRec."Max Idle Time" = 0 THEN
EXIT;
CASE PFCHeaderRec."Max Idle" OF
PFCHeaderRec."Max Idle"::Days : Interval := 86400000;
PFCHeaderRec."Max Idle"::Hours : Interval := 3600000;
ELSE
EXIT;
END;
Interval *= PFCHeaderRec."Max Idle Time";
PFCHeaderRec.IdleAt := Now() + Interval;
CheckLockTimeout()
//
// Check For PFCs in locked state for more than [Setup.LockTimeout] no. of minutes
// And set them to Error state if lock retained too long.
//
IF Setup.LockTimeout = 0 THEN
EXIT;
PFCHeaderRec.SETCURRENTKEY(ExecuteStatus, LockTime);
PFCHeaderRec.SETFILTER(ExecuteStatus, '<>%1', PFCHeaderRec.ExecuteStatus::Error);
PFCHeaderRec.SETFILTER(LockTime, '>%1&<%2',
CREATEDATETIME(0D, 0T),
(CURRENTDATETIME - (60000 * Setup.LockTimeout)));
IF PFCHeaderRec.FINDFIRST() THEN REPEAT
IF PFCHeaderRec.GET(PFCHeaderRec."PFC Nr.") THEN BEGIN
PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
PFCHeaderRec.VALIDATE(StatusCode, Setup.LockTimeoutStatus);
// Preserve old status description.
IF STRPOS(PFCHeaderRec."Status Description", ERR_LockTimeout) = 0 THEN // did we do this already?
PFCHeaderRec."Status Description" := DELSTR(ERR_LockTimeout + ': ' + PFCHeaderRec."Status Description",
MAXSTRLEN(PFCHeaderRec."Status Description")+1);
PFCHeaderRec.MODIFY(FALSE);
END;
UNTIL PFCHeaderRec.NEXT = 0;
CheckMaxIdle()
//
// Check For PFCs with IdlesAt time exceeded
// And mark them as MaxIdle.
//
IF Setup.MaxIdleStatus = '' THEN
EXIT;
PFCHeaderRec.SETCURRENTKEY(IdleAt);
PFCHeaderRec.SETFILTER(ExecuteStatus, '<>%1', PFCHeaderRec.ExecuteStatus::Error);
PFCHeaderRec.SETFILTER(StatusCode, '<>%1', Setup.MaxIdleStatus);
PFCHeaderRec.SETFILTER(IdleAt, '>%1&<=%2',
CREATEDATETIME(0D, 0T),
Now());
IF PFCHeaderRec.FINDSET(FALSE, FALSE) THEN REPEAT
PFCHeaderTmp."PFC Nr." := PFCHeaderRec."PFC Nr.";
PFCHeaderTmp.INSERT;
UNTIL PFCHeaderRec.NEXT = 0;
IF PFCHeaderTmp.FIND('-') THEN REPEAT
IF PFCEngine.ReservePFC_COMMIT(PFCHeaderTmp."PFC Nr.") THEN BEGIN
IF PFCHeaderRec.GET(PFCHeaderTmp."PFC Nr.") THEN BEGIN
PFCHeaderRec.VALIDATE(StatusCode, Setup.MaxIdleStatus);
PFCHeaderRec.MODIFY(FALSE);
END;
PFCEngine.ReleasePFC_COMMIT(PFCHeaderTmp."PFC Nr.");
END;
UNTIL PFCHeaderTmp.NEXT = 0;
Now() : DateTime
EXIT(CREATEDATETIME(WORKDATE, TIME));
_SetVars(NewRunType : Option;PFCNo : Code[20];LineNo : Integer;StatusOption : Option;Value : Text[250])
RunType := NewRunType;
_PFCNo := PFCNo;
_PFCLineNo := LineNo;
_StatusOption := StatusOption;
_StatusValue := Value;
_Status := StatusOption; //TB-ALG TT35971
_GetLastExecuteStatus(VAR ExecuteStatus : Option)
//
// Return execute status from last PFC execution
//
ExecuteStatus := _ExecuteStatus;
EXIT;
http://ssdynamics.co.in