Eddie Shipman
asked on
Old code, using labels/goto. Need to remove them.
Got this structure inside one of my procedures:
label 1;
procedure HandleErrorA(sMsg: string);
begin
LogSendOrderError(nStoreKe y, _ApplicationError, 'MDOtherMcLaneOrder', sMsg);
end;
procedure HandleError(sMsg: string);
begin
bFileError := TRUE;
HandleErrorA(sMsg);
LogInfo(sMsg);
end;
procedure WaitConnect;
var
dt: TDateTime;
begin
dt := Now;
while not (bConnectDone or bConnectFailed) do begin
Sleep(_SleepLength);
Application.ProcessMessage s;
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec tTimeout);
Break;
end;
end;
end;
procedure WaitTransmit;
var
dt: TDateTime;
begin
dt := Now;
while not bTransmitDone do begin
Sleep(_SleepLength);
Application.ProcessMessage s;
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDITransm itTimeout) ;
Break;
end;
end;
end;
procedure WaitConnectCancel;
var
dt: TDateTime;
begin
dt := Now;
while not bConnectCancelled do begin
Sleep(_SleepLength);
Application.ProcessMessage s;
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec tCancelTim eout);
bConnectCancelFailed := TRUE;
Break;
end;
end;
end;
procedure SendFile(sFileName: string);
begin
Protocol.FileMask := sFileName;
nErrorCode := 0;
bTransmitDone := FALSE;
Protocol.StartTransmit;
WaitTransmit;
end;
Then later in the program, I have this:
{Connect}
if bEstablishConnection then
begin
bConnectDone := FALSE;
bConnectFailed := FALSE;
TapiDevice.SelectedDevice := sDevice;
TapiDevice.Dial(sPhoneNum) ;
WaitConnect(nStoreKey);
if bFileError then goto 1;
if (not bConnectFailed) and bConnectDone then
begin
LogInfo('Connection established with ' + sVendorName + '.');
if ComPort.WaitForString('C', _WaitForStringTimeout, FALSE, TRUE) then
begin
LogInfo('C received after establishing connection.');
{Transmit sign-on file}
SendFile(nStoreKey, sTempDir + _SignOnFile);
if bFileError then
begin
HandleError(nStoreKey, _msg_EDISignOnError);
goto 1;
end;
Now, what exactly is "RUN" when the goto is performed? I need
to know because I'm restructuring the program and want to get rid
of the gotos. What would I normally do here? I have never used gotos
and labels in a Delph program before.
label 1;
procedure HandleErrorA(sMsg: string);
begin
LogSendOrderError(nStoreKe
end;
procedure HandleError(sMsg: string);
begin
bFileError := TRUE;
HandleErrorA(sMsg);
LogInfo(sMsg);
end;
procedure WaitConnect;
var
dt: TDateTime;
begin
dt := Now;
while not (bConnectDone or bConnectFailed) do begin
Sleep(_SleepLength);
Application.ProcessMessage
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec
Break;
end;
end;
end;
procedure WaitTransmit;
var
dt: TDateTime;
begin
dt := Now;
while not bTransmitDone do begin
Sleep(_SleepLength);
Application.ProcessMessage
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDITransm
Break;
end;
end;
end;
procedure WaitConnectCancel;
var
dt: TDateTime;
begin
dt := Now;
while not bConnectCancelled do begin
Sleep(_SleepLength);
Application.ProcessMessage
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec
bConnectCancelFailed := TRUE;
Break;
end;
end;
end;
procedure SendFile(sFileName: string);
begin
Protocol.FileMask := sFileName;
nErrorCode := 0;
bTransmitDone := FALSE;
Protocol.StartTransmit;
WaitTransmit;
end;
Then later in the program, I have this:
{Connect}
if bEstablishConnection then
begin
bConnectDone := FALSE;
bConnectFailed := FALSE;
TapiDevice.SelectedDevice := sDevice;
TapiDevice.Dial(sPhoneNum)
WaitConnect(nStoreKey);
if bFileError then goto 1;
if (not bConnectFailed) and bConnectDone then
begin
LogInfo('Connection established with ' + sVendorName + '.');
if ComPort.WaitForString('C',
begin
LogInfo('C received after establishing connection.');
{Transmit sign-on file}
SendFile(nStoreKey, sTempDir + _SignOnFile);
if bFileError then
begin
HandleError(nStoreKey, _msg_EDISignOnError);
goto 1;
end;
Now, what exactly is "RUN" when the goto is performed? I need
to know because I'm restructuring the program and want to get rid
of the gotos. What would I normally do here? I have never used gotos
and labels in a Delph program before.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I'm not really sure what the developer wanted to accomplish here. All the instances where the goto is being used is after calls the the procedures that occur after the label in the code.
it goes kind of like this for, say, the SendFile routine:
SendFile(nStoreKey, sTempDir + _SignOnFile);
if bFileError then
begin
HandleError(Self, nStoreKey, _msg_EDISignOnError);
goto 1;
end;
In HandleError, you can see that bFileError is being set to True so it will always go to the label.
I'm kind of wondering how I can better handle this.
it goes kind of like this for, say, the SendFile routine:
SendFile(nStoreKey, sTempDir + _SignOnFile);
if bFileError then
begin
HandleError(Self, nStoreKey, _msg_EDISignOnError);
goto 1;
end;
In HandleError, you can see that bFileError is being set to True so it will always go to the label.
I'm kind of wondering how I can better handle this.
I beg to differ. You showed this:
label 1;
Which is the declaration of the label (like declararing a function). I have double checked your code and I don't see a
1:
Which is the ACTUAL label jump point anywhere in your code.
label 1;
Which is the declaration of the label (like declararing a function). I have double checked your code and I don't see a
1:
Which is the ACTUAL label jump point anywhere in your code.
ASKER
the code beween
label 1;
and
procedure SendFile(sFileName: string);
begin
Protocol.FileMask := sFileName;
nErrorCode := 0;
bTransmitDone := FALSE;
Protocol.StartTransmit;
WaitTransmit;
end;
is all there is, there is nothing else. The label doen'st actually take you anywhere.
Here is the ENTIRE procedure:
procedure TMcLaneSendOrder.SendOrder (OrderKeys : TStringList; bShowProgress: Boolean;
OrderDestination: TOrderDestination);
const
_SleepLength = 500;
_WaitForStringTimeout = 1092;
_SignOnFile = 'McLaneSignOn.tmp';
_ProtocolLogFile = 'McLaneProtocol.log';
var
i: integer;
qryOrder: TQuery;
genqry: TQuery;
sDestDir: string;
sTempDir: string;
sTempFile: string;
strlFileList: TStringList;
strlSend: TswStringList;
strlSentOrders: TStringList;
strlFile: TStringList;
strlVendorError: TStringList;
strlStoreError: TStringList;
sLine: string;
nTotalDetailLines: integer;
fTotalOrderQty: extended;
fOrderQty: integer;
bEDISetupError: boolean;
sFileName: string;
sStoreID: string;
sStoreKey: string;
sVendorKey: string;
sDevice: string;
sPhoneNum: string;
sCustomerID: string;
sOrderID: string;
sPassword: string;
sVendorName: string;
sOrderNum: string;
sOrderKey: string;
nStoreKey: integer;
sCurrVendorKey: string;
bFileError: boolean;
bEstablishConnection: boolean;
label 1;
procedure HandleErrorA(sMsg: string);
begin
LogSendOrderError(nStoreKe y, _ApplicationError, 'MDOtherMcLaneOrder', sMsg);
end;
procedure HandleError(sMsg: string);
begin
bFileError := TRUE;
HandleErrorA(sMsg);
LogInfo(sMsg);
end;
procedure WaitConnect;
var
dt: TDateTime;
begin
dt := Now;
while not (bConnectDone or bConnectFailed) do begin
Sleep(_SleepLength);
Application.ProcessMessage s;
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec tTimeout);
Break;
end;
end;
end;
procedure WaitTransmit;
var
dt: TDateTime;
begin
dt := Now;
while not bTransmitDone do begin
Sleep(_SleepLength);
Application.ProcessMessage s;
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDITransm itTimeout) ;
Break;
end;
end;
end;
procedure WaitConnectCancel;
var
dt: TDateTime;
begin
dt := Now;
while not bConnectCancelled do begin
Sleep(_SleepLength);
Application.ProcessMessage s;
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec tCancelTim eout);
bConnectCancelFailed := TRUE;
Break;
end;
end;
end;
procedure SendFile(sFileName: string);
begin
Protocol.FileMask := sFileName;
nErrorCode := 0;
bTransmitDone := FALSE;
Protocol.StartTransmit;
WaitTransmit;
end;
begin
strlFileList := TStringList.Create;
strlSend := TswStringList.Create;
strlSentOrders := TStringList.Create;
strlFile := TStringList.Create;
strlVendorError := TStringList.Create;
strlStoreError := TStringList.Create;
qryOrder := TQuery.Create(nil);
genqry := TQuery.Create(nil);
try
{connection}
qryOrder.DatabaseName := _SWDatabaseName;
genqry.DatabaseName := _SWDatabaseName;
{initialization}
bConnectCancelled := FALSE;
bConnectCancelFailed := FALSE;
bConnectDone := FALSE;
bConnectFailed := FALSE;
bTransmitDone := FALSE;
nErrorCode := 0;
TimeoutLength := StrToDateTime('01/01/00 00:02:00') -
Trunc(StrToDateTime('01/01 /00 00:02:00'));
IsCancelled := FALSE;
Progress := 0;
ProgressIncrement := 0;
if bShowProgress then
begin
CreateProgressDlg('Creatin g McLane Electronic Order(s)');
ProgressIncrement := (1 / OrderKeys.Count) * 100;
Application.ProcessMessage s;
end;
sTempDir := sysTempPath;
sLogDir := ExtractFilePath(ParamStr(0 ));
sLogDir := ExtractFilePath(Copy(sLogD ir, 1, Length(sLogDir) - 1)) + 'Log\';
ForceDirectories(sLogDir);
DeleteFile(sLogDir + _ProtocolLogFile);
DeleteFile(sLogDir + _CustomLog);
for i := 0 to OrderKeys.Count - 1 do
begin
bEDISetupError := FALSE;
nTotalDetailLines := 0;
fTotalOrderQty := 0;
if bShowProgress then
begin
Application.ProcessMessage s;
CheckProgress;
if IsCancelled then Break;
end;
{main}
with qryOrder do
begin
Close;
SQL.Clear;
SQL.Add( 'SELECT S.STORE_ID,'
+ _crlf + ' O.STORE_KEY,'
+ _crlf + ' O.ORDER_KEY,'
+ _crlf + ' O.ORDER_NUM,'
+ _crlf + ' V.VENDOR_KEY,'
+ _crlf + ' V.VENDOR_NAME,'
+ _crlf + ' V.ORDER_ID,'
+ _crlf + ' V.CUSTOMER_ID,'
+ _crlf + ' V.ORDER_PASSWORD,'
+ _crlf + ' V.ORDER_PHONE,'
+ _crlf + ' E.MODEM_TYPE'
+ _crlf + 'FROM MDTRORDER_HDR O'
+ _crlf + ' INNER JOIN SYCFVENDOR V'
+ _crlf + ' ON V.VENDOR_KEY = O.VENDOR_KEY'
+ _crlf + ' INNER JOIN DICFEDI E'
+ _crlf + ' ON E.STORE_KEY = O.STORE_KEY'
+ _crlf + ' INNER JOIN SYCFSTORE S'
+ _crlf + ' ON S.STORE_KEY = O.STORE_KEY'
+ _crlf + 'WHERE O.ORDER_KEY = ' + OrderKeys[i] );
Open;
sStoreID := FieldByName('STORE_ID').As String;
sStoreKey := FieldByName('STORE_KEY').A sString;
sVendorKey := FieldByName('VENDOR_KEY'). AsString;
sDevice := FieldByName('MODEM_TYPE'). AsString;
sPhoneNum := FieldByName('ORDER_PHONE') .AsString;
sCustomerID := Trim(FieldByName('CUSTOMER _ID').AsSt ring);
sOrderID := Trim(FieldByName('ORDER_ID ').AsStrin g);
sPassword := FieldByName('ORDER_PASSWOR D').AsStri ng;
sVendorName := FieldByName('VENDOR_NAME') .AsString;
sOrderNum := FieldByName('ORDER_NUM').A sString;
sOrderKey := FieldByName('ORDER_KEY').A sString;
nStoreKey := FieldByName('STORE_KEY').A sInteger;
if InList(sVendorKey, strlVendorError) or InList(sStoreKey, strlStoreError ) then
bEDISetupError := TRUE
else
begin
if (sOrderID = '') or (sCustomerID = '') or (sPassword = '') or
(sPhoneNum = '') then
begin
bEDISetupError := TRUE;
if not InList(sVendorKey, strlVendorError) then
strlVendorError.Add(sVendo rKey);
end;
if FieldByName('MODEM_TYPE'). AsString = '' then
begin
bEDISetupError := TRUE;
if not InList(sStoreKey, strlStoreError) then
strlStoreError.Add(sStoreK ey);
end;
end;
if bEDISetupError then
begin
HandleErrorA(_msg_NoEDIInf oSetup + ' Order Num: ' + sOrderNum + ' Vendor: ' +
sVendorName );
Close;
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
Continue;
end;
Close;
end;//with qryOrder
with qryOrder do
begin
Close;
SQL.Clear;
SQL.Add(
'SELECT O.BUSINESS_DAY,'
+ _crlf + ' L.ORDER_QUANTITY,'
+ _crlf + ' P.PRODUCT_ID'
+ _crlf + 'FROM MDTRORDER_HDR O'
+ _crlf + ' INNER JOIN MDTRORDER_LINE L'
+ _crlf + ' ON L.ORDER_KEY = O.ORDER_KEY'
+ _crlf + ' INNER JOIN SYCFVENDOR V'
+ _crlf + ' ON V.VENDOR_KEY = O.VENDOR_KEY'
+ _crlf + ' INNER JOIN MDCFPROD_VEND_MULT P'
+ _crlf + ' ON P.VENDOR_KEY = O.VENDOR_KEY'
+ _crlf + ' AND P.PRODUCT_KEY = L.PRODUCT_KEY'
+ _crlf + ' AND P.MULTIPLIER = L.MULTIPLIER'
+ _crlf + 'WHERE O.ORDER_KEY = ' + OrderKeys[i]
);
Open;
{Create temp file}
sTempFile := fileTemp('.tmp');
{Clear the file stringlist}
strlFile.Clear;
{Transmission Header}
sLine := '$$ADD ID='
+ strPadR(sOrderID, 2)
+ strPadR(sCustomerID, 6)
+ ' BATCHID=''EOE ORDER''';
strlFile.Add(sLine);
{Header 2}
sLine := '1'
+ FormatDateTime('yyyymmdd', FieldByName('BUSINESS_DAY' ).AsDateTi me)
+ strPadR(sOrderID, 2)
+ strPadR(sCustomerID, 6)
+ strPadR(sOrderNum, 10)
+ strSpace(47);
strlFile.Add(sLine);
{Detail Lines}
while not eof do
begin
fOrderQty := Trunc(FieldByName('ORDER_Q UANTITY'). AsFloat + 0.5); {round up}
sLine := '2'
+ strPadZeroL(FieldByName('P RODUCT_ID' ).AsString , 6)
+ strPadZeroL(IntToStr(fOrde rQty), 5)
+ strSpace(11);
strlFile.Add(sLine);
{Totals for Summary Record}
Inc(nTotalDetailLines);
fTotalOrderQty := fTotalOrderQty + fOrderQty;
Next;
end;
{Summary Record}
sLine := '3'
+ strPadZeroL(IntToStr(nTota lDetailLin es), 6)
+ strPadZeroL(IntToStr(Trunc (fTotalOrd erQty)), 9);
strlFile.Add(sLine);
Close;
end;//with qryOrder
strlFile.SaveToFile(sTempF ile);
strlFileList.Add(sTempFile
+ _Tab + sStoreKey
+ _Tab + sVendorKey
+ _Tab + sDevice
+ _Tab + sPhoneNum
+ _Tab + sCustomerID
+ _Tab + sOrderID
+ _Tab + sPassword
+ _Tab + sVendorName
+ _Tab + sOrderNum
+ _Tab + sOrderKey
+ _Tab + sStoreID
);
{mainend}
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
end; {for}
if bShowProgress then
begin
Sleep(1000);
TerminateProgress;
end;
{------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------}
if IsCancelled or (strlFileList.Count = 0) then Exit;
Progress := 0;
ProgressIncrement := 0;
if OrderDestination = odModem then
begin
if bShowProgress then
begin
CreateProgressDlg('Sending McLane Electronic Order(s)');
ProgressIncrement := (1 / strlFileList.Count) * 100;
Application.ProcessMessage s;
end;
ComPort := TApdComPort.Create(nil);
ComPort.AutoOpen := FALSE;
ComPort.TapiMode := tmOn;
ComPort.Baud := 9600;
ComPort.DataBits := 8;
ComPort.Parity := pNone;
ComPort.StopBits := 1;
TapiDevice := TApdTapiDevice.Create(nil) ;
TapiDevice.ComPort := ComPort;
TapiDevice.OnTapiConnect := OnConnect;
TapiDevice.OnTapiFail := OnConnectFail;
TapiDevice.OnTapiPortClose := OnClosePort;
Protocol := TApdProtocol.Create(nil);
Protocol.ComPort := ComPort;
Protocol.ProtocolType := ptXModem;
Protocol.OnProtocolFinish := OnTransmitFinish;
Protocol_Log := TApdProtocolLog.Create(nil );
Protocol_Log.Protocol := Protocol;
Protocol_Log.HistoryName := sLogDir + _ProtocolLogFile;
Protocol.ProtocolLog := Protocol_Log;
sCurrVendorKey := ''; {Track current vendor being processed}
strlVendorError.Clear; {Track vendors that errored out}
for i := 0 to strlFileList.Count - 1 do
begin
bFileError := FALSE;
strlSend.TabText := strlFileList[i];
sFileName := strlSend[0];
sStoreKey := strlSend[1];
sVendorKey := strlSend[2];
sDevice := strlSend[3];
sPhoneNum := strlSend[4];
sCustomerID := strlSend[5];
sOrderID := strlSend[6];
sPassword := strlSend[7];
sVendorName := strlSend[8];
sOrderNum := strlSend[9];
sOrderKey := strlSend[10];
nStoreKey := StrToInt(sStoreKey);
{If a previous attempt to send to this vendor failed, do not send the rest of the orders for this vendor}
if strlVendorError.IndexOf(sV endorKey) <> -1 then
HandleError(Format(_msg_ED ICannotSen dToVendor, [sVendorName]));
if bFileError then goto 1;
if bShowProgress then
begin
Application.ProcessMessage s;
CheckProgress;
if IsCancelled then Break;
end;
{***** main *****}
if sVendorKey <> sCurrVendorKey then {If another vendor, establish new connection}
begin
bEstablishConnection := TRUE;
sCurrVendorKey := sVendorKey; {make this the "current vendor"}
{Cancel current call first}
if i <> 0 then
begin
if TapiDevice.TapiState = tsConnected then
begin
bConnectCancelled := FALSE;
bConnectCancelFailed := FALSE;
if not TapiDevice.CancelCall then
begin
WaitConnectCancel;
if bFileError then goto 1;
end;
end;
end;
{Prepare sign-on file first}
strlFile.Clear;
strlFile.Add('/*SIGNON RMT=' + sOrderID + sCustomerID + ' PASSWORD=' + sPassword);
strlFile.SaveToFile(sTempD ir + _SignOnFile);
end
else {Connect only if disconnected}
bEstablishConnection := (TapiDevice.TapiState <> tsConnected);
{Connect}
if bEstablishConnection then
begin
bConnectDone := FALSE;
bConnectFailed := FALSE;
TapiDevice.SelectedDevice := sDevice;
TapiDevice.Dial(sPhoneNum) ;
WaitConnect;
if bFileError then goto 1;
if (not bConnectFailed) and bConnectDone then
begin
LogInfo('Connection established with ' + sVendorName + '.');
if ComPort.WaitForString('C', _WaitForStringTimeout, FALSE, TRUE) then
begin
LogInfo('C received after establishing connection.');
{Transmit sign-on file}
SendFile(sTempDir + _SignOnFile);
if bFileError then
begin
HandleError(_msg_EDISignOn Error);
goto 1;
end;
if nErrorCode <> 0 then
HandleError(_msg_EDISignOn Error + ' ' + ErrorMsg(nErrorCode));
end
else
HandleError(_msg_EDIDidNot ReceiveC + ' After connecting.');
end
else
HandleError(_msg_EDIConnec tionError) ;
end;
if bFileError then goto 1;
if ComPort.WaitForString('C', _WaitForStringTimeout, FALSE, TRUE) then
begin
LogInfo('C received after sending sign-on file or before sending the next order file.');
{Transmit order file}
SendFile(sFileName);
if bFileError then goto 1;
if nErrorCode <> 0 then HandleError(ErrorMsg(nErro rCode));
end
else
HandleError(_msg_EDIDidNot ReceiveC + ' After sending sign-on file or before sending the next order file.');
if bFileError then goto 1;
if not ComPort.WaitForString('C', _WaitForStringTimeout, FALSE, TRUE) then
HandleError(_msg_EDIDidNot ReceiveC + ' After sending an order file.')
else
LogInfo('C received after sending an order file (' + sFileName + ').');
if bFileError then goto 1;
1:
if bFileError then
begin
if strlVendorError.IndexOf(sV endorKey) = -1 then
strlVendorError.Add(sVendo rKey);
HandleError(Format(_msg_Or derNotSent , [sVendorName, sOrderNum]));
end
else
strlSentOrders.Add(sOrderK ey); {Remember successfully sent orders}
{***** mainend *****}
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
end; {for}
{Disconnect }
if TapiDevice.TapiState = tsConnected then
begin
bConnectCancelled := FALSE;
bConnectCancelFailed := FALSE;
if not TapiDevice.CancelCall then WaitConnectCancel;
if not bConnectCancelFailed then LogInfo('Connection cancelled.');
end;
end//if OrderDestination = odModem
else
begin
if bShowProgress then
begin
CreateProgressDlg('Copying files.');
ProgressIncrement := (1 / strlFileList.Count) * 100;
Application.ProcessMessage s;
end;
sDestDir := GetAppDirectory(AdTransfer ) + 'EDI\Outgoing';
ForceDirectories(sDestDir) ;
for i := 0 to strlFileList.Count - 1 do
begin
bFileError := FALSE;
strlSend.TabText := strlFileList[i];
sFileName := strlSend[0];
sVendorName := strlSend[8];
sOrderNum := strlSend[9];
sStoreID := strlSend[11];
if bShowProgress then
begin
Application.ProcessMessage s;
CheckProgress;
if IsCancelled then Break;
end;
sTempFile := sDestDir + '\ORDER' + StringOfChar('0', 8 - Length(sOrderNum)) +
sOrderNum + '_' + sStoreID + '.txt';
if FileExists(sTempFile) and (not DeleteFile(sTempFile)) then
HandleError(Format(_msg_Or derNotSent , [sVendorName, sOrderNum]) +
' ''' + SysErrorMessage(GetLastErr or) + '''')
else if not RenameFile(sFileName, sTempFile) then
HandleError(Format(_msg_Or derNotSent , [sVendorName, sOrderNum]) +
' ''' + SysErrorMessage(GetLastErr or) + '''')
else
strlSentOrders.Add(sOrderK ey); {Remember successfully sent orders}
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
end;//for i := 0 to strlFileList.Count - 1
end;
{Update Status}
with genqry do
begin
Close;
SQL.Clear;
SQL.Add( 'UPDATE MDTRORDER_HDR'
+ _crlf + 'SET STATUS = ''' + _Sent + ''','
+ _crlf + ' SENT_DATE = GETDATE()'
+ _crlf + 'WHERE ORDER_KEY IN (' + strlSentOrders.CommaText + ')'
);
if strlSentOrders.CommaText <> '' then ExecSQL;
end;
if bShowProgress then
begin
Sleep(1000);
TerminateProgress;
end;
finally
qryOrder.Close;
qryOrder.Free;
genqry.Close;
genqry.Free;
strlFile.Free;
strlVendorError.Free;
strlStoreError.Free;
if Assigned(ComPort) then begin
ComPort.Free;
end;
if Assigned(TapiDevice) then begin
TapiDevice.Free;
end;
if Assigned(Protocol) then begin
Protocol.Free;
end;
if Assigned(Protocol_Log) then begin
Protocol_Log.Free;
end;
if bShowProgress then begin
TerminateProgress;
end;
for i := 0 to strlFileList.Count - 1 do begin
strlSend.TabText := strlFileList[i];
DeleteFile(strlSend[0]);
end;
strlSend.Free;
strlFileList.Free;
DeleteFile(sTempDir + _SignOnFile);
if bShowProgress then begin
if strlSentOrders.Count <> OrderKeys.Count then begin
MessageDlg(Format(_msg_EDI SendIncomp lete, [IntToStr(strlSentOrders.C ount), IntToStr(OrderKeys.Count)] ), mtInformation, [mbOk], 0);
end else begin
MessageDlg(_msg_EDISendCom plete, mtInformation, [mbOk], 0);
end;
end;
strlSentOrders.Free;
end;
end;
This is some very old, maybe 7-8 yrs, code and very convoluted. I'd like to be able to rewrite this to
better handle the error conditions outlined in the code. I am also going to write another procedure
called SendOrderFTP where I can use FTP to send the order .vs sending via TapiDevice and need
the HandleErrorA, HandleError, WaitConnect, WaitTransmit, WaitConnectCancel, and SendFile
public so it can be called from both of them.
label 1;
and
procedure SendFile(sFileName: string);
begin
Protocol.FileMask := sFileName;
nErrorCode := 0;
bTransmitDone := FALSE;
Protocol.StartTransmit;
WaitTransmit;
end;
is all there is, there is nothing else. The label doen'st actually take you anywhere.
Here is the ENTIRE procedure:
procedure TMcLaneSendOrder.SendOrder
OrderDestination: TOrderDestination);
const
_SleepLength = 500;
_WaitForStringTimeout = 1092;
_SignOnFile = 'McLaneSignOn.tmp';
_ProtocolLogFile = 'McLaneProtocol.log';
var
i: integer;
qryOrder: TQuery;
genqry: TQuery;
sDestDir: string;
sTempDir: string;
sTempFile: string;
strlFileList: TStringList;
strlSend: TswStringList;
strlSentOrders: TStringList;
strlFile: TStringList;
strlVendorError: TStringList;
strlStoreError: TStringList;
sLine: string;
nTotalDetailLines: integer;
fTotalOrderQty: extended;
fOrderQty: integer;
bEDISetupError: boolean;
sFileName: string;
sStoreID: string;
sStoreKey: string;
sVendorKey: string;
sDevice: string;
sPhoneNum: string;
sCustomerID: string;
sOrderID: string;
sPassword: string;
sVendorName: string;
sOrderNum: string;
sOrderKey: string;
nStoreKey: integer;
sCurrVendorKey: string;
bFileError: boolean;
bEstablishConnection: boolean;
label 1;
procedure HandleErrorA(sMsg: string);
begin
LogSendOrderError(nStoreKe
end;
procedure HandleError(sMsg: string);
begin
bFileError := TRUE;
HandleErrorA(sMsg);
LogInfo(sMsg);
end;
procedure WaitConnect;
var
dt: TDateTime;
begin
dt := Now;
while not (bConnectDone or bConnectFailed) do begin
Sleep(_SleepLength);
Application.ProcessMessage
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec
Break;
end;
end;
end;
procedure WaitTransmit;
var
dt: TDateTime;
begin
dt := Now;
while not bTransmitDone do begin
Sleep(_SleepLength);
Application.ProcessMessage
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDITransm
Break;
end;
end;
end;
procedure WaitConnectCancel;
var
dt: TDateTime;
begin
dt := Now;
while not bConnectCancelled do begin
Sleep(_SleepLength);
Application.ProcessMessage
if (Now - dt) > TimeoutLength then begin
HandleError(_msg_EDIConnec
bConnectCancelFailed := TRUE;
Break;
end;
end;
end;
procedure SendFile(sFileName: string);
begin
Protocol.FileMask := sFileName;
nErrorCode := 0;
bTransmitDone := FALSE;
Protocol.StartTransmit;
WaitTransmit;
end;
begin
strlFileList := TStringList.Create;
strlSend := TswStringList.Create;
strlSentOrders := TStringList.Create;
strlFile := TStringList.Create;
strlVendorError := TStringList.Create;
strlStoreError := TStringList.Create;
qryOrder := TQuery.Create(nil);
genqry := TQuery.Create(nil);
try
{connection}
qryOrder.DatabaseName := _SWDatabaseName;
genqry.DatabaseName := _SWDatabaseName;
{initialization}
bConnectCancelled := FALSE;
bConnectCancelFailed := FALSE;
bConnectDone := FALSE;
bConnectFailed := FALSE;
bTransmitDone := FALSE;
nErrorCode := 0;
TimeoutLength := StrToDateTime('01/01/00 00:02:00') -
Trunc(StrToDateTime('01/01
IsCancelled := FALSE;
Progress := 0;
ProgressIncrement := 0;
if bShowProgress then
begin
CreateProgressDlg('Creatin
ProgressIncrement := (1 / OrderKeys.Count) * 100;
Application.ProcessMessage
end;
sTempDir := sysTempPath;
sLogDir := ExtractFilePath(ParamStr(0
sLogDir := ExtractFilePath(Copy(sLogD
ForceDirectories(sLogDir);
DeleteFile(sLogDir + _ProtocolLogFile);
DeleteFile(sLogDir + _CustomLog);
for i := 0 to OrderKeys.Count - 1 do
begin
bEDISetupError := FALSE;
nTotalDetailLines := 0;
fTotalOrderQty := 0;
if bShowProgress then
begin
Application.ProcessMessage
CheckProgress;
if IsCancelled then Break;
end;
{main}
with qryOrder do
begin
Close;
SQL.Clear;
SQL.Add( 'SELECT S.STORE_ID,'
+ _crlf + ' O.STORE_KEY,'
+ _crlf + ' O.ORDER_KEY,'
+ _crlf + ' O.ORDER_NUM,'
+ _crlf + ' V.VENDOR_KEY,'
+ _crlf + ' V.VENDOR_NAME,'
+ _crlf + ' V.ORDER_ID,'
+ _crlf + ' V.CUSTOMER_ID,'
+ _crlf + ' V.ORDER_PASSWORD,'
+ _crlf + ' V.ORDER_PHONE,'
+ _crlf + ' E.MODEM_TYPE'
+ _crlf + 'FROM MDTRORDER_HDR O'
+ _crlf + ' INNER JOIN SYCFVENDOR V'
+ _crlf + ' ON V.VENDOR_KEY = O.VENDOR_KEY'
+ _crlf + ' INNER JOIN DICFEDI E'
+ _crlf + ' ON E.STORE_KEY = O.STORE_KEY'
+ _crlf + ' INNER JOIN SYCFSTORE S'
+ _crlf + ' ON S.STORE_KEY = O.STORE_KEY'
+ _crlf + 'WHERE O.ORDER_KEY = ' + OrderKeys[i] );
Open;
sStoreID := FieldByName('STORE_ID').As
sStoreKey := FieldByName('STORE_KEY').A
sVendorKey := FieldByName('VENDOR_KEY').
sDevice := FieldByName('MODEM_TYPE').
sPhoneNum := FieldByName('ORDER_PHONE')
sCustomerID := Trim(FieldByName('CUSTOMER
sOrderID := Trim(FieldByName('ORDER_ID
sPassword := FieldByName('ORDER_PASSWOR
sVendorName := FieldByName('VENDOR_NAME')
sOrderNum := FieldByName('ORDER_NUM').A
sOrderKey := FieldByName('ORDER_KEY').A
nStoreKey := FieldByName('STORE_KEY').A
if InList(sVendorKey, strlVendorError) or InList(sStoreKey, strlStoreError ) then
bEDISetupError := TRUE
else
begin
if (sOrderID = '') or (sCustomerID = '') or (sPassword = '') or
(sPhoneNum = '') then
begin
bEDISetupError := TRUE;
if not InList(sVendorKey, strlVendorError) then
strlVendorError.Add(sVendo
end;
if FieldByName('MODEM_TYPE').
begin
bEDISetupError := TRUE;
if not InList(sStoreKey, strlStoreError) then
strlStoreError.Add(sStoreK
end;
end;
if bEDISetupError then
begin
HandleErrorA(_msg_NoEDIInf
sVendorName );
Close;
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
Continue;
end;
Close;
end;//with qryOrder
with qryOrder do
begin
Close;
SQL.Clear;
SQL.Add(
'SELECT O.BUSINESS_DAY,'
+ _crlf + ' L.ORDER_QUANTITY,'
+ _crlf + ' P.PRODUCT_ID'
+ _crlf + 'FROM MDTRORDER_HDR O'
+ _crlf + ' INNER JOIN MDTRORDER_LINE L'
+ _crlf + ' ON L.ORDER_KEY = O.ORDER_KEY'
+ _crlf + ' INNER JOIN SYCFVENDOR V'
+ _crlf + ' ON V.VENDOR_KEY = O.VENDOR_KEY'
+ _crlf + ' INNER JOIN MDCFPROD_VEND_MULT P'
+ _crlf + ' ON P.VENDOR_KEY = O.VENDOR_KEY'
+ _crlf + ' AND P.PRODUCT_KEY = L.PRODUCT_KEY'
+ _crlf + ' AND P.MULTIPLIER = L.MULTIPLIER'
+ _crlf + 'WHERE O.ORDER_KEY = ' + OrderKeys[i]
);
Open;
{Create temp file}
sTempFile := fileTemp('.tmp');
{Clear the file stringlist}
strlFile.Clear;
{Transmission Header}
sLine := '$$ADD ID='
+ strPadR(sOrderID, 2)
+ strPadR(sCustomerID, 6)
+ ' BATCHID=''EOE ORDER''';
strlFile.Add(sLine);
{Header 2}
sLine := '1'
+ FormatDateTime('yyyymmdd',
+ strPadR(sOrderID, 2)
+ strPadR(sCustomerID, 6)
+ strPadR(sOrderNum, 10)
+ strSpace(47);
strlFile.Add(sLine);
{Detail Lines}
while not eof do
begin
fOrderQty := Trunc(FieldByName('ORDER_Q
sLine := '2'
+ strPadZeroL(FieldByName('P
+ strPadZeroL(IntToStr(fOrde
+ strSpace(11);
strlFile.Add(sLine);
{Totals for Summary Record}
Inc(nTotalDetailLines);
fTotalOrderQty := fTotalOrderQty + fOrderQty;
Next;
end;
{Summary Record}
sLine := '3'
+ strPadZeroL(IntToStr(nTota
+ strPadZeroL(IntToStr(Trunc
strlFile.Add(sLine);
Close;
end;//with qryOrder
strlFile.SaveToFile(sTempF
strlFileList.Add(sTempFile
+ _Tab + sStoreKey
+ _Tab + sVendorKey
+ _Tab + sDevice
+ _Tab + sPhoneNum
+ _Tab + sCustomerID
+ _Tab + sOrderID
+ _Tab + sPassword
+ _Tab + sVendorName
+ _Tab + sOrderNum
+ _Tab + sOrderKey
+ _Tab + sStoreID
);
{mainend}
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
end; {for}
if bShowProgress then
begin
Sleep(1000);
TerminateProgress;
end;
{-------------------------
if IsCancelled or (strlFileList.Count = 0) then Exit;
Progress := 0;
ProgressIncrement := 0;
if OrderDestination = odModem then
begin
if bShowProgress then
begin
CreateProgressDlg('Sending
ProgressIncrement := (1 / strlFileList.Count) * 100;
Application.ProcessMessage
end;
ComPort := TApdComPort.Create(nil);
ComPort.AutoOpen := FALSE;
ComPort.TapiMode := tmOn;
ComPort.Baud := 9600;
ComPort.DataBits := 8;
ComPort.Parity := pNone;
ComPort.StopBits := 1;
TapiDevice := TApdTapiDevice.Create(nil)
TapiDevice.ComPort := ComPort;
TapiDevice.OnTapiConnect := OnConnect;
TapiDevice.OnTapiFail := OnConnectFail;
TapiDevice.OnTapiPortClose
Protocol := TApdProtocol.Create(nil);
Protocol.ComPort := ComPort;
Protocol.ProtocolType := ptXModem;
Protocol.OnProtocolFinish := OnTransmitFinish;
Protocol_Log := TApdProtocolLog.Create(nil
Protocol_Log.Protocol := Protocol;
Protocol_Log.HistoryName := sLogDir + _ProtocolLogFile;
Protocol.ProtocolLog := Protocol_Log;
sCurrVendorKey := ''; {Track current vendor being processed}
strlVendorError.Clear; {Track vendors that errored out}
for i := 0 to strlFileList.Count - 1 do
begin
bFileError := FALSE;
strlSend.TabText := strlFileList[i];
sFileName := strlSend[0];
sStoreKey := strlSend[1];
sVendorKey := strlSend[2];
sDevice := strlSend[3];
sPhoneNum := strlSend[4];
sCustomerID := strlSend[5];
sOrderID := strlSend[6];
sPassword := strlSend[7];
sVendorName := strlSend[8];
sOrderNum := strlSend[9];
sOrderKey := strlSend[10];
nStoreKey := StrToInt(sStoreKey);
{If a previous attempt to send to this vendor failed, do not send the rest of the orders for this vendor}
if strlVendorError.IndexOf(sV
HandleError(Format(_msg_ED
if bFileError then goto 1;
if bShowProgress then
begin
Application.ProcessMessage
CheckProgress;
if IsCancelled then Break;
end;
{***** main *****}
if sVendorKey <> sCurrVendorKey then {If another vendor, establish new connection}
begin
bEstablishConnection := TRUE;
sCurrVendorKey := sVendorKey; {make this the "current vendor"}
{Cancel current call first}
if i <> 0 then
begin
if TapiDevice.TapiState = tsConnected then
begin
bConnectCancelled := FALSE;
bConnectCancelFailed := FALSE;
if not TapiDevice.CancelCall then
begin
WaitConnectCancel;
if bFileError then goto 1;
end;
end;
end;
{Prepare sign-on file first}
strlFile.Clear;
strlFile.Add('/*SIGNON RMT=' + sOrderID + sCustomerID + ' PASSWORD=' + sPassword);
strlFile.SaveToFile(sTempD
end
else {Connect only if disconnected}
bEstablishConnection := (TapiDevice.TapiState <> tsConnected);
{Connect}
if bEstablishConnection then
begin
bConnectDone := FALSE;
bConnectFailed := FALSE;
TapiDevice.SelectedDevice := sDevice;
TapiDevice.Dial(sPhoneNum)
WaitConnect;
if bFileError then goto 1;
if (not bConnectFailed) and bConnectDone then
begin
LogInfo('Connection established with ' + sVendorName + '.');
if ComPort.WaitForString('C',
begin
LogInfo('C received after establishing connection.');
{Transmit sign-on file}
SendFile(sTempDir + _SignOnFile);
if bFileError then
begin
HandleError(_msg_EDISignOn
goto 1;
end;
if nErrorCode <> 0 then
HandleError(_msg_EDISignOn
end
else
HandleError(_msg_EDIDidNot
end
else
HandleError(_msg_EDIConnec
end;
if bFileError then goto 1;
if ComPort.WaitForString('C',
begin
LogInfo('C received after sending sign-on file or before sending the next order file.');
{Transmit order file}
SendFile(sFileName);
if bFileError then goto 1;
if nErrorCode <> 0 then HandleError(ErrorMsg(nErro
end
else
HandleError(_msg_EDIDidNot
if bFileError then goto 1;
if not ComPort.WaitForString('C',
HandleError(_msg_EDIDidNot
else
LogInfo('C received after sending an order file (' + sFileName + ').');
if bFileError then goto 1;
1:
if bFileError then
begin
if strlVendorError.IndexOf(sV
strlVendorError.Add(sVendo
HandleError(Format(_msg_Or
end
else
strlSentOrders.Add(sOrderK
{***** mainend *****}
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
end; {for}
{Disconnect }
if TapiDevice.TapiState = tsConnected then
begin
bConnectCancelled := FALSE;
bConnectCancelFailed := FALSE;
if not TapiDevice.CancelCall then WaitConnectCancel;
if not bConnectCancelFailed then LogInfo('Connection cancelled.');
end;
end//if OrderDestination = odModem
else
begin
if bShowProgress then
begin
CreateProgressDlg('Copying
ProgressIncrement := (1 / strlFileList.Count) * 100;
Application.ProcessMessage
end;
sDestDir := GetAppDirectory(AdTransfer
ForceDirectories(sDestDir)
for i := 0 to strlFileList.Count - 1 do
begin
bFileError := FALSE;
strlSend.TabText := strlFileList[i];
sFileName := strlSend[0];
sVendorName := strlSend[8];
sOrderNum := strlSend[9];
sStoreID := strlSend[11];
if bShowProgress then
begin
Application.ProcessMessage
CheckProgress;
if IsCancelled then Break;
end;
sTempFile := sDestDir + '\ORDER' + StringOfChar('0', 8 - Length(sOrderNum)) +
sOrderNum + '_' + sStoreID + '.txt';
if FileExists(sTempFile) and (not DeleteFile(sTempFile)) then
HandleError(Format(_msg_Or
' ''' + SysErrorMessage(GetLastErr
else if not RenameFile(sFileName, sTempFile) then
HandleError(Format(_msg_Or
' ''' + SysErrorMessage(GetLastErr
else
strlSentOrders.Add(sOrderK
if bShowProgress then
begin
Progress := Progress + ProgressIncrement;
UpdateProgress;
end;
end;//for i := 0 to strlFileList.Count - 1
end;
{Update Status}
with genqry do
begin
Close;
SQL.Clear;
SQL.Add( 'UPDATE MDTRORDER_HDR'
+ _crlf + 'SET STATUS = ''' + _Sent + ''','
+ _crlf + ' SENT_DATE = GETDATE()'
+ _crlf + 'WHERE ORDER_KEY IN (' + strlSentOrders.CommaText + ')'
);
if strlSentOrders.CommaText <> '' then ExecSQL;
end;
if bShowProgress then
begin
Sleep(1000);
TerminateProgress;
end;
finally
qryOrder.Close;
qryOrder.Free;
genqry.Close;
genqry.Free;
strlFile.Free;
strlVendorError.Free;
strlStoreError.Free;
if Assigned(ComPort) then begin
ComPort.Free;
end;
if Assigned(TapiDevice) then begin
TapiDevice.Free;
end;
if Assigned(Protocol) then begin
Protocol.Free;
end;
if Assigned(Protocol_Log) then begin
Protocol_Log.Free;
end;
if bShowProgress then begin
TerminateProgress;
end;
for i := 0 to strlFileList.Count - 1 do begin
strlSend.TabText := strlFileList[i];
DeleteFile(strlSend[0]);
end;
strlSend.Free;
strlFileList.Free;
DeleteFile(sTempDir + _SignOnFile);
if bShowProgress then begin
if strlSentOrders.Count <> OrderKeys.Count then begin
MessageDlg(Format(_msg_EDI
end else begin
MessageDlg(_msg_EDISendCom
end;
end;
strlSentOrders.Free;
end;
end;
This is some very old, maybe 7-8 yrs, code and very convoluted. I'd like to be able to rewrite this to
better handle the error conditions outlined in the code. I am also going to write another procedure
called SendOrderFTP where I can use FTP to send the order .vs sending via TapiDevice and need
the HandleErrorA, HandleError, WaitConnect, WaitTransmit, WaitConnectCancel, and SendFile
public so it can be called from both of them.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
instead of going to 1...
raise an exception...
catch your exception
try
//rewrite all the code as procedure or method calls
except
On EFileError
end;
raise an exception...
catch your exception
try
//rewrite all the code as procedure or method calls
except
On EFileError
end;
ASKER
I been working on other things with that unit, like breaking out the creation
of the file and didn't see that. Thanks.
of the file and didn't see that. Thanks.
People who use GoTo should be shot. :-( Survivors should be shot again...
Sorry, just needed to rant a little about the use of the Goto statement, which should never have been part of Delphi in the first place. Please ignore this all...
Sorry, just needed to rant a little about the use of the Goto statement, which should never have been part of Delphi in the first place. Please ignore this all...
ASKER
Agreed. This code was written about 7-8 yrs ago by a group that we purchased the software from and
they had a very strange way of looking at things going on in our market. They almost totally ignored
how things were being done market-wide and stayed within a narrow specification that satisfied
their two largest customers only.
We've fortunately, been able to get some of the market-share back due to our butchering up the
remnants of their stuff but there are things that we haven't touched in a while and we're constantly
finding gotchas like this.
Trying to refactor their stuff is almost likea total re-write. Kind of frustrating, too, when their are no
developer comments in the source code.
But hey..."Pascal is self-documenting", said an old employer that deplored comments in our code and
stripped them all out when we checked it in to our version control. fortunately, I no longer work for them
and their horrid code base.
they had a very strange way of looking at things going on in our market. They almost totally ignored
how things were being done market-wide and stayed within a narrow specification that satisfied
their two largest customers only.
We've fortunately, been able to get some of the market-share back due to our butchering up the
remnants of their stuff but there are things that we haven't touched in a while and we're constantly
finding gotchas like this.
Trying to refactor their stuff is almost likea total re-write. Kind of frustrating, too, when their are no
developer comments in the source code.
But hey..."Pascal is self-documenting", said an old employer that deplored comments in our code and
stripped them all out when we checked it in to our version control. fortunately, I no longer work for them
and their horrid code base.
That code is written like Old Basic code...This was the only way to handle errors in a semi elegant way...without trapping your code with Error Code everywhere...
in a way it's simlar to a Try throw exception Except block...They obviously never embraced Delphi and where programming pre Turbo Pascal 5.5 for Dos(which added Objects)...(would not suprise me if this code is a port from Old DOS Base)
in a way it's simlar to a Try throw exception Except block...They obviously never embraced Delphi and where programming pre Turbo Pascal 5.5 for Dos(which added Objects)...(would not suprise me if this code is a port from Old DOS Base)
ASKER
Nope, DataFlex.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
My feeling after carefully looking at the code, was that the developer was only doing this inside the for loop and
was breaking to check some statuses and then moving on to the next item in the loop.
I thik I have it down. I will be awarding points later today.
was breaking to check some statuses and then moving on to the next item in the loop.
I thik I have it down. I will be awarding points later today.
opps...your forgot something...
except on EAbort do ; // Silently ignore abort.
end
else
raise;
;)
except on EAbort do ; // Silently ignore abort.
end
else
raise;
;)
Yep. I blame old age for that forgetfullness. :-)
ASKER
it really doesn't do anything.