Solved

Old code, using labels/goto. Need to remove them.

Posted on 2006-07-24
16
418 Views
Last Modified: 2010-04-16
Got this structure inside one of my procedures:

  label 1;

  procedure HandleErrorA(sMsg: string);
  begin
    LogSendOrderError(nStoreKey, _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.ProcessMessages;
      if (Now - dt) > TimeoutLength then begin
        HandleError(_msg_EDIConnectTimeout);
        Break;
      end;
    end;
  end;

  procedure WaitTransmit;
  var
    dt: TDateTime;
  begin
    dt := Now;
    while not bTransmitDone do begin
      Sleep(_SleepLength);
      Application.ProcessMessages;
      if (Now - dt) > TimeoutLength then begin
        HandleError(_msg_EDITransmitTimeout);
        Break;
      end;
    end;
  end;

  procedure WaitConnectCancel;
  var
    dt: TDateTime;
  begin
    dt := Now;
    while not bConnectCancelled do begin
      Sleep(_SleepLength);
      Application.ProcessMessages;
      if (Now - dt) > TimeoutLength then begin
        HandleError(_msg_EDIConnectCancelTimeout);
        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.
0
Comment
Question by:EddieShipman
  • 7
  • 4
  • 3
  • +1
16 Comments
 
LVL 26

Assisted Solution

by:Russell Libby
Russell Libby earned 100 total points
ID: 17170714

The label 1 is jumped to directly. You didn't show the label code, but most likely it was sitting at the bottom of your function/procedure. People use it as a way of short cutting out of multiple if statements. Another way of writing something like that would be:

try
  // Do some stuff
  if Error then exit;
finally
  // Check error and do whatever else needs to be done
end;

But is normally handed with multiple if statements

if This then
begin
  if That then
  begin

  end
  else
    Error;
end
else
  Error;

--

Regards,
Russell
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17170741
I did show the label code, it is OUTSIDE any other procedure. I am suspecting that
it really doesn't do anything.
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17170757
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.
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17170772
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.
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17171308
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(nStoreKey, _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.ProcessMessages;
      if (Now - dt) > TimeoutLength then begin
        HandleError(_msg_EDIConnectTimeout);
        Break;
      end;
    end;
  end;

  procedure WaitTransmit;
  var
    dt: TDateTime;
  begin
    dt := Now;
    while not bTransmitDone do begin
      Sleep(_SleepLength);
      Application.ProcessMessages;
      if (Now - dt) > TimeoutLength then begin
        HandleError(_msg_EDITransmitTimeout);
        Break;
      end;
    end;
  end;

  procedure WaitConnectCancel;
  var
    dt: TDateTime;
  begin
    dt := Now;
    while not bConnectCancelled do begin
      Sleep(_SleepLength);
      Application.ProcessMessages;
      if (Now - dt) > TimeoutLength then begin
        HandleError(_msg_EDIConnectCancelTimeout);
        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('Creating McLane Electronic Order(s)');
      ProgressIncrement := (1 / OrderKeys.Count) * 100;
      Application.ProcessMessages;
    end;

    sTempDir := sysTempPath;
    sLogDir := ExtractFilePath(ParamStr(0));
    sLogDir := ExtractFilePath(Copy(sLogDir, 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.ProcessMessages;
        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').AsString;
        sStoreKey   := FieldByName('STORE_KEY').AsString;
        sVendorKey  := FieldByName('VENDOR_KEY').AsString;
        sDevice     := FieldByName('MODEM_TYPE').AsString;
        sPhoneNum   := FieldByName('ORDER_PHONE').AsString;
        sCustomerID := Trim(FieldByName('CUSTOMER_ID').AsString);
        sOrderID    := Trim(FieldByName('ORDER_ID').AsString);
        sPassword   := FieldByName('ORDER_PASSWORD').AsString;
        sVendorName := FieldByName('VENDOR_NAME').AsString;
        sOrderNum   := FieldByName('ORDER_NUM').AsString;
        sOrderKey   := FieldByName('ORDER_KEY').AsString;
        nStoreKey   :=  FieldByName('STORE_KEY').AsInteger;

        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(sVendorKey);
          end;

          if FieldByName('MODEM_TYPE').AsString = '' then
          begin
            bEDISetupError := TRUE;
            if not InList(sStoreKey, strlStoreError) then
              strlStoreError.Add(sStoreKey);
          end;
        end;

        if bEDISetupError then
        begin
          HandleErrorA(_msg_NoEDIInfoSetup + ' 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').AsDateTime)
          + 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_QUANTITY').AsFloat + 0.5); {round up}
          sLine := '2'
            + strPadZeroL(FieldByName('PRODUCT_ID').AsString, 6)
            + strPadZeroL(IntToStr(fOrderQty), 5)
            + strSpace(11);
          strlFile.Add(sLine);

          {Totals for Summary Record}
          Inc(nTotalDetailLines);
          fTotalOrderQty := fTotalOrderQty + fOrderQty;

          Next;
        end;

        {Summary Record}
        sLine := '3'
          + strPadZeroL(IntToStr(nTotalDetailLines), 6)
          + strPadZeroL(IntToStr(Trunc(fTotalOrderQty)), 9);
        strlFile.Add(sLine);

        Close;
      end;//with qryOrder

      strlFile.SaveToFile(sTempFile);
      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.ProcessMessages;
      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(sVendorKey) <> -1 then
          HandleError(Format(_msg_EDICannotSendToVendor, [sVendorName]));

        if bFileError then goto 1;

        if bShowProgress then
        begin
          Application.ProcessMessages;
          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(sTempDir + _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_EDISignOnError);
                goto 1;
              end;

              if nErrorCode <> 0 then
                HandleError(_msg_EDISignOnError + ' ' + ErrorMsg(nErrorCode));
            end
            else
              HandleError(_msg_EDIDidNotReceiveC + ' After connecting.');
          end
          else
            HandleError(_msg_EDIConnectionError);
        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(nErrorCode));
        end
        else
          HandleError(_msg_EDIDidNotReceiveC + ' 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_EDIDidNotReceiveC + ' 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(sVendorKey) = -1 then
            strlVendorError.Add(sVendorKey);

          HandleError(Format(_msg_OrderNotSent, [sVendorName, sOrderNum]));
        end
        else
          strlSentOrders.Add(sOrderKey); {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.ProcessMessages;
      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.ProcessMessages;
          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_OrderNotSent, [sVendorName, sOrderNum]) +
                      ' ''' + SysErrorMessage(GetLastError) + '''')
        else if not RenameFile(sFileName, sTempFile) then
          HandleError(Format(_msg_OrderNotSent, [sVendorName, sOrderNum]) +
                      ' ''' + SysErrorMessage(GetLastError) + '''')
        else
          strlSentOrders.Add(sOrderKey); {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_EDISendIncomplete, [IntToStr(strlSentOrders.Count), IntToStr(OrderKeys.Count)]), mtInformation, [mbOk], 0);
      end else begin
        MessageDlg(_msg_EDISendComplete, 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.


0
 
LVL 6

Accepted Solution

by:
House_of_Dexter earned 200 total points
ID: 17171418
This is what it does

1:
        if bFileError then
        begin
          if strlVendorError.IndexOf(sVendorKey) = -1 then
            strlVendorError.Add(sVendorKey);

          HandleError(Format(_msg_OrderNotSent, [sVendorName, sOrderNum]));
        end
        else
          strlSentOrders.Add(sOrderKey); {Remember successfully sent orders}
0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 17171448
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;
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17171496
I been working on other things with that unit, like breaking out the creation
of the file and didn't see that. Thanks.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 17173866
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...
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17176678
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.
0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 17176901
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)


0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17178958
Nope, DataFlex.
0
 
LVL 17

Assisted Solution

by:Wim ten Brink
Wim ten Brink earned 200 total points
ID: 17182181
> "Pascal is self-documenting", said an old employer that deplored comments in our code

My previous employer also considered it a waste of my time when I added comments into the sourcecode that I was working on. Unfortunately for him, some of the code I worked on contained some pretty complex algorithm stuff where one mistake could have some major effects. It was the same employer, btw, who had developed an application in the past that was picked up by some anti-virus products as 'Dangerous' and 'possible virus'. And when I had to examine why this happened, I even discovered that the application did have some viral behaviour. It was an Outlook add-in but it contained a keyhook. Since the add-in is a DLL something nasty happened when the keyhook was installed. The whole DLL didn't just become part of the Outlook process but it became part of ALL running processes! Pretty nasty since a simple crash of Outlook or our add-in could result in a total system crash leaving the user with a nice, blue screen with white letters...
I fixed that problem and added a comment to it. A warning to be more careful with this kind of code. And then I left the company to work for a better-paying employer. And my old employer? He had to find a developer who was experienced enough to understand the algorithms and who could manage with the lack of comments in the code. Well, he outsourced the project and is now able to blame someone else when the project fails again. And again...

And about the Goto problem? All I can suggest is that you try to follow the flow of the application and rewrite the code where needed. Beware, House_of_Dexter already found the location. Search for '1:' in the procedure. :-) Done the work for you, and I think (based on the suggestions of the other members) that you'd end up with this code, starting from the first Goto statement to the location where the label is set:

        try
          if bFileError then Abort;

          if bShowProgress then
          begin
            Application.ProcessMessages;
            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 Abort;
                end;
              end;
            end;
            {Prepare sign-on file first}
            strlFile.Clear;
            strlFile.Add('/*SIGNON RMT=' + sOrderID + sCustomerID + ' PASSWORD=' + sPassword);
            strlFile.SaveToFile(sTempDir + _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 Abort;

            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_EDISignOnError);
                  Abort;
                end;

                if nErrorCode <> 0 then
                  HandleError(_msg_EDISignOnError + ' ' + ErrorMsg(nErrorCode));
              end
              else
                HandleError(_msg_EDIDidNotReceiveC + ' After connecting.');
            end
            else
              HandleError(_msg_EDIConnectionError);
          end;

          if bFileError then Abort;

          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 Abort;
            if nErrorCode <> 0 then HandleError(ErrorMsg(nErrorCode));
          end
          else
            HandleError(_msg_EDIDidNotReceiveC + ' After sending sign-on file or before sending the next order file.');

          if bFileError then Abort;

          if not ComPort.WaitForString('C', _WaitForStringTimeout, FALSE, TRUE) then
            HandleError(_msg_EDIDidNotReceiveC + ' After sending an order file.')
          else
            LogInfo('C received after sending an order file (' + sFileName + ').');

          if bFileError then Abort;
        except on EAbort do ; // Silently ignore abort.
        end;

It's not my idea, though. Blame House_of_Dexter for this solution. :-) I just point out how it will look like in code.
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 17183988
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.
0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 17185343
opps...your forgot something...

except on EAbort do ; // Silently ignore abort.
        end
else
  raise;

;)
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 17222672
Yep. I blame old age for that forgetfullness. :-)
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now