Continuation of the article “Let’s be friends with tables”

The three most popular buttons in applications built with the My Visual Dtabase development environment are tabular data editing buttons: add, modify, and delete a record. They are usually found next to each table that the user intends to edit. Their functionality is determined by visual settings, and the creation takes a few seconds. But in our application there are only three editing buttons, so they will not be ordinary, but “heroic”. Such buttons will easily cope with all

These buttons are located on the main form (1) and have traditional names and pictures (2). But that’s where their similarity to standard buttons ends, as all their power lies in the scripts. And the power of scripts is in the conventions that must be observed when naming application forms.

Conventions

Conventions are rules that a developer sets for himself. This is a very useful practice that allows you to write efficient code. Details about this technique and various examples of its use are written in my book “Visual Programming”, Chapter 12. Good Deal .

The following are conventions that have helped in writing efficient code for edit buttons.

Names for table view forms

The name of the form must consist of the three-character prefix frm followed by the name of the table that the form is displaying. The table name may be followed by a suffix. The suffix is ​​separated from the table name by an underscore and consists of an arbitrary number of characters. Thanks to the suffix, you can create several forms of a tabular

frm<table name>[_<suffix>]

For example, in our application, the classType table stores various information displayed by various forms: data about types (frmClassType_TypeList) and classes, and classes are represented as a list ( frmClassType_List) and as a tree (frmClassType_Tree).

Names for editing forms

The name of the editing form consists of the prefix efm and the name of the table that this form is intended to edit.

efm<table name>

Scripts

Adding a new record uses the form method NewRecord(). The name of the table is passed to it as the first parameter.

Note. The second parameter is used when creating child records in a tree structure, but it requires a component with certain settings on the editing form. Our application will use a different technology for adding to the tree.
procedure frmMain_btnNew_OnClick (Sender: TObject; var Cancel: boolean);
// addition
var
  tmpID: integer;
  tmpTableName: string;
  tmpEditForm:TAForm;
  tmpForm:TAForm;
begin
  // if the tab with an example is open, then create an example
  if frmMain.pgcMain.ActivePage = frmMain.tshExample then
  begin
    efmExample.NewRecord('example');
  end
  else // if the navigator tab is open and the user has selected a table, then we create an entry in the table
  if (frmMain.pgcMain.ActivePage = frmMain.tshNavigation) and (ActiveGrid <> nil) then
  begin
    // define the name of the edited table using the form naming convention
    // <frm><table name>[_<suffix>]
    tmpTableName := Grid_GetTableName(ActiveGrid);
    // use the convention for the edit form:
    // the edit form is called by the template:
    // <efm><table name>
    tmpEditForm := App_GetFormByName('efm'+tmpTableName);
    CForm(ActiveGrid,tmpForm);
    // some tables depend on the main ones, so a check is needed
    if not Form_CheckMasterForm(tmpForm.Name) then
      ShowHint(ActiveGrid,'Select a record in the main table')
    else
      // open edit form
      tmpEditForm.NewRecord(tmpTableName);
  end;
end;Code language: Delphi (delphi)

The editing procedure is also very elegant, and is based on the ShowRecord() form method, in which the table name and the number of the record being edited are passed as parameters.

procedure frmMain_btnEdit_OnClick (Sender: TObject; var Cancel: boolean);
// редактирование
var
  tmpID: integer;
  tmpTableName: string;
  tmpEditForm:TAForm;
begin
  if frmMain.pgcMain.ActivePage = frmMain.tshExample then
  begin
    if IDExample <> -1 then
    begin
      efmExample.ShowRecord('example',IDExample);
      LoadExample;
    end;
  end
  else
  if frmMain.pgcMain.ActivePage = frmMain.tshNavigation then
  begin
    tmpID := ActiveGrid.dbItemID;
    tmpTableName := Grid_GetTableName(ActiveGrid);
    if tmpID = -1 then
      ShowHint(ActiveGrid,'Select record')
    else
    begin
      // we use the convention:
      // the edit form is called by the template:
      // <efm><table name>
      tmpEditForm := App_GetFormByName('efm'+tmpTableName);
      if tmpEditForm<>nil then
        tmpEditForm.ShowRecord(tmpTableName, tmpID );
    end;
  end;
end;Code language: Delphi (delphi)

Deletion looks similar to editing, but uses the SQL DELETE command in its work:

procedure frmMain_btnDelete_OnClick (Sender: TObject; var Cancel: boolean);
var
  tmpID: string;
  tmpTableName: string;
begin
  if frmMain.pgcMain.ActivePage = frmMain.tshExample then
  begin
    if IDExample <> -1 then
      if MessageBox( 'Delete example?', 'Delete', MB_YESNO + MB_ICONWARNING ) = mrYes then
      begin
        SQLExecute('delete from example where id = '+IntToStr(IDExample) );
        UpdateDatabase('example');
      end;
  end
  else
  if (frmMain.pgcMain.ActivePage = frmMain.tshNavigation) and (ActiveGrid<>nil) then
  begin
    tmpID := IntToStr(ActiveGrid.dbItemID);
    tmpTableName := Grid_GetTableName(ActiveGrid);
    if tmpID = '-1' then
      ShowHint(ActiveGrid,'Select record')
    else
    if MessageBox( 'Delete record?', 'Delete', MB_YESNO + MB_ICONWARNING ) = mrYes then
    begin
      SQLExecute('delete from '+tmpTableName+' where id = '+tmpID );
      UpdateDatabase(tmpTableName);
    end;
  end;
end;Code language: Delphi (delphi)

The above procedures use the key function Grid_GetTableName(). Its implementation looks very concise.

function Grid_GetTableName( AGrid: TdbStringGridEx ):string;
// возвращает имя таблицы
var
  tmpForm:TAForm;
begin
  // We use the naming convention of the form:
  // <frm><table name>[_<suffix>]
  // i.e. there can be multiple table view forms for one table,
  // they must be distinguished by the suffix
  CForm(AGrid,tmpForm);
  Result := DeleteSuffix(DeleteClassName(tmpForm.Name));
end;Code language: Delphi (delphi)
Note. When trying to create a similar function without using naming conventions, I found a bug in MVDB, namely: the TdbTreeView component in the dbGeneralTable property does not have the name of the table that it displays. This error prevented us from creating a universal function that would work both for tables and for a tree.

And here is another useful function used in the “heroic” buttons procedures, which returns the application form by name:

function App_GetFormByName(AName: string): TAForm;
// get form by name
var
  tmpForm: TAForm;
  i: integer;
begin
  AName := UpperCase(AName);
  for i := 0 to Screen.FormCount - 1 do
  begin
    Result := TAForm(Screen.Forms[i]);
    if UpperCase(Result.Name) = AName then
      exit;
  end;
  Result := nil;
end;Code language: PHP (php)

To be continued

Leave a Reply

Your email address will not be published. Required fields are marked *