BCS Mass Links (Global Changes)

There are those time when source code files require changes of a specific occurrence of datum from one value to a new value.

This component accomplishes that goal by employing sub directory selection and file specification via a specified extension.

Once the file for modification are identifies simple click on the Update Files menu item and the designated changes are applied in every occurrence.

The files selection is made by the following code.

{*-----------------------------------------------------------------------------
 Procedure: LoadFiles1Click
 Date:      29-Dec-2013
 @Param     Sender: TObject
 @Return    None
 
 -----------------------------------------------------------------------------}
 
procedure TBCSMassLinkC.LoadFiles1Click(Sender: TObject);
begin
  BCSXE3UtilsCmp1.PopulateListBox
    (BCSXE3UtilsCmp1.GetFileNames(BCSXE3UtilsCmp1.SelADir, '*.htm'),
    BCSXE3UtilsCmp1.FilLen, ListBox1);
end;

Of course the above procedure is executed when the Load Files menu item is clicked.

The global or mass changes are invoked by the snippet below.

{*-----------------------------------------------------------------------------
 Procedure: UpdateFiles1Click
 Date:      29-Dec-2013
 @Param     Sender: TObject
 @Return    None
 
 -----------------------------------------------------------------------------}
 
procedure TBCSMassLinkC.UpdateFiles1Click(Sender: TObject);
var
  j: Integer;
begin
  i := 0;
  repeat
    sc.LoadFromFile(ListBox1.Items[i]);
    j := 0;
    repeat
      buf := sc[j];
      buf := StringReplace(buf,
        'Created with DelphiCodeToDoc. To obtain the latest revision, please visit ',
        'Please Visit The Brooks Computing Systems, LLC Web Site. ',
        [rfreplaceAll]);
      buf := StringReplace(buf, 'http://dephicodetodoc.sourceforge.net',
        'http://bcsjava.com', [rfreplaceAll]);
      sc[j] := buf;
      Inc(j);
    until j > sc.Count - 1;
    sc.SaveToFile(ListBox1.Items[i]);
    Inc(i);
  until i > ListBox1.Items.Count - 1;
  // ModalResult := mrOk;
  Close;
end;

Any possible combination of changes are available simply by including or modifying StringReplace statements.  As always there are many variations of how to make things work more efficiently but in our example I intended to use the KISS methodology.

The component documentation for this component may be found here.  http://archbrooks.com/compdoc/BCSMassLink/html/BCS%20Mass%20Link%20Global%20Changes.htm

The source code for this project may be located here.  http://cc.embarcadero.com/item/29680

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems, LLC authored this article.

BCS Move A File Component

This utility provides all the necessary communications to effective move a file from an existing location to a new location.

This is accomplished by selecting the target directory after a source file is supplied via the RSource property.

The file name and extension is copied from the RSource property and appended to the target directory. The file is copied to the desired location and if the file copy was successful a deletion of the RSource property specification occurs.

Message Boxes are used to advise the end user of the success or failure of the operation.

Component documentation is located at http://archbrooks.com/compdoc/BCSMoveFile/html/BCS%20Move%20A%20File.htm

The source code may be downloaded from http://cc.embarcadero.com/Item/29679

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems, LLC authored this article.

BCS Populate List Box (One Liner)

There are those occasion when we need to populate a list box with file names to subsequently act on one of more of those file names.

With the BCSXE3Utils this is accomplished in one easy statement.

Be sure to watch the video near the end of this post.

{*-----------------------------------------------------------------------------
  Procedure: LoadListBox1Click
  Date:      18-Dec-2013
  @Param     Sender: TObject
  @Return    None
 
-----------------------------------------------------------------------------}
 
procedure TBCSCopItC.LoadListBox1Click(Sender: TObject);
begin;
  BCSXE3UtilsCmp1.PopulateListBox
    (BCSXE3UtilsCmp1.GetFileNames(BCSXE3UtilsCmp1.SelADir, '*.bat'),
    BCSXE3UtilsCmp1.FilLen, ListBox1);
end;

Notice the GetFileNames function prompts the user to select a directory and specifiles ‘*.bat’ as the file extension.  This yields a traversed list of all available subdirectories from the selected sub directory that contains batch files only.

Once the listbox is populated the further action can be taken as indicated by the example below.

{*-----------------------------------------------------------------------------
  Procedure: ListBox1DblClick
  Date:      18-Dec-2013
  @Param     Sender: TObject
  @Return    None
 
-----------------------------------------------------------------------------}
 
procedure TBCSCopItC.ListBox1DblClick(Sender: TObject);
begin
  BCSXE3UtilsCmp1.ShellExec(ListBox1.Items[ListBox1.ItemIndex]);
end;

As the above code indicates when the listbox item is double clicked the ShellExecute command of BCSXE3Utils is invoked.

This gives the technician a quick and dirty method of acting on a list of files in a listbox.


The source code for BCSXE3Utils is found here http://cc.embarcadero.com/Item/29423.

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems, LLC authored this article.

BCS Filter Records By Date Range

There are those times when data records need to be selected based on date fields. The following code snippet indicates how to filter records for a specific day.

{*-----------------------------------------------------------------------------
  Procedure: Daily1Click
  Date:      15-Dec-2013
  @Param     Sender: TObject
  @Return    None
 
-----------------------------------------------------------------------------}
 
procedure TBCSTasksC.Daily1Click(Sender: TObject);
var
  rdt: TDateTime;
  ft, et: string;
begin
  BCSGetDateTimeCmp1.SelDateTime := Now;
  if BCSGetDateTimeCmp1.Execute then
  begin
    rdt := BCSGetDateTimeCmp1.SelDateTime;
    ft := FormatDateTime('yyyy-mm-dd', rdt) + ' 00:00:00';
    et := FormatDateTime('yyyy-mm-dd', rdt) + ' 23:59:59';
    BCSTasksdm.atattd.Filter := '((sdt >=' + '''' + ft + '''' + ') and (edt <='
      + '''' + et + '''' + '))';
    BCSTasksdm.atattd.Filtered := True;
  MemView := BCSTasksdm.frxReport1.FindObject('Memo4') as TfrxMemoView;
  MemView.Text := 'Category ' + FormatDateTime('dddd, mmmm dd, yyyy', rdt);
  end;
end;

Notice the date format for MySQL is yyyy-mm-dd hh:mm:ss.  There is a starting date and time and an ending date and time.  The filter selects records between the date time ranges.

To select the records for a specific week the following code snippet should be adhered to.

{*-----------------------------------------------------------------------------
  Procedure: Weekly1Click
  Date:      15-Dec-2013
  @Param     Sender: TObject
  @Return    None
 
-----------------------------------------------------------------------------}
 
procedure TBCSTasksC.Weekly1Click(Sender: TObject);
var
  fd, ld: String;
  rdt: TDateTime;
begin
  BCSGetDateTimeCmp1.SelDateTime := Now;
  if BCSGetDateTimeCmp1.Execute then
  begin
    rdt := BCSGetDateTimeCmp1.SelDateTime;
    BCSXE3UtilsCmp1.FirLasDow(rdt);
    fd := FormatDateTime('yyyy-mm-dd hh:mm:ss', BCSXE3UtilsCmp1.FirstDayOfWeek);
    ld := FormatDateTime('yyyy-mm-dd hh:mm:ss', BCSXE3UtilsCmp1.LastDayOfWeek);
    BCSTasksdm.atattd.Filter := '((sdt >= ' + '''' + fd + '''' + ') and (edt <='
      + '''' + ld + '''' + '))';
    BCSTasksdm.atattd.Filtered := True;
      MemView := BCSTasksdm.frxReport1.FindObject('Memo4') as TfrxMemoView;
  MemView.Text := 'Category ' +
  FormatDateTime('dddd, mmmm dd, yyyy', BCSXE3UtilsCmp1.FirstDayOfWeek) +
  ' Thru ' +
  FormatDateTime('dddd, mmmm dd, yyyy', BCSXE3UtilsCmp1.LastDayOfWeek);
 
  end;
end;

The date ranges span midnight on Monday through midnight on Sunday.

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems, LLC authored this article.

BCS Data Grid With Data Entry Component Enhancement

Many times it is advantageous to use a component to accomplish data entry as opposed to the default data entry platform. An example of this it to use a component for date time data entry. A drop down calendar and spin controls for the other data entry functions is readily available.

The code snippet below shows how to implement component functionality for data entry capabilities.

{*-----------------------------------------------------------------------------
 Procedure: BCSTasksGrid1TitleClick
 Date:      14-Aug-2013
 @Param     Column: TColumn
 @Return    None
 
 -----------------------------------------------------------------------------}
 
procedure TBCSTasksC.BCSTasksGrid1CellClick(Column: TColumn);
begin
  if ((Column.Field.FullName = 'sdt') or (Column.Field.FullName = 'edt')) then
  begin
    BCSGetDateTimeCmp1.SelDateTime := Column.Field.AsDateTime;
    if BCSGetDateTimeCmp1.Execute then
    begin
      BCSTasksGrid1.DataSource.DataSet.Edit;
      Column.Field.AsDateTime := BCSGetDateTimeCmp1.SelDateTime;
      BCSTasksGrid1.DataSource.DataSet.Post;
    end;
  end;
end;

In our example two date fields are employed.  Any number of date fields may be used.  Simply modify the if statement to add as many date fields that are required.

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems, LLC authored this article.

BCS Multiple Table Database Query

There are those time when several tables must be combined to complete a reporting retirement. When those situation arise simply use a query to select all the data elements from each table. If there are multiple records in the table the where clause should be used in each primary key so only the record desired are returned in the results. The query also be parameterized so the key variable are seamlessly applied to the query.

The example below will demonstrate the overall desired effect.

SELECT * FROM cd01,cd02,cd03 WHERE did = :rdid AND motid = :rmotid AND sigid = 1

The fields prefixed by the colon (:) are the parameters.  Make sure parameters are of the respective type and are defined prior to invoking the code to start the result retrieval.

The following snippet shows how to actually invoke the parameterized query.

{*-----------------------------------------------------------------------------
  Procedure: RunReps1Click
  Date:      13-Dec-2013
  @Param     Sender: TObject
  @Return    None
 
-----------------------------------------------------------------------------}
 
procedure TBCSCcXqtC.RunReps1Click(Sender: TObject);
begin
  if BCSCcHeadCmp1.Execute then
  begin
    if BCSCcBodyCmp1.Execute then
    begin
      UniQuery1.Close;
      UniQuery1.ParamByName('rdid').AsInteger := BCSCcHeadCmp1.RDid;
      UniQuery1.ParamByName('rmotid').AsInteger := BCSCcBodyCmp1.RMot;
      // UniQuery1.ParamByName('rsigid').AsInteger := 1;
      UniQuery1.Open;
      frxReport2.ShowReport(true);
    end;
  end;

The first component selects the document id or RDid while the second component sets the motion parameter for the query to be set RMot.   The query is closed, the parameters are set, the query is opened and the report is generated.

Parameterized queries are very useful to positioning data in a table and returning a queried result.  To achieve this level of functionality with table components would be difficult if not impossible.

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems, LLC authored this article.

BCS Fast Reports Reusability

A regular recurring theme when developing software there exists scenarios where an application can have more than one entity using the facilities or database and reports.

The unique id number must exists for each entity then master detail relationships are employed to traverse the applications facilities.

The main difference in the reporting facilities are the headings used by each entity.

To promote reusability of the reports subsystem properties are established at the component level that allows for changing headings to reflect the appropriate entity.

When the component is used the following code is available to support the multi entity application.

{*-----------------------------------------------------------------------------
  Procedure: btnTestCompClick
  @Author Mr. Arch Brooks, Software Engineer, Brooks Computing Systems LLC
  @Version 1.0
  Date:      09-May-2013
  @Param  Sender TObject Primary Object For Dialog
  Result:    None
  ----------------------------------------------------------------------------- }
 
procedure TBCSJeiSvccmpC.btnTestCompClick(Sender: TObject);
begin
  BCSJeiSvcCmp1.RCaption := 'BCS Costs of Services';
  BCSJeiSvcCmp1.RCid := 1;
  BCSJeiSvcCmp1.RH1 := 'Brooks Computing Systems, LLC';
  BCSJeiSvcCmp1.RH2 := 'P. O. Box 7682';
  BCSJeiSvcCmp1.RH3 := 'Columbia, Missouri 65205-7682';
  BCSJeiSvcCmp1.RH4 := 'Costs of Services';
  BCSJeiSvcCmp1.Execute;
end;

Notice the components properties are all preceded by a capital R the the property description.  This is a standard enforced to properly identify and group all component properties.

The definition of the frxMemoView class is found in frxClass.  To access it be sure to include it in a uses statement.

uses frxClass;

The following code snippet show how the component with implement the available properties.

{*-----------------------------------------------------------------------------
 Procedure: Execute
 @Author Mr. Arch Brooks, Software Engineer, Brooks Computing Systems LLC
 @Version 1.0
 Date:      09-May-2013
 Arguments: None
 @return    Boolean T Sucessful Execution F Unsucessful Execution
 -----------------------------------------------------------------------------}
 
function TBCSJeiSvcCmp.Execute: BooLean;
var
  MemView: TfrxMemoView;
begin
  result := false;
  Application.CreateForm(TBCSJeiSvcdm, BCSJeiSvcdm);
  if RCid = 0 then
  begin
    RCid := 1;
  end;
  BCSJeiSvcdm.RCid := RCid;
  BCSJeiSvcdm.ataei_svcs.Active := false;
  BCSJeiSvcdm.ataei_svcs.Filter := 'cid = ' + IntToStr(RCid);
  BCSJeiSvcdm.ataei_svcs.Filtered := true;
  BCSJeiSvcdm.ataei_svcs.Active := true;
  Application.CreateForm(TBCSJeiSvcC, BCSJeiSvcC);
 
  MemView := BCSJeiSvcdm.frxReport1.FindObject('Memo2') as TfrxMemoView;
  MemView.Text := RH1;
  MemView := BCSJeiSvcdm.frxReport1.FindObject('Memo3') as TfrxMemoView;
  MemView.Text := RH2;
  MemView := BCSJeiSvcdm.frxReport1.FindObject('Memo4') as TfrxMemoView;
  MemView.Text := RH3;
  MemView := BCSJeiSvcdm.frxReport1.FindObject('Memo5') as TfrxMemoView;
  MemView.Text := RH4;
 
  if RCaption > '' then
  begin
    BCSJeiSvcC.Caption := RCaption;
  end;
  if BCSJeiSvcC.ShowModal = id_OK then
  begin
    result := true;
  end;
  BCSJeiSvcC.Free;
  BCSJeiSvcdm.Free;
end;

Notice the RCid (company / entity id) property is set to one if it is not initialized.  Also notice the RCid is used in the filter for the data table.  This ensures only the records for the desired entity are exposed.

Next the headings are set along with the dialog caption.  These features ensures our application is usable by multiple companies or entities without changing the core functionality of the application.

Mr. Arch Brooks, Software Engineer, Brooks Computing Systems authored this article.