Advertisement
believe_me

Untitled

May 19th, 2022
1,443
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. unit StartUnit;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, EditUnit, Vcl.Themes, Vcl.Styles,
  8.   Vcl.Samples.Spin, ShowUnit;
  9.  
  10. type
  11.   TStartForm = class(TForm)
  12.     ShowModeButton: TButton;
  13.     EditModeButton: TButton;
  14.     MainMenu: TMainMenu;
  15.     InstructionMenu: TMenuItem;
  16.     DeveloperMenu: TMenuItem;
  17.     CostSpinEdit: TSpinEdit;
  18.     ModeLabel: TLabel;
  19.     ColorLabel: TLabel;
  20.     LightRButton: TRadioButton;
  21.     DarkRButton: TRadioButton;
  22.     CostLabel: TLabel;
  23.     procedure DeveloperMenuClick(Sender: TObject);
  24.     procedure EditModeButtonClick(Sender: TObject);
  25.     procedure ShowModeButtonClick(Sender: TObject);
  26.     procedure FormCreate(Sender: TObject);
  27.     procedure LightRButtonClick(Sender: TObject);
  28.     procedure DarkRButtonClick(Sender: TObject);
  29.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  30.     procedure InstructionMenuClick(Sender: TObject);
  31.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  32.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  33.   private
  34.     { Private declarations }
  35.   public
  36.     { Public declarations }
  37.   end;
  38.  
  39. var
  40.     StartForm: TStartForm;
  41.     ServiceCost: integer;
  42.  
  43. implementation
  44.  
  45. {$R *.dfm}
  46.  
  47. uses
  48.     WriteUnit;
  49.  
  50. const
  51.     LIGHT_SKIN = 'Smokey Quartz Kamri';
  52.     DARK_SKIN = 'Charcoal Dark Slate';
  53.  
  54. procedure TStartForm.DeveloperMenuClick(Sender: TObject);
  55. begin
  56.     MessageDlg('Student: Ravodin Alexander Dmitrievich.' + #13#10 + 'Group: 151002.'
  57.                + #13#10 + #13#10 + 'Contacts:' + #13#10 + 'VKontakte: ' +
  58.                'https://vk.com/ushouldbelieveme' + #13#10 +'E-mail: ' +
  59.                'telephonedatabasedev@gmail.com', MtInformation, [mbOk], 0);
  60. end;
  61.  
  62. procedure TStartForm.InstructionMenuClick(Sender: TObject);
  63. begin
  64.     MessageDlg('This is the start window. It includes next functions:' + #13#10 +
  65.               '1. Сhoosing a work mod;' + #13#10 + '2. Choosing a color mod;' +
  66.               #13#10 + '3. Provider cost setting.' + #13#10 + #13#10 + 'First' +
  67.               ' option includes two modes:' + #13#10 + '- Show mode: allows' +
  68.               'you just to see subscribers using searching and sorting tools.'
  69.               + #13#10 + '- Edit mode: includes 3 more functions:' + #13#10 +
  70.               'a) Adding subscribers;' + #13#10 + 'b) Editing current ' +
  71.               'subscriber''s data;' + #13#10 + 'c) Deleting subscribers;' +
  72.               #13#10 + #13#10 + 'Color mode allow you to switch between ligth' +
  73.               ' and dark themes.' + #13#10 + #13#10 + 'Setting a provider cost' +
  74.               ' will determine the way of payment calсulation:' + #13#10 +
  75.               'You enter 30-days provider cost in dollars and new payments' +
  76.               ' will be counted according to in.' + #13#10 + 'Press "ctrl + i"'
  77.               + ' to open instruction;' + #13#10 +  'Press "esc" to exit program.',
  78.               MtInformation, [mbOk], 0);
  79. end;
  80.  
  81. procedure TStartForm.EditModeButtonClick(Sender: TObject);
  82. begin
  83.     EditForm.show();
  84.     StartForm.Enabled := false;
  85.     ServiceCost := CostSpinEdit.value;
  86. end;
  87.  
  88. procedure TStartForm.FormClose(Sender: TObject; var Action: TCloseAction);
  89. begin
  90.     removeDeleters;
  91. end;
  92.  
  93. procedure TStartForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  94. begin
  95.     CanClose := false;
  96.     if MessageDlg('Are you sure if you want to exit?', mtConfirmation, mbYESNO, 0) = mrYES then
  97.     begin
  98.         CanClose := true;
  99.     end;
  100. end;
  101.  
  102. procedure TStartForm.FormCreate(Sender: TObject);
  103. begin
  104.     TStyleManager.TrySetStyle(LIGHT_SKIN);
  105.     LightRButton.Checked := true;
  106. end;
  107.  
  108. procedure TStartForm.FormKeyPress(Sender: TObject; var Key: Char);
  109. begin
  110.     if key = #27 then
  111.         StartForm.Close()
  112. end;
  113.  
  114. procedure TStartForm.LightRButtonClick(Sender: TObject);
  115. begin
  116.     TStyleManager.TrySetStyle(LIGHT_SKIN);
  117. end;
  118.  
  119. procedure TStartForm.DarkRButtonClick(Sender: TObject);
  120. begin
  121.     TStyleManager.TrySetStyle(DARK_SKIN);
  122. end;
  123.  
  124. procedure TStartForm.ShowModeButtonClick(Sender: TObject);
  125.  
  126. begin;
  127.     ServiceCost := CostSpinEdit.value;
  128.     StartForm.Enabled := false;
  129.     ShowForm.show();
  130. end;
  131.  
  132. end.
  133.  
  134.  
  135. unit EditUnit;
  136.  
  137. interface
  138.  
  139. uses
  140.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  141.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.Menus, Vcl.StdCtrls, ListUnit,
  142.   System.Actions, Vcl.ActnList, System.UITypes;
  143.  
  144. type
  145.   TEditForm = class(TForm)
  146.     SubscribersStringGrid: TStringGrid;
  147.     TelephoneEdit: TEdit;
  148.     MainMenu: TMainMenu;
  149.     AddButton: TButton;
  150.     EditButton: TButton;
  151.     DeleteButton: TButton;
  152.     InstructionMenu: TMenuItem;
  153.     TelephoneRButton: TRadioButton;
  154.     SortLabel: TLabel;
  155.     NameRButton: TRadioButton;
  156.     SurnameRButton: TRadioButton;
  157.     PatronymicRButton: TRadioButton;
  158.     CityRButton: TRadioButton;
  159.     NameLabel: TLabel;
  160.     SurnameLabel: TLabel;
  161.     NameEdit: TEdit;
  162.     SurnameEdit: TEdit;
  163.     PatronymicEdit: TEdit;
  164.     CItyEdit: TEdit;
  165.     ShowButton: TButton;
  166.     PatronymicLabel: TLabel;
  167.     CityLabel: TLabel;
  168.     TelephoneLabel: TLabel;
  169.     TaskLabel: TLabel;
  170.     ClearButton: TButton;
  171.     DateRButton: TRadioButton;
  172.     procedure FormShow(Sender: TObject);
  173.     procedure FormCreate(Sender: TObject);
  174.     procedure AddButtonClick(Sender: TObject);
  175.     procedure fillStringGrid(SubscribersStringGrid: TStringGrid; TelephoneEdit, SurnameEdit, NameEdit,
  176.                                 PatronymicEdit, CityEdit: TEdit);
  177.     procedure ShowButtonClick(Sender: TObject);
  178.     procedure clearStringGrid();
  179.     procedure DeleteButtonClick(Sender: TObject);
  180.     procedure RadioButtonCLick(Sender: TObject);
  181.     procedure ClearButtonClick(Sender: TObject);
  182.     function isCorrectTextData(CurrentEdit: TEdit): boolean;
  183.     function isCorrectNumberData(CurrentEdit: TEdit): boolean;
  184.     procedure DataEditKeyPress(Sender: TObject; var Key: Char);
  185.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  186.     procedure TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  187.     function areEditsCorrect(): boolean;
  188.     procedure EditButtonClick(Sender: TObject);
  189.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  190.     procedure InstructionMenuClick(Sender: TObject);
  191.     procedure buildStringGrid(SubscribersStringGrid: TStringGrid);
  192.     procedure setEditButtonsCondition();
  193.     procedure sortList();
  194.     procedure getRequiredSubscriber(var RequiredSubscriber: TRequiredSubscriber;
  195.                                     RequiredTelephoneNumber: string; RequiredSurname: string; RequiredName: string;
  196.                                             RequiredPatronymic: string; RequiredCity: string);
  197.   private
  198.     { Private declarations }
  199.   public
  200.     { Public declarations }
  201.   end;
  202.  
  203. var
  204.   EditForm: TEditForm;
  205.   SubscriberList: TSubscriberList;
  206.   SubscriberIndex: TNumber;
  207.  
  208. implementation
  209. {$R *.dfm}
  210.  
  211. uses
  212.     ReadUnit, WriteUnit, AddUnit, CorrectUnit, StartUnit;
  213.  
  214. const
  215.     TEXT_TOP_OFFSET = 3;
  216.     BIG_LETTERS = ['A'..'Z'];
  217.     SMALL_LETTERS = ['a'..'z'];
  218.     DIGITS = ['0'..'9'];
  219.  
  220. var
  221.     CurrentRadioButton: integer = 0;
  222.     NumberArray: array of TNumber;
  223.  
  224. procedure TEditForm.AddButtonClick(Sender: TObject);
  225. begin
  226.     AddForm.Show;
  227.     EditForm.Enabled := false;
  228. end;
  229.  
  230. procedure TEditForm.FormClose(Sender: TObject; var Action: TCloseAction);
  231. var
  232.     P: TSubscriberPointer;
  233. begin
  234.     SubscriberList.deleteList;
  235.     SubscriberList.Free;
  236.     clearStringGrid;
  237.     StartForm.enabled := true;
  238.     StartForm.show;
  239. end;
  240.  
  241. procedure TEditForm.setEditButtonsCondition();
  242. begin
  243.     if  SubscribersStringGrid.RowCount > 1 then
  244.     begin
  245.         DeleteButton.Enabled := true;
  246.         EditButton.Enabled := true;
  247.     end
  248.     else
  249.     begin
  250.         DeleteButton.Enabled := false;
  251.         EditButton.Enabled := false;
  252.     end;
  253. end;
  254.  
  255. procedure TEditForm.buildStringGrid(SubscribersStringGrid: TStringGrid);
  256. const
  257.     NUMBER_PART = 14;
  258.     TELEPHONE_PART = 7.5;
  259.     SURNAME_PART = 5.1;
  260.     NAME_PART = 6.6;
  261.     PATRONYMIC_PART = SURNAME_PART;
  262.     CITY_PART = 6.5;
  263.     DAYS_PART = 13;
  264. var
  265.     StringGridSize: integer;
  266. begin
  267.     SubscribersStringGrid.Cells[0, 0] := '  №';
  268.     SubscribersStringGrid.Cells[1, 0] := '   Telephone';
  269.     SubscribersStringGrid.Cells[2, 0] := '       Surname';
  270.     SubscribersStringGrid.Cells[3, 0] := '        Name';
  271.     SubscribersStringGrid.Cells[4, 0] := '       Patronymic';
  272.     SubscribersStringGrid.Cells[5, 0] := '           City';
  273.     SubscribersStringGrid.Cells[6, 0] := 'Days left';
  274.     StringGridSize := SubscribersStringGrid.width;
  275.     SubscribersStringGrid.ColWidths[0] := Round(StringGridSize / NUMBER_PART);
  276.     SubscribersStringGrid.ColWidths[1] := Round(StringGridSize / TELEPHONE_PART);
  277.     SubscribersStringGrid.ColWidths[2] := Round(StringGridSize / SURNAME_PART);
  278.     SubscribersStringGrid.ColWidths[3] := Round(StringGridSize / NAME_PART);
  279.     SubscribersStringGrid.ColWidths[4] := Round(StringGridSize / PATRONYMIC_PART);
  280.     SubscribersStringGrid.ColWidths[5] := Round(StringGridSize / CITY_PART);
  281.     SubscribersStringGrid.ColWidths[6] := Round(StringGridSize / DAYS_PART);
  282. end;
  283.  
  284. procedure TEditForm.FormCreate(Sender: TObject);
  285. begin
  286.     buildStringGrid(SubscribersStringGrid);
  287. end;
  288.  
  289. procedure TEditForm.FormKeyPress(Sender: TObject; var Key: Char);
  290. begin
  291.     if key = #27 then
  292.         EditForm.Close()
  293.     else
  294.         if Key = #13 then
  295.             ShowButtonClick(Sender);
  296. end;
  297.  
  298. procedure TEditForm.FormShow(Sender: TObject);
  299. begin
  300.     SubscriberList := TSubscriberList.NewSubscriberList();
  301.     EditButton.Enabled := false;
  302.     DeleteButton.Enabled := false;
  303.     clearStringGrid;
  304. end;
  305.  
  306. procedure TEditForm.InstructionMenuClick(Sender: TObject);
  307. begin
  308.     MessageDlg('This is the edit window. It includes next functions:' + #13#10 + '1. Searching by certain data;' + #13#10
  309.                             + '2. Sorting by all categories;' + #13#10 +
  310.                             '3. Adding new subscriber;' + #13#10 + '4. Edtining selected one;' +  #13#10 +
  311.                             '5. Deleting selected one.' + #13#10 + #13#10 +
  312.                             'Right input:' + #13#10 +
  313.                             'a) Telephone number field: first char - "+" or digit and next are digits; length = 13;'
  314.                             + #13#10 + 'b) Text fields: first char - big letter and next are small letters. Length:'
  315.                             + #13#10 + 'City -11, Surname - 14, Name - 11, Patronymic - 14.' + #13#10
  316.                             + #13#10 + 'Use "clear" to clear all fields and turn sort off;'
  317.                             + #13#10 + #13#10 + 'Press "ctrl + i" to open instruction;'
  318.                             + #13#10 + 'Press "enter" to show subscribers;'
  319.                             + #13#10 + 'Press "esc" to go back to start widnow.', MtInformation, [mbOk], 0);
  320. end;
  321.  
  322. procedure TEditForm.ShowButtonClick(Sender: TObject);
  323. begin
  324.     if areEditsCorrect() then
  325.     begin
  326.         clearStringGrid();
  327.         if not isFileEmpty() then
  328.         begin
  329.             fillStringGrid(SubscribersStringGrid, TelephoneEdit, SurnameEdit, NameEdit,
  330.                             PatronymicEdit, CityEdit);
  331.             setEditButtonsCondition();
  332.         end
  333.         else
  334.             MessageDlg('Subscriber file is empty.', mtError, [mbOk], 0, mbOk);
  335.     end
  336.     else
  337.     begin
  338.         MessageDlg('Wrong data.', mtError, [mbCancel], 0);
  339.         clearButtonClick(Sender);
  340.     end;
  341. end;
  342.  
  343. function TEditForm.areEditsCorrect(): boolean;
  344. begin
  345.     Result := (IsCorrectNumberData(TelephoneEdit) and IsCorrectTextData(SurnameEdit) and
  346.                IsCorrectTextData(NameEdit) and IsCorrectTextData(PatronymicEdit) and
  347.                IsCorrectTextData(CityEdit));
  348. end;
  349.  
  350. procedure TEditForm.DataEditKeyPress(Sender: TObject; var Key: Char);
  351. begin
  352.     if (Key <> #08) then
  353.     begin
  354.         if length((Sender as TEdit).text) = 0 then
  355.         begin
  356.             if not (Key in BIG_LETTERS) then
  357.                 Key := #0
  358.         end
  359.         else
  360.             if not(Key in SMALL_LETTERS) then
  361.                 Key := #0;
  362.     end;
  363. end;
  364.  
  365. procedure TEditForm.TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  366. begin
  367.     if (Key <> #08) then
  368.     begin
  369.         if length((Sender as TEdit).text) = 0 then
  370.         begin
  371.             if ((not(Key in DIGITS)) and (Key <> '+')) then
  372.                 Key := #0
  373.         end
  374.         else
  375.             if not(Key in DIGITS) then
  376.                 Key := #0;
  377.     end;
  378. end;
  379.  
  380. procedure TEditForm.RadioButtonCLick(Sender: TObject);
  381. begin
  382.     CurrentRadioButton := (Sender as TRadioButton).tag;
  383. end;
  384.  
  385. procedure TEditForm.ClearButtonClick(Sender: TObject);
  386. begin
  387.     TelephoneEdit.text := '';
  388.     NameEdit.text := '';
  389.     SurnameEdit.text := '';
  390.     PatronymicEdit.text := '';
  391.     CityEdit.text := '';
  392.     TelephoneRButton.Checked := false;
  393.     SurnameRButton.Checked := false;
  394.     NameRButton.Checked := false;
  395.     PatronymicRButton.Checked := false;
  396.     CityRButton.Checked := false;
  397.     DateRButton.Checked := false;
  398.     CurrentRadioButton := 0;
  399.     SubscribersStringGrid.RowCount := 1;
  400.     EditButton.Enabled := false;
  401.     DeleteButton.Enabled := false;
  402. end;
  403.  
  404.  
  405. procedure TEditForm.sortList();
  406. begin
  407.     if not SubscriberList.IsEmpty then
  408.         case CurrentRadioButton of
  409.             0: ;
  410.             1: SubscriberList.sort(TSubscriberList.compareByTelephoneNumber);
  411.             2: SubscriberList.sort(TSubscriberList.CompareBySurname);
  412.             3: SubscriberList.sort(TSubscriberList.CompareByName);
  413.             4: SubscriberList.sort(TSubscriberList.CompareByPatronymic);
  414.             5: SubscriberList.sort(TSubscriberList.CompareByCity);
  415.             6: SubscriberList.sort(TSubscriberList.CompareByDate);
  416.         end;
  417. end;
  418.  
  419. procedure TEditForm.fillStringGrid(SubscribersStringGrid: TStringGrid;
  420.                             TelephoneEdit, SurnameEdit, NameEdit,
  421.                                 PatronymicEdit, CityEdit: TEdit);
  422. var
  423.     i, j, ListLength: Integer;
  424.     PCurrentSubscriber: TSubscriberPointer;
  425.     RequiredSubscriber: TRequiredSubscriber;
  426. begin
  427.     i := 1;
  428.     j := 0;
  429.     SubscriberList.deleteList();
  430.     getRequiredSubscriber(RequiredSubscriber, TelephoneEdit.text, SurnameEdit.text, NameEdit.text,
  431.                                 PatronymicEdit.text, CityEdit.text);
  432.     readSubscribers(RequiredSubscriber);
  433.     sortList();
  434.     ListLength := SubscriberList.length();
  435.     setlength(NumberArray, ListLength);
  436.     PCurrentSubscriber := SubscriberList.getHeader()^.next;
  437.     while (PCurrentSubscriber <> nil) do
  438.     begin
  439.         SubscribersStringGrid.RowCount := SubscribersStringGrid.RowCount + 1;
  440.         SubscribersStringGrid.Cells[0, i] := intToStr(i);
  441.         SubscribersStringGrid.Cells[1, i] := PCurrentSubscriber^.telephoneNumber;
  442.         SubscribersStringGrid.Cells[2, i] := PCurrentSubscriber^.surname;
  443.         SubscribersStringGrid.Cells[3, i] := PCurrentSubscriber^.name;
  444.         SubscribersStringGrid.Cells[4, i] := PCurrentSubscriber^.patronymic;
  445.         SubscribersStringGrid.Cells[5, i] := PCurrentSubscriber^.city;
  446.         SubscribersStringGrid.Cells[6, i] := intToStr(PCurrentSubscriber^.numberOfDays);
  447.         NumberArray[j] := PCurrentSubscriber^.number;
  448.         Inc(i);
  449.         inc(j);
  450.         PCurrentSubscriber := PCurrentSubscriber^.next;
  451.     end;
  452. end;
  453.  
  454. procedure TEditForm.getRequiredSubscriber(var RequiredSubscriber: TRequiredSubscriber; RequiredTelephoneNumber: string; RequiredSurname: string;
  455.                                             RequiredName: string; RequiredPatronymic: string;
  456.                                             RequiredCity: string);
  457. begin
  458.     RequiredSubscriber.telephoneNumber := RequiredTelephoneNumber;
  459.     RequiredSubscriber.surname := RequiredSurname;
  460.     RequiredSubscriber.name := RequiredName;
  461.     RequiredSubscriber.patronymic := RequiredPatronymic;
  462.     RequiredSubscriber.city := RequiredCity;
  463. end;
  464.  
  465. procedure TEditForm.clearStringGrid();
  466. begin
  467.     SubscribersStringGrid.RowCount := 1;
  468.     SubscribersStringGrid.ColCount := 7;
  469. end;
  470.  
  471. procedure TEditForm.DeleteButtonClick(Sender: TObject);
  472. var
  473.     SubscriberNumber: integer;
  474. begin
  475.     if (SubscribersStringGrid.Row <> 0) then
  476.     begin
  477.         SubscriberNumber := NumberArray[SubscribersStringGrid.Row - 1];
  478.         deleteSubscriber(SubscriberNumber);
  479.         ShowButtonClick(Sender);
  480.     end;
  481. end;
  482.  
  483. procedure TEditForm.EditButtonClick(Sender: TObject);
  484. begin
  485.     if (SubscribersStringGrid.Row <> 0) then
  486.     begin
  487.         SubscriberIndex := NumberArray[SubscribersStringGrid.Row - 1];
  488.         EditForm.Enabled := false;
  489.         CorrectForm.Show;
  490.     end;
  491. end;
  492.  
  493. function TEditForm.IsCorrectTextData(CurrentEdit: TEdit): boolean;
  494. var
  495.     IsCorrectInput: boolean;
  496.     TextLength, i: integer;
  497. begin
  498.     isCorrectInput := false;
  499.     TextLength := length(CurrentEdit.text);
  500.     i := 2;
  501.     if TextLength <= CurrentEdit.MaxLength then
  502.     begin
  503.         if TextLength = 0 then
  504.             IsCorrectInput := true
  505.         else
  506.         begin
  507.             if (TextLength = 1) and (CurrentEdit.text[1] in BIG_LETTERS) then
  508.                 IsCorrectInput := True
  509.             else
  510.             begin
  511.                 IsCorrectInput := CurrentEdit.text[1] in BIG_LETTERS;
  512.                 while IsCorrectInput and (i <= TextLength) do
  513.                 begin
  514.                     if not(CurrentEdit.text[i] in SMALL_LETTERS) then
  515.                         IsCorrectInput := false;
  516.                     inc(i);
  517.                 end;
  518.             end;
  519.         end;
  520.     end;
  521.     Result := IsCorrectInput;
  522. end;
  523.  
  524. function TEditForm.isCorrectNumberData(CurrentEdit: TEdit): boolean;
  525.  
  526. var
  527.     IsCorrectInput: boolean;
  528.     TextLength, i: integer;
  529.  
  530. begin
  531.     isCorrectInput := false;
  532.     TextLength := length(CurrentEdit.text);
  533.     i := 2;
  534.     if TextLength <= CurrentEdit.MaxLength then
  535.     begin
  536.         if TextLength = 0 then
  537.             IsCorrectInput := true
  538.         else
  539.         begin
  540.             if (TextLength = 1) and ((CurrentEdit.text[1] in DIGITS) or (CurrentEdit.text[1] = '+')) then
  541.                 isCorrectInput := true
  542.             else
  543.             begin
  544.                 IsCorrectInput := (CurrentEdit.text[1] in DIGITS) or (CurrentEdit.text[1] = '+');
  545.                 while isCorrectInput and (i <= TextLength) do
  546.                 begin
  547.                     if not (CurrentEdit.text[i] in DIGITS) then
  548.                         IsCorrectInput := false;
  549.                     inc(i);
  550.                 end;
  551.             end;
  552.         end;
  553.     end;
  554.     Result := IsCorrectInput;
  555. end;
  556.  
  557. end.
  558.  
  559.  
  560. unit ShowUnit;
  561.  
  562. interface
  563.  
  564. uses
  565.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  566.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.Menus, Vcl.StdCtrls, ListUnit,
  567.   System.Actions, Vcl.ActnList, System.UITypes, EditUnit;
  568.  
  569. type
  570.   TShowForm = class(TForm)
  571.     SubscribersStringGrid: TStringGrid;
  572.     TelephoneEdit: TEdit;
  573.     MainMenu: TMainMenu;
  574.     InstructionMenu: TMenuItem;
  575.     TelephoneRButton: TRadioButton;
  576.     SortLabel: TLabel;
  577.     NameRButton: TRadioButton;
  578.     SurnameRButton: TRadioButton;
  579.     PatronymicRButton: TRadioButton;
  580.     CityRButton: TRadioButton;
  581.     NameLabel: TLabel;
  582.     SurnameLabel: TLabel;
  583.     NameEdit: TEdit;
  584.     SurnameEdit: TEdit;
  585.     PatronymicEdit: TEdit;
  586.     CItyEdit: TEdit;
  587.     ShowButton: TButton;
  588.     PatronymicLabel: TLabel;
  589.     CityLabel: TLabel;
  590.     TelephoneLabel: TLabel;
  591.     TaskLabel: TLabel;
  592.     ClearButton: TButton;
  593.     DateRButton: TRadioButton;
  594.     procedure FormShow(Sender: TObject);
  595.     procedure FormCreate(Sender: TObject);
  596.     procedure AddButtonClick(Sender: TObject);
  597.     procedure fillStringGrid();
  598.     procedure ShowButtonClick(Sender: TObject);
  599.     procedure clearStringGrid();
  600.     procedure RadioButtonCLick(Sender: TObject);
  601.     procedure ClearButtonClick(Sender: TObject);
  602.     procedure TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  603.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  604.     procedure TextEditKeyPress(Sender: TObject; var Key: Char);
  605.     function areEditsCorrect(): boolean;
  606.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  607.     procedure InstructionMenuClick(Sender: TObject);
  608.   private
  609.     { Private declarations }
  610.   public
  611.     { Public declarations }
  612.   end;
  613.  
  614.  
  615. var
  616.   ShowForm: TShowForm;
  617.  
  618. implementation
  619. {$R *.dfm}
  620.  
  621. uses
  622.     ReadUnit, WriteUnit, AddUnit, CorrectUnit, StartUnit;
  623.  
  624. const
  625.     TEXT_TOP_OFFSET = 3;
  626.     BIG_LETTERS = ['A'..'Z'];
  627.     SMALL_LETTERS = ['a'..'z'];
  628.     DIGITS = ['0'..'9'];
  629.  
  630. var
  631.     CurrentRadioButton: integer = 0;
  632.  
  633. procedure TShowForm.AddButtonClick(Sender: TObject);
  634. begin
  635.     AddForm.Show;
  636.     ShowForm.Enabled := false;
  637. end;
  638.  
  639. procedure TShowForm.FormClose(Sender: TObject; var Action: TCloseAction);
  640. begin
  641.     SubscriberList.deleteList;
  642.     SubscriberList.Free;
  643.     clearStringGrid;
  644.     StartForm.enabled := true;
  645.     StartForm.show;
  646. end;
  647.  
  648. procedure TShowForm.FormCreate(Sender: TObject);
  649. begin
  650.     EditForm.buildStringGrid(SubscribersStringGrid);
  651. end;
  652.  
  653. procedure TShowForm.FormKeyPress(Sender: TObject; var Key: Char);
  654. begin
  655.     if key = #27 then
  656.         ShowForm.Close()
  657.     else
  658.         if Key = #13 then
  659.             ShowButtonClick(Sender);
  660. end;
  661.  
  662. procedure TShowForm.FormShow(Sender: TObject);
  663. begin
  664.     SubscriberList := TSubscriberList.NewSubscriberList();
  665.     clearStringGrid();
  666. end;
  667.  
  668. procedure TShowForm.ShowButtonClick(Sender: TObject);
  669. begin
  670.     if areEditsCorrect() then
  671.     begin
  672.         clearStringGrid();
  673.         if not isFileEmpty() then
  674.             fillStringGrid()
  675.         else
  676.             MessageDlg('Subscriber file is empty.', mtError, [mbOk], 0, mbOk);
  677.     end
  678.     else
  679.     begin
  680.         MessageDlg('Wrong data.', mtError, [mbCancel], 0);
  681.         clearButtonClick(Sender);
  682.     end;
  683. end;
  684.  
  685. function TShowForm.areEditsCorrect(): boolean;
  686. begin
  687.     Result := (EditForm.IsCorrectNumberData(TelephoneEdit) and EditForm.IsCorrectTextData(SurnameEdit) and
  688.                EditForm.IsCorrectTextData(NameEdit) and EditForm.IsCorrectTextData(PatronymicEdit) and
  689.                EditForm.IsCorrectTextData(CityEdit));
  690. end;
  691.  
  692. procedure TShowForm.TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  693. begin
  694.     EditForm.TelephoneEditKeyPress(Sender, Key);
  695. end;
  696.  
  697. procedure TShowForm.TextEditKeyPress(Sender: TObject; var Key: Char);
  698. begin
  699.     EditForm.DataEditKeyPress(Sender, Key);
  700. end;
  701.  
  702. procedure TShowForm.RadioButtonCLick(Sender: TObject);
  703. begin
  704.     EditForm.RadioButtonCLick(Sender);
  705. end;
  706.  
  707. procedure TShowForm.ClearButtonClick(Sender: TObject);
  708. begin
  709.     TelephoneEdit.text := '';
  710.     NameEdit.text := '';
  711.     SurnameEdit.text := '';
  712.     PatronymicEdit.text := '';
  713.     CityEdit.text := '';
  714.     TelephoneRButton.Checked := false;
  715.     SurnameRButton.Checked := false;
  716.     NameRButton.Checked := false;
  717.     PatronymicRButton.Checked := false;
  718.     CityRButton.Checked := false;
  719.     DateRButton.Checked := false;
  720.     CurrentRadioButton := 0;
  721.     SubscribersStringGrid.RowCount := 1;
  722. end;
  723.  
  724. procedure sortList();
  725. begin
  726.     EditForm.sortList;
  727. end;
  728.  
  729. procedure TShowForm.fillStringGrid();
  730. begin
  731.     EditForm.fillStringGrid(SubscribersStringGrid, TelephoneEdit, SurnameEdit, NameEdit,
  732.                                 PatronymicEdit, CityEdit);
  733. end;
  734.  
  735. procedure TShowForm.clearStringGrid();
  736. begin
  737.     SubscribersStringGrid.RowCount := 1;
  738.     SubscribersStringGrid.ColCount := 7;
  739. end;
  740.  
  741. end.
  742.  
  743.  
  744. unit AddUnit;
  745.  
  746. interface
  747.  
  748. uses
  749.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  750.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.Samples.Spin, EditUnit;
  751.  
  752. type
  753.   TAddForm = class(TForm)
  754.     NameLabel: TLabel;
  755.     SurnameLabel: TLabel;
  756.     PatronymicLabel: TLabel;
  757.     CityLabel: TLabel;
  758.     DateLabel: TLabel;
  759.     TelephoneLabel: TLabel;
  760.     TelephoneEdit: TEdit;
  761.     NameEdit: TEdit;
  762.     SurnameEdit: TEdit;
  763.     PatronymicEdit: TEdit;
  764.     CItyEdit: TEdit;
  765.     TaskLabel: TLabel;
  766.     AddButton: TButton;
  767.     MainMenu: TMainMenu;
  768.     InstructionMenu: TMenuItem;
  769.     SubscriberAddedLabel: TLabel;
  770.     PaymentEdit: TSpinEdit;
  771.     WrongDataLabel: TLabel;
  772.     SubscriberExistsLabel: TLabel;
  773.     procedure AddButtonClick(Sender: TObject);
  774.     procedure SomeEditChange(Sender: TObject);
  775.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  776.     procedure turnLabelsOff();
  777.     procedure InstructionMenuClick(Sender: TObject);
  778.     procedure TextEditKeyPress(Sender: TObject; var Key: Char);
  779.     procedure TelephoneKeyPress(Sender: TObject; var Key: Char);
  780.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  781.     procedure FormShow(Sender: TObject);
  782.     function areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, FathernameEdit, CityEdit: TEdit): boolean;
  783.     function areEditsCorrect(): boolean;
  784.   private
  785.     { Private declarations }
  786.   public
  787.     { Public declarations }
  788.   end;
  789.  
  790. var
  791.   AddForm: TAddForm;
  792.  
  793. implementation
  794.  
  795. {$R *.dfm}
  796.  
  797. uses
  798.     ReadUnit, WriteUnit, ListUnit, StartUnit;
  799.  
  800. const
  801.     BIG_LETTERS = ['A'..'Z'];
  802.     SMALL_LETTERS = ['a'..'z'];
  803.     DIGITS = ['0'..'9'];
  804.  
  805. procedure TAddForm.AddButtonClick(Sender: TObject);
  806. var
  807.     TelephoneNumber: TTelephoneNumber;
  808.     Surname: TSurname;
  809.     Name: TName;
  810.     Patronymic: TPatronymic;
  811.     City: TCity;
  812.     DateOfPay: TDateOfPay;
  813.     SameSubscriberIndex: integer;
  814.     RequiredSubscriber: TRequiredSubscriber;
  815. begin
  816.     TelephoneNumber := toTelephoneNumber(TelephoneEdit.text);
  817.     Surname := toSurname(SurnameEdit.Text);
  818.     Name := toName(NameEdit.Text);
  819.     Patronymic := toPatronymic(PatronymicEdit.Text);
  820.     City := toCity(CityEdit.Text);
  821.     DateOfPay := toDateOfPay(Now, PaymentEdit.value);
  822.     TurnLabelsOff();
  823.     EditForm.getRequiredSubscriber(RequiredSubscriber,  TelephoneEdit.text, SurnameEdit.text, NameEdit.text,
  824.                                 PatronymicEdit.text, CityEdit.text);
  825.     if isExist(RequiredSubscriber, SameSubscriberIndex) then
  826.         SubscriberExistsLabel.Visible := true
  827.     else
  828.     begin
  829.         if not areEditsCorrect() then
  830.             WrongDataLabel.Visible := true
  831.         else
  832.         begin
  833.             write(TelephoneNumber, Surname, Name, Patronymic, City, DateofPay);
  834.             SubscriberAddedLabel.Visible := true;
  835.         end;
  836.     end;
  837. end;
  838.  
  839. function TAddForm.areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, FathernameEdit, CityEdit: TEdit): boolean;
  840.  
  841. begin
  842.     Result := ((TelephoneEdit.text <> '') and (SurnameEdit.text <> '') and (FathernameEdit.text <> '')
  843.                 and (NameEdit.text <> '') and (CityEdit.text <> ''));
  844. end;
  845.  
  846. function TAddForm.areEditsCorrect(): boolean;
  847.  
  848. begin
  849.     Result := (EditForm.IsCorrectNumberData(TelephoneEdit) and EditForm.IsCorrectTextData(SurnameEdit) and
  850.                EditForm.IsCorrectTextData(NameEdit) and EditForm.IsCorrectTextData(PatronymicEdit) and
  851.                EditForm.IsCorrectTextData(CityEdit) and
  852.                areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, PatronymicEdit, CityEdit));
  853. end;
  854.  
  855. procedure TAddForm.FormClose(Sender: TObject; var Action: TCloseAction);
  856. var
  857.     Edit: TEdit;
  858. begin
  859.     EditForm.enabled := true;
  860.     TurnLabelsOff();
  861.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  862.         Edit.text := '';
  863.     PaymentEdit.value := 0;
  864. end;
  865.  
  866. procedure TAddForm.FormKeyPress(Sender: TObject; var Key: Char);
  867. begin
  868.     if key = #27 then
  869.         AddForm.Close()
  870.     else
  871.         if Key = #13 then
  872.             AddButtonClick(Sender);
  873. end;
  874.  
  875. procedure TAddForm.FormShow(Sender: TObject);
  876. var
  877.     Edit: TEdit;
  878. begin
  879.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  880.         Edit.text := '';
  881. end;
  882.  
  883. procedure TAddForm.SomeEditChange(Sender: TObject);
  884. begin
  885.     turnLabelsOff();
  886. end;
  887.  
  888. procedure TAddForm.TextEditKeyPress(Sender: TObject; var Key: Char);
  889. begin
  890.     if (Key <> #08) then
  891.     begin
  892.         if length((Sender as TEdit).text) = 0 then
  893.         begin
  894.             if not (Key in BIG_LETTERS) then
  895.                 Key := #0
  896.         end
  897.         else if not(Key in SMALL_LETTERS) then
  898.             Key := #0;
  899.     end;
  900. end;
  901.  
  902. procedure TAddForm.TelephoneKeyPress(Sender: TObject; var Key: Char);
  903. begin
  904.     if (Key <> #08) then
  905.     begin
  906.         if length((Sender as TEdit).text) = 0 then
  907.         begin
  908.             if ((not(Key in DIGITS)) and (Key <> '+')) then
  909.                 Key := #0
  910.         end
  911.         else if not(Key in DIGITS) then
  912.             Key := #0;
  913.     end;
  914. end;
  915.  
  916. procedure TAddForm.TurnLabelsOff();
  917. begin
  918.     SubscriberAddedLabel.Visible := false;
  919.     SubscriberExistsLabel.Visible := false;
  920.     WrongDataLabel.Visible := false;
  921. end;
  922.  
  923. end.
  924.  
  925.  
  926. unit CorrectUnit;
  927.  
  928. interface
  929.  
  930. uses
  931.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  932.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.Samples.Spin, DateUtils, AddUnit, EditUnit;
  933.  
  934. type
  935.   TCorrectForm = class(TForm)
  936.     NameLabel: TLabel;
  937.     SurnameLabel: TLabel;
  938.     PatronumicLabel: TLabel;
  939.     CityLabel: TLabel;
  940.     TelephoneLabel: TLabel;
  941.     TelephoneEdit: TEdit;
  942.     NameEdit: TEdit;
  943.     SurnameEdit: TEdit;
  944.     PatronymicEdit: TEdit;
  945.     CItyEdit: TEdit;
  946.     TaskLabel: TLabel;
  947.     SaveButton: TButton;
  948.     MainMenu: TMainMenu;
  949.     InstructionMenu: TMenuItem;
  950.     PayLabel: TLabel;
  951.     ResetButton: TButton;
  952.     DateLabel: TLabel;
  953.     DateOfPayLabel: TLabel;
  954.     PaySpinEdit: TSpinEdit;
  955.     SuccessLabel: TLabel;
  956.     WrongDataLabel: TLabel;
  957.     UpdateMenu: TMenuItem;
  958.     SubscriberExistsLabel: TLabel;
  959.     procedure ResetButtonClick(Sender: TObject);
  960.     procedure TurnLabelsOff();
  961.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  962.     procedure FormShow(Sender: TObject);
  963.     procedure SaveButtonClick(Sender: TObject);
  964.     procedure showSavedInfo();
  965.     procedure UpdateMenuClick(Sender: TObject);
  966.     procedure deleteSpaces();
  967.     procedure InstructionMenuClick(Sender: TObject);
  968.     procedure TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  969.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  970.     procedure TextEditKeyPress(Sender: TObject; var Key: Char);
  971.     function areEditsCorrect(): boolean;
  972.     procedure SomeEditChange(Sender: TObject);
  973.   private
  974.     { Private declarations }
  975.   public
  976.     { Public declarations }
  977.   end;
  978.  
  979. var
  980.   CorrectForm: TCorrectForm;
  981.  
  982. implementation
  983.  
  984. {$R *.dfm}
  985.  
  986. uses
  987.     ReadUnit, WriteUnit, ListUnit;
  988.  
  989.  
  990. procedure TCorrectForm.ResetButtonClick(Sender: TObject);
  991. begin
  992.     DateOfPayLabel.caption := dateToStr(Now);
  993.     PaySpinEdit.Value := 0;
  994.     turnLabelsOff();
  995. end;
  996.  
  997. function TCorrectForm.areEditsCorrect(): boolean;
  998.  
  999. begin
  1000.     Result := (EditForm.IsCorrectNumberData(TelephoneEdit) and EditForm.IsCorrectTextData(SurnameEdit) and
  1001.                EditForm.IsCorrectTextData(NameEdit) and EditForm.IsCorrectTextData(PatronymicEdit) and
  1002.                EditForm.IsCorrectTextData(CityEdit) and
  1003.                AddForm.areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, PatronymicEdit, CityEdit));
  1004. end;
  1005.  
  1006. procedure TCorrectForm.SaveButtonClick(Sender: TObject);
  1007. var
  1008.     TelephoneNumber: TTelephoneNumber;
  1009.     Surname: TSurname;
  1010.     Name: TName;
  1011.     Patronymic: TPatronymic;
  1012.     City: TCity;
  1013.     DateofPay: TDateOfPay;
  1014.     SameSubscriberIndex: integer;
  1015.     RequiredSubscriber: TRequiredSubscriber;
  1016. begin
  1017.     SameSubscriberIndex := -1;
  1018.     TelephoneNumber := toTelephoneNumber(TelephoneEdit.text);
  1019.     Surname := toSurname(SurnameEdit.Text);
  1020.     Name := toName(NameEdit.Text);
  1021.     Patronymic := toPatronymic(PatronymicEdit.Text);
  1022.     City := toCity(CityEdit.Text);
  1023.     DateOfPay := toDateOfPay(strToDate(DateOfPayLabel.Caption), PaySpinEdit.Value);
  1024.     PaySpinEdit.Value := 0;
  1025.     EditForm.getRequiredSubscriber(RequiredSubscriber,  TelephoneEdit.text, SurnameEdit.text, NameEdit.text,
  1026.                                 PatronymicEdit.text, CityEdit.text);
  1027.     if isExist(RequiredSubscriber, SameSubscriberIndex)
  1028.         and (not(SubscriberIndex = SameSubscriberIndex)) then
  1029.         SubscriberExistsLabel.Visible := true
  1030.     else
  1031.     begin
  1032.         if (not areEditsCorrect()) then
  1033.             WrongDataLabel.Visible := true
  1034.         else
  1035.         begin
  1036.             write(SubscriberIndex, TelephoneNumber, Surname, Name, Patronymic, City,
  1037.                   DateofPay);
  1038.             showSavedInfo();
  1039.             SuccessLabel.Visible := true;
  1040.         end;
  1041.     end;
  1042. end;
  1043.  
  1044. procedure TCorrectForm.FormClose(Sender: TObject; var Action: TCloseAction);
  1045. begin
  1046.     EditForm.enabled := true;
  1047.     PaySpinEdit.value := 0;
  1048. end;
  1049.  
  1050. procedure TCorrectForm.FormKeyPress(Sender: TObject; var Key: Char);
  1051. begin
  1052.     if key = #27 then
  1053.         AddForm.Close()
  1054.     else
  1055.         if Key = #13 then
  1056.             SaveButtonClick(Sender);
  1057. end;
  1058.  
  1059. procedure TCorrectForm.FormShow(Sender: TObject);
  1060. begin
  1061.     showSavedInfo();
  1062. end;
  1063.  
  1064. procedure TCorrectForm.deleteSpaces();
  1065. var
  1066.     Edit: TEdit;
  1067.     i: integer;
  1068.     BufferString: string;
  1069. begin
  1070.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  1071.     begin
  1072.         BufferString := Edit.text;
  1073.         Edit.text := '';
  1074.         for i := 1 to length(BufferString) do
  1075.             if BufferString[i] <> ' ' then
  1076.                 Edit.text := Edit.text + BufferString[i];
  1077.     end;
  1078. end;
  1079.  
  1080. procedure TCorrectForm.showSavedInfo();
  1081. var
  1082.     CurrentSubscriber: TSubscriber;
  1083.     DateString: string;
  1084. begin
  1085.     CurrentSubscriber := getSubscriber(SubscriberIndex, DateString);
  1086.     TelephoneEdit.text := CurrentSubscriber.telephoneNumber;
  1087.     SurnameEdit.text := CurrentSubscriber.surname;
  1088.     NameEdit.text := CurrentSubscriber.name;
  1089.     PatronymicEdit.text := CurrentSubscriber.patronymic;
  1090.     CityEdit.text := CurrentSubscriber.city;
  1091.     deleteSpaces;
  1092.     DateOfPayLabel.caption := DateString;
  1093.     PaySpinEdit.Value := 0;
  1094.     turnLabelsOff();
  1095. end;
  1096.  
  1097. procedure TCorrectForm.TextEditKeyPress(Sender: TObject; var Key: Char);
  1098. begin
  1099.     AddForm.TextEditKeyPress(Sender, Key);
  1100. end;
  1101.  
  1102. procedure TCorrectForm.SomeEditChange(Sender: TObject);
  1103. begin
  1104.     turnLabelsOff();
  1105. end;
  1106.  
  1107. procedure TCorrectForm.TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  1108. begin
  1109.     AddForm.TelephoneKeyPress(Sender, Key);
  1110. end;
  1111.  
  1112. procedure TCorrectForm.TurnLabelsOff();
  1113. begin
  1114.     SuccessLabel.visible := false;
  1115.     WrongDataLabel.visible := false;
  1116.     SubscriberExistsLabel.visible := false;
  1117. end;
  1118.  
  1119. procedure TCorrectForm.UpdateMenuClick(Sender: TObject);
  1120. begin
  1121.     showSavedInfo();
  1122. end;
  1123.  
  1124. end.
  1125.  
  1126.  
  1127. unit ReadUnit;
  1128.  
  1129. interface
  1130.  
  1131. uses
  1132.     System.SysUtils, ListUnit, EditUnit, DateUtils;
  1133.  
  1134. const
  1135.     PathToFile = 'C:\t\SubscribersFile.bin';
  1136.     FILE_NAME = 'SubscribersFile.bin';
  1137.     DELETER: ansichar = '/';
  1138.     START_SUBSCRIBER_OFFSET: LongWord = 0;
  1139.  
  1140. type
  1141.     TBinaryFile = file of byte;
  1142.  
  1143.     procedure readSubscribers(var RequiredSubscriber: TRequiredSubscriber);
  1144.     function getSubscriber(Index: longWord; var DateString: string): TSubscriber;
  1145.     function isEqual(var RequiredString: string; var CurrentArray: array of AnsiChar): boolean;
  1146.     function isExist(var RequiredSubscriber: TRequiredSubscriber; var SameSubscriberIndex: integer): Boolean;
  1147.     function isFileEmpty(): Boolean;
  1148.     function dateArrayToString(var DateOfPayArray: TDateOfPay): string;
  1149.     function dateToNumber(var DateOfPayArray: TDateOfPay): TNumberOfdays;
  1150.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1151.                                       var TelephoneNumberArray: TTelephoneNumber): boolean; overload;
  1152.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1153.                                       var SurnameArray: TSurname): boolean; overload;
  1154.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1155.                                       var NameArray: TName): boolean; overload;
  1156.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1157.                                       var FathernameArray: TPatronymic): boolean; overload;
  1158.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1159.                                       var CityArray: TCity): boolean; overload;
  1160.     function isRequiredSubscriber(var SourceFile: TBinaryFile; var TelephoneNumberArray: TTelephoneNumber;
  1161.                                 var SurnameArray: TSurname; var NameArray: TName;
  1162.                                   var PatromynicArray: TPatronymic; var CityArray: TCity;
  1163.                                   var RequiredSubscriber: TRequiredSubscriber): boolean;
  1164.  
  1165. implementation
  1166.  
  1167. function dateArrayToString(var DateOfPayArray: TDateOfPay): string;
  1168. begin
  1169.     Result := copy(DateOfPayArray, 1, 2) + '.' + copy(DateOfPayArray, 3, 2) + '.' + copy(DateOfPayArray, 5, 4);
  1170. end;
  1171.  
  1172. function dateToNumber(var DateOfPayArray: TDateOfPay): TNumberOfdays;
  1173. var
  1174.     NumberOfDaysLeft: integer;
  1175.     WritenTime, NowTime: TDateTime;
  1176.     StringTime: string;
  1177.     Difference: TNumberOfDays;
  1178.     DayDifferece: TNumberOfDays;
  1179.     ComparisonResult: integer;
  1180. begin
  1181.     StringTime := dateArrayToString(DateOfPayArray);
  1182.     WritenTime := strToDate(StringTime);
  1183.     NowTime := Now();
  1184.     ComparisonResult := compareDate(WritenTime, NowTime);
  1185.     DayDifferece := daysBetween(WritenTime, NowTime);
  1186.     Difference := DayDifferece * ComparisonResult;
  1187.     Result := Difference;
  1188. end;
  1189.  
  1190. procedure readSubscribers(var RequiredSubscriber: TRequiredSubscriber);
  1191. var
  1192.     SourceFile: TBinaryFile;
  1193.     TelephoneNumberArray: TTelephoneNumber;
  1194.     SurnameArray: TSurname;
  1195.     NameArray: TName;
  1196.     PatromynicArray: TPatronymic;
  1197.     CityArray: TCity;
  1198.     DateofPayArray: TDateOfPay;
  1199.     Number: TNumber;
  1200.     Offset: integer;
  1201.     OneByte: ansichar;
  1202.     NumberOfDays: longWord;
  1203. begin
  1204.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1205.     reset(SourceFile);
  1206.     Offset := START_SUBSCRIBER_OFFSET;
  1207.     Seek(SourceFile, Offset);
  1208.     while not EOF(SourceFile) do
  1209.     begin
  1210.         blockRead(SourceFile, OneByte, 1);
  1211.         if OneByte <> DELETER then
  1212.         begin
  1213.             Seek(SourceFile, Offset);
  1214.             blockRead(SourceFile, Number, NUMBER_LENGTH);
  1215.             if isRequiredSubscriber(SourceFile, TelephoneNumberArray,
  1216.               SurnameArray, NameArray, PatromynicArray, CityArray,
  1217.               RequiredSubscriber) then
  1218.             begin
  1219.                 blockRead(SourceFile, DateOfPayArray, DATE_OF_PAY_LENGTH);
  1220.                 NumberOfDays := dateToNumber(DateOfPayArray);
  1221.                 SubscriberList.add(TelephoneNumberArray, SurnameArray,
  1222.                   NameArray, PatromynicArray, CityArray, NumberOfDays, Number);
  1223.             end;
  1224.         end;
  1225.         Offset := Offset + RECORD_SIZE;
  1226.         Seek(SourceFile, Offset);
  1227.     end;
  1228.     close(SourceFile);
  1229. end;
  1230.  
  1231. function getSubscriber(Index: longWord; var DateString: string): TSubscriber;
  1232. var
  1233.     SourceFile: TBinaryFile;
  1234.     Offset: integer;
  1235.     CurrentSubscriber: TSubscriber;
  1236.     DateOfPayArray: TDateOfPay;
  1237.     NumberOfDays: longWord;
  1238. begin
  1239.      assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1240.      reset(SourceFile);
  1241.      Offset := START_SUBSCRIBER_OFFSET + RECORD_SIZE * Index + NUMBER_LENGTH;
  1242.      Seek(SourceFile, Offset);
  1243.      blockRead(SourceFile, CurrentSubscriber.telephoneNumber, TELEPHONE_NUMBER_LENGTH);
  1244.      blockRead(SourceFile, CurrentSubscriber.surname, SURNAME_LENGTH);
  1245.      blockRead(SourceFile, CurrentSubscriber.name, NAME_LENGTH);
  1246.      blockRead(SourceFile, CurrentSubscriber.patronymic, PATRONYMIC_LENGTH);
  1247.      blockRead(SourceFile, CurrentSubscriber.city, CITY_LENGTH);
  1248.      blockRead(SourceFile, DateOfPayArray, DATE_OF_PAY_LENGTH);
  1249.      DateString := dateArrayToString(DateOfPayArray);
  1250.      close(SourceFile);
  1251.      Result := CurrentSubscriber;
  1252. end;
  1253.  
  1254. function isExist(var RequiredSubscriber: TRequiredSubscriber; var SameSubscriberIndex: integer): boolean;
  1255. var
  1256.     IsExist: boolean;
  1257.     SourceFile: TBinaryFile;
  1258.     TelephoneNumberArray: TTelephoneNumber;
  1259.     SurnameArray: TSurname;
  1260.     NameArray: TName;
  1261.     PatromynicArray: TPatronymic;
  1262.     CityArray: TCity;
  1263.     DateofPayArray: TDateOfPay;
  1264.     Number: TNumber;
  1265.     Offset: integer;
  1266.     OneByte: ansichar;
  1267. begin
  1268.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1269.     reset(SourceFile);
  1270.     Offset := START_SUBSCRIBER_OFFSET;
  1271.     Seek(SourceFile, Offset);
  1272.     IsExist := false;
  1273.     while (not EOF(SourceFile)) and (not IsExist) do
  1274.     begin
  1275.         blockRead(SourceFile, OneByte, 1);
  1276.         if OneByte <> DELETER then
  1277.         begin
  1278.             Seek(SourceFile, Offset);
  1279.             blockRead(SourceFile, Number, NUMBER_LENGTH);
  1280.               if isRequiredSubscriber(SourceFile, TelephoneNumberArray,
  1281.                         SurnameArray, NameArray, PatromynicArray, CityArray, RequiredSubscriber) then
  1282.               begin
  1283.                   IsExist := true;
  1284.                   SameSubscriberIndex := Number;
  1285.               end;
  1286.         end;
  1287.         Offset := Offset + RECORD_SIZE;
  1288.         Seek(SourceFile, Offset);
  1289.     end;
  1290.     close(SourceFile);
  1291.     Result := IsExist;
  1292. end;
  1293.  
  1294. function isRequiredSubscriber(var SourceFile: TBinaryFile; var TelephoneNumberArray: TTelephoneNumber;
  1295.                                 var SurnameArray: TSurname; var NameArray: TName;
  1296.                                   var PatromynicArray: TPatronymic; var CityArray: TCity;
  1297.                                   var RequiredSubscriber: TRequiredSubscriber): boolean;
  1298. begin
  1299.     Result := isRequiredData(SourceFile, RequiredSubscriber.telephoneNumber, TelephoneNumberArray)
  1300.               and isRequiredData(SourceFile, RequiredSubscriber.surname, SurnameArray)
  1301.               and isRequiredData(SourceFile, RequiredSubscriber.name, NameArray)
  1302.               and isRequiredData(SourceFile, RequiredSubscriber.patronymic, PatromynicArray)
  1303.               and isRequiredData(SourceFile, RequiredSubscriber.city, CityArray);
  1304. end;
  1305.  
  1306. function isFileEmpty(): Boolean;
  1307. var
  1308.     SourceFile: TBinaryFile;
  1309.     SizeOfFile: integer;
  1310. begin
  1311.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1312.     Reset(SourceFile);
  1313.     SizeOfFile := FileSize(SourceFile);
  1314.     close(SourceFile);
  1315.     Result := (SizeOfFile = 0);
  1316. end;
  1317.  
  1318. function isEqual(var RequiredString: string; var CurrentArray: array of AnsiChar): Boolean;
  1319. var
  1320.     IsSame: boolean;
  1321.     i: integer;
  1322. begin
  1323.     IsSame := true;
  1324.     i := 1;
  1325.     while IsSame and (i <= length(RequiredString)) do
  1326.         if (RequiredString[i] <> char(CurrentArray[i - 1])) then
  1327.             IsSame := false
  1328.         else
  1329.             inc(i);
  1330.     Result := IsSame;
  1331. end;
  1332.  
  1333. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1334.                                           var TelephoneNumberArray: TTelephoneNumber): boolean;
  1335. begin
  1336.     blockRead(SourceFile, TelephoneNumberArray, TELEPHONE_NUMBER_LENGTH);
  1337.     Result := isEqual(RequiredString, TelephoneNumberArray);
  1338. end;
  1339.  
  1340. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1341.                                           var SurnameArray: TSurname): boolean;
  1342. begin
  1343.     blockRead(SourceFile, SurnameArray, SURNAME_LENGTH);
  1344.     Result := isEqual(RequiredString, SurnameArray);
  1345. end;
  1346.  
  1347. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1348.                                           var NameArray: TName): boolean;
  1349. begin
  1350.     blockRead(SourceFile, NameArray, NAME_LENGTH);
  1351.     Result := isEqual(RequiredString, NameArray);
  1352. end;
  1353.  
  1354. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1355.                                           var FathernameArray: TPatronymic): boolean;
  1356. begin
  1357.     blockRead(SourceFile, FathernameArray, PATRONYMIC_LENGTH);
  1358.     Result := isEqual(RequiredString, FathernameArray);
  1359. end;
  1360.  
  1361. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  1362.                                           var CityArray: TCity): boolean;
  1363. begin
  1364.     blockRead(SourceFile, CityArray, CITY_LENGTH);
  1365.     Result := isEqual(RequiredString, CityArray);
  1366. end;
  1367.  
  1368. end.
  1369.  
  1370.  
  1371. unit ListUnit;
  1372.  
  1373. interface
  1374.  
  1375. uses
  1376.     System.SysUtils, Vcl.ExtCtrls;
  1377.  
  1378. const
  1379.     TELEPHONE_NUMBER_LENGTH = 13;
  1380.     SURNAME_LENGTH = 14;
  1381.     NAME_LENGTH = 11;
  1382.     PATRONYMIC_LENGTH = 14;
  1383.     CITY_LENGTH = 11;
  1384.     DATE_OF_PAY_LENGTH = 8;
  1385.     NUMBER_LENGTH = 4;
  1386.     RECORD_SIZE = TELEPHONE_NUMBER_LENGTH + SURNAME_LENGTH + NAME_LENGTH +
  1387.                  PATRONYMIC_LENGTH + CITY_LENGTH + DATE_OF_PAY_LENGTH + NUMBER_LENGTH;
  1388.     ONLY_DATA_SIZE = TELEPHONE_NUMBER_LENGTH + SURNAME_LENGTH + NAME_LENGTH +
  1389.                  PATRONYMIC_LENGTH + CITY_LENGTH + DATE_OF_PAY_LENGTH;
  1390.  
  1391. type
  1392.  
  1393.     TTelephoneNumber = array[1..TELEPHONE_NUMBER_LENGTH] of AnsiChar;
  1394.     TSurname = array[1..SURNAME_LENGTH] of AnsiChar;
  1395.     TName = array[1..NAME_LENGTH] of AnsiChar;
  1396.     TPatronymic = array[1..PATRONYMIC_LENGTH] of AnsiChar;
  1397.     TCity = array[1..CITY_LENGTH] of AnsiChar;
  1398.     TDateOfPay = array[1..DATE_OF_PAY_LENGTH] of AnsiChar;
  1399.     TNumberOfDays = integer;
  1400.     TNumber = longWord;
  1401.     TSubscriberPointer = ^TSubscriber;
  1402.     TCompareMethod = function(Previous, Next: TSubscriberPointer): boolean of object;
  1403.  
  1404.     TSubscriber = record
  1405.         next: TSubscriberPointer;
  1406.         telephoneNumber: TTelephoneNumber;
  1407.         surname: TSurname;
  1408.         name: TName;
  1409.         patronymic: TPatronymic;
  1410.         city: TCity;
  1411.         numberOfDays: TNumberOfDays;
  1412.         number: TNumber;
  1413.     end;
  1414.  
  1415.     TRequiredSubscriber = record
  1416.         telephoneNumber, surname, name, patronymic, city: string;
  1417.         numberOfDays: TNumberOfDays;
  1418.         number: TNumber;
  1419.     end;
  1420.  
  1421.     TSubscriberList = class
  1422.         private
  1423.             Header: TSubscriberPointer;
  1424.             procedure QuckSort(var headRef: TSubscriberPointer; CompareMethod: TCompareMethod);
  1425.             function getTail(Node: TSubscriberPointer): TSubscriberPointer;
  1426.             function quickSortRecur(head: TSubscriberPointer;
  1427.                                         fin: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  1428.             function partition(head: TSubscriberPointer; Fin: TSubscriberPointer;
  1429.                        var NewHead: TSubscriberPointer;
  1430.                        var NewTail: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  1431.         public
  1432.             function getHeader(): TSubscriberPointer;
  1433.             constructor NewSubscriberList();
  1434.             destructor Destroy(); override;
  1435.             procedure add(CurrentTelephoneNumber: TTelephoneNumber;
  1436.               CurrentSurname: TSurname; CurrentName: TName;
  1437.               CurrentFatherName: TPatronymic; CurrentCity: TCity;
  1438.               CurrentNumberOfDays: TNumberOfDays; CurrentNumber: TNumber);
  1439.             procedure deleteList();
  1440.             function length(): integer;
  1441.             function IsEmpty(): boolean;
  1442.             function getLastPosition(): TSubscriberPointer;
  1443.             procedure sort(CompareMethod: TCompareMethod);
  1444.             class function compareByTelephoneNumber(Previous,
  1445.               Next: TSubscriberPointer): boolean;
  1446.             class function compareBySurname(Previous,
  1447.               Next: TSubscriberPointer): boolean;
  1448.             class function compareByName(Previous,
  1449.               Next: TSubscriberPointer): boolean;
  1450.             class function compareByPatronymic(Previous,
  1451.               Next: TSubscriberPointer): boolean;
  1452.             class function compareByCity(Previous,
  1453.               Next: TSubscriberPointer): boolean;
  1454.             class function compareByDate(Previous,
  1455.               Next: TSubscriberPointer): boolean;
  1456.     end;
  1457.  
  1458. implementation
  1459.  
  1460. uses
  1461.     EditUnit, ReadUnit;
  1462.  
  1463. constructor TSubscriberList.NewSubscriberList();
  1464. begin
  1465.     new(Header);
  1466.     Header^.next := nil;
  1467. end;
  1468.  
  1469. Destructor TSubscriberList.Destroy;
  1470. Begin
  1471.     Dispose(Self.Header);
  1472. Inherited;
  1473. End;
  1474.  
  1475. function TSubscriberList.IsEmpty(): Boolean;
  1476. begin
  1477.     Result := (Header^.next = nil);
  1478. end;
  1479.  
  1480. function TSubscriberList.getHeader(): TSubscriberPointer;
  1481. begin
  1482.     Result := Self.Header;
  1483. end;
  1484.  
  1485. function TSubscriberList.length(): integer;
  1486. var
  1487.     ListLength: integer;
  1488.     PTemp: TSubscriberPointer;
  1489. begin
  1490.     PTemp := getHeader();
  1491.     ListLength := 0;
  1492.     while (PTemp^.next <> nil) do
  1493.     begin
  1494.         PTemp := PTemp^.next;
  1495.         inc(ListLength);
  1496.     end;
  1497.     Result := ListLength;
  1498. end;
  1499.  
  1500. function TSubscriberList.getLastPosition(): TSubscriberPointer;
  1501. var
  1502.     PTemp: TSubscriberPointer;
  1503. begin
  1504.     PTemp := getHeader();
  1505.     while (PTemp^.next <> nil) do
  1506.         PTemp := PTemp^.next;
  1507.     Result := PTemp;
  1508. end;
  1509.  
  1510. procedure TSubscriberList.add(CurrentTelephoneNumber: TTelephoneNumber; CurrentSurname: TSurname;
  1511.                               CurrentName: TName; CurrentFatherName: TPatronymic; CurrentCity: TCity;
  1512.                               CurrentNumberOfDays: TNumberOfDays; CurrentNumber: TNumber);
  1513. var
  1514.     PLastSubscriber: TSubscriberPointer;
  1515. begin
  1516.     PLastSubscriber := getLastPosition();
  1517.     new(PLastSubscriber^.next);
  1518.     PLastSubscriber := PLastSubscriber^.next;
  1519.     PLastSubscriber^.number := CurrentNumber;
  1520.     PLastSubscriber^.telephoneNumber := CurrentTelephoneNumber;
  1521.     PLastSubscriber^.surname := CurrentSurname;
  1522.     PLastSubscriber^.name := CurrentName;
  1523.     PLastSubscriber^.patronymic := CurrentFatherName;
  1524.     PLastSubscriber^.city := CurrentCity;
  1525.     PLastSubscriber^.numberOfDays := CurrentNumberOfDays;
  1526.     PLastSubscriber^.next := nil;
  1527. end;
  1528.  
  1529. procedure TSubscriberList.deleteList();
  1530. var
  1531.     PDeleter: TSubscriberPointer;
  1532.     PTemp: TSubscriberPointer;
  1533. begin
  1534.     PTemp := Header^.next;;
  1535.     while PTemp <> nil do
  1536.     begin
  1537.         PDeleter := PTemp;
  1538.         PTemp := PTemp^.next;
  1539.         dispose(PDeleter);
  1540.     end;
  1541.     Header^.next := nil;
  1542. end;
  1543.  
  1544. class function TSubscriberList.compareByTelephoneNumber(Previous, Next: TSubscriberPointer): boolean;
  1545. begin
  1546.     Result := (Previous^.telephoneNumber > Next^.telephoneNumber);
  1547. end;
  1548.  
  1549. class function TSubscriberList.compareBySurname(Previous, Next: TSubscriberPointer): boolean;
  1550. begin
  1551.     Result := (Previous^.surname > Next^.surname);
  1552. end;
  1553.  
  1554. class function TSubscriberList.compareByName(Previous, Next: TSubscriberPointer): boolean;
  1555. begin
  1556.     Result := (Previous^.name > Next^.name);
  1557. end;
  1558.  
  1559. class function TSubscriberList.compareByPatronymic(Previous, Next: TSubscriberPointer): boolean;
  1560. begin
  1561.     Result := (Previous^.patronymic > Next^.patronymic);
  1562. end;
  1563.  
  1564. class function TSubscriberList.compareByCity(Previous, Next: TSubscriberPointer): boolean;
  1565. begin
  1566.     Result := (Previous^.city > Next^.city);
  1567. end;
  1568.  
  1569. class function TSubscriberList.compareByDate(Previous, Next: TSubscriberPointer): boolean;
  1570. begin
  1571.     Result := (Previous^.numberOfDays > Next^.numberOfDays);
  1572. end;
  1573.  
  1574.  
  1575. function TSubscriberList.getTail(Node: TSubscriberPointer): TSubscriberPointer;
  1576. begin
  1577.     while (Node <> nil) and (Node^.next <> nil) do
  1578.         Node := Node^.next;
  1579.     Result := Node;
  1580. end;
  1581.  
  1582. function TSubscriberList.partition(Head: TSubscriberPointer; Fin: TSubscriberPointer;
  1583.                        var NewHead: TSubscriberPointer;
  1584.                        var NewTail: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  1585. var
  1586.     Pivot: TSubscriberPointer;
  1587.     Previous: TSubscriberPointer;
  1588.     Current: TSubscriberPointer;
  1589.     Tail: TSubscriberPointer;
  1590.     Temp: TSubscriberPointer;
  1591. begin
  1592.     Pivot := Fin;
  1593.     Previous := nil;
  1594.     Current := Head;
  1595.     Tail := Pivot;
  1596.     while (Current <> Pivot) do
  1597.     begin
  1598.         if CompareMethod(Pivot, Current) then
  1599.         begin
  1600.             if (NewHead = nil) then
  1601.                 NewHead := Current;
  1602.             Previous := Current;
  1603.             Current := Current^.next;
  1604.         end
  1605.         else
  1606.         begin
  1607.             if (Previous <> nil) then
  1608.                 Previous^.next := Current^.next;
  1609.             Temp := Current^.next;
  1610.             Current^.next := nil;
  1611.             Tail^.next := Current;
  1612.             Tail := Current;
  1613.             Current := Temp;
  1614.         end;
  1615.     end;
  1616.     if (NewHead = nil) then
  1617.         NewHead := Pivot;
  1618.     NewTail := Tail;
  1619.     Result := Pivot;
  1620. end;
  1621.  
  1622. function TSubscriberList.quickSortRecur(Head: TSubscriberPointer;
  1623.                  Fin: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  1624. var
  1625.     NewHead: TSubscriberPointer;
  1626.     NewEnd: TSubscriberPointer;
  1627.     Temp: TSubscriberPointer;
  1628.     Pivot: TSubscriberPointer;
  1629. begin
  1630.     if ((not (Head <> nil)) or (Head = Fin)) then
  1631.         Result := Head
  1632.     else
  1633.     begin
  1634.         NewHead := nil;
  1635.         NewEnd := nil;
  1636.         Pivot := partition(Head, Fin, NewHead, NewEnd, CompareMethod);
  1637.         if (NewHead <> Pivot) then
  1638.         begin
  1639.             Temp := NewHead;
  1640.             while (Temp^.next <> Pivot) do
  1641.                 Temp := Temp^.next;
  1642.             Temp^.next := nil;
  1643.             NewHead := quickSortRecur(NewHead, Temp,CompareMethod);
  1644.             Temp := getTail(NewHead);
  1645.             Temp^.next := Pivot;
  1646.         end;
  1647.     Pivot^.next := quickSortRecur(Pivot^.next, NewEnd, CompareMethod);
  1648.     Result := NewHead;
  1649.     end;
  1650. end;
  1651.  
  1652. procedure TSubscriberList.Sort(CompareMethod: TCompareMethod);
  1653. begin
  1654.     QuckSort(Self.getHeader^.next, CompareMethod);
  1655. end;
  1656.  
  1657. procedure TSubscriberList.QuckSort(var headRef: TSubscriberPointer; CompareMethod: TCompareMethod);
  1658. var
  1659.     Tail: TSubscriberPointer;
  1660. begin
  1661.     Tail := getTail(headRef);
  1662.     headRef := quickSortRecur(headRef, Tail, CompareMethod);
  1663. end;
  1664.  
  1665. end.
  1666.  
  1667.  
  1668. unit WriteUnit;
  1669.  
  1670. interface
  1671.  
  1672. uses
  1673.     System.SysUtils, ListUnit, ReadUnit, StartUnit;
  1674.  
  1675.     procedure clearFile();
  1676.     procedure write(TelephoneNumber: TTelephoneNumber; Surname: TSurname;
  1677.                               Name: TName; FatherName: TPatronymic;
  1678.                               City: TCity; DateOfPay: TDateOfPay); overload;
  1679.     procedure write(SubscriberIndex: TNumber; TelephoneNumber: TTelephoneNumber;
  1680.                                     Surname: TSurname; Name: TName; FatherName: TPatronymic;
  1681.                                   City: TCity; DateOfPay: TDateOfPay); overload;
  1682.     function toTelephoneNumber(Data: string): TTelephoneNumber;
  1683.     function toSurname(Data: string): TSurname;
  1684.     function toName(Data: string): TName;
  1685.     function toPatronymic(Data: string): TPatronymic;
  1686.     function toCity(Data: string): TCity;
  1687.     function toDateOfPay(StartDate: TDate; Data: integer): TDateOfPay;
  1688.     procedure deleteSubscriber(NumberOfSubscriber: TNumber);
  1689.     procedure removeDeleters();
  1690.  
  1691. implementation
  1692.  
  1693. uses
  1694.     DateUtils, Math;
  1695.  
  1696. procedure clearFile();
  1697. var
  1698.     SourceFile: TBinaryFile;
  1699. begin
  1700.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1701.     rewrite(SourceFile);
  1702.     closeFile(SourceFile);
  1703. end;
  1704.  
  1705. procedure removeDeleters();
  1706. const
  1707.     TEMP_FILE_NAME = 'TempFile.bin';
  1708. var
  1709.     SourceFile, TempFile: TBinaryFile;
  1710.     OneByte: ansichar;
  1711.     BufferArray: Array[1..ONLY_DATA_SIZE] of ansichar;
  1712.     offset: integer;
  1713.     Number: longWord;
  1714. begin
  1715.     assign(SourceFile, GetCurrentDir + '\' + FILE_NAME);
  1716.     assign(TempFile, GetCurrentDir + '\' + TEMP_FILE_NAME);
  1717.     Number := 0;
  1718.     rewrite(TempFile);
  1719.     reset(SourceFile);
  1720.     offset := START_SUBSCRIBER_OFFSET;
  1721.     while not EOF(SourceFile) do
  1722.     begin
  1723.         blockRead(SourceFile, OneByte, 1);
  1724.         if (OneByte <> DELETER) then
  1725.         begin
  1726.             Seek(SourceFile, Offset + NUMBER_LENGTH);
  1727.             blockRead(SourceFile, BufferArray, ONLY_DATA_SIZE);
  1728.             blockWrite(TempFile, Number, NUMBER_LENGTH);
  1729.             blockWrite(TempFile,  BufferArray, ONLY_DATA_SIZE);
  1730.             inc(Number);
  1731.         end;
  1732.         Offset := Offset + RECORD_SIZE;
  1733.         seek(SourceFile, Offset);
  1734.     end;
  1735.     closeFile(SourceFile);
  1736.     closeFile(TempFile);
  1737.     deleteFile(GetCurrentDir + '\' + FILE_NAME);
  1738.     RenameFile(GetCurrentDir + '\' + TEMP_FILE_NAME, GetCurrentDir + '\' + FILE_NAME);
  1739. end;
  1740.  
  1741. procedure write(TelephoneNumber: TTelephoneNumber; Surname: TSurname;
  1742.                                   Name: TName; FatherName: TPatronymic;
  1743.                                   City: TCity; DateOfPay: TDateOfPay);
  1744. const
  1745.     MAX_SUBSCRIBER_NUMBER = 999999;
  1746. var
  1747.     SourceFile: TBinaryFile;
  1748.     SizeOfFile: integer;
  1749.     NumberOfRecord: LongWord;
  1750. begin
  1751.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1752.     reset(SourceFile);
  1753.     SizeOfFile := fileSize(SourceFile) - START_SUBSCRIBER_OFFSET;
  1754.     NumberOfRecord := SizeOfFile div RECORD_SIZE;
  1755.     if NumberOfRecord < MAX_SUBSCRIBER_NUMBER then
  1756.     begin
  1757.         Seek(SourceFile, SizeOfFile);
  1758.         blockWrite(SourceFile, NumberOfRecord, NUMBER_LENGTH);
  1759.         blockWrite(SourceFile, TelephoneNumber, TELEPHONE_NUMBER_LENGTH);
  1760.         blockWrite(SourceFile, Surname, SURNAME_LENGTH);
  1761.         blockWrite(SourceFile, Name, NAME_LENGTH);
  1762.         blockWrite(SourceFile, FatherName, PATRONYMIC_LENGTH);
  1763.         blockWrite(SourceFile, City, CITY_LENGTH);
  1764.         blockWrite(SourceFile, DateOfPay, DATE_OF_PAY_LENGTH);
  1765.     end;
  1766.     closeFile(SourceFile);
  1767. end;
  1768.  
  1769. procedure write(SubscriberIndex: TNumber; TelephoneNumber: TTelephoneNumber;
  1770.                                     Surname: TSurname; Name: TName; FatherName: TPatronymic;
  1771.                                   City: TCity; DateOfPay: TDateOfPay);
  1772. var
  1773.     SourceFile: TBinaryFile;
  1774. begin
  1775.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1776.     reset(SourceFile);
  1777.     seek(SourceFile, START_SUBSCRIBER_OFFSET + SubscriberIndex * RECORD_SIZE);
  1778.     blockWrite(SourceFile, SubscriberIndex, NUMBER_LENGTH);
  1779.     blockWrite(SourceFile, TelephoneNumber, TELEPHONE_NUMBER_LENGTH);
  1780.     blockWrite(SourceFile, Surname, SURNAME_LENGTH);
  1781.     blockWrite(SourceFile, Name, NAME_LENGTH);
  1782.     blockWrite(SourceFile, Fathername, PATRONYMIC_LENGTH);
  1783.     blockWrite(SourceFile, City, CITY_LENGTH);
  1784.     blockWrite(SourceFile, DateofPay, DATE_OF_PAY_LENGTH);
  1785.     closeFile(SourceFile);
  1786. end;
  1787.  
  1788. procedure deleteSubscriber(NumberOfSubscriber: TNumber);
  1789. const
  1790.     DELETER: ansichar = '/';
  1791. var
  1792.     SourceFile: TBinaryFile;
  1793.     Offset: integer;
  1794.     NumberOfRecord: LongWord;
  1795.     DeleterArray: array[1..RECORD_SIZE] of ansichar;
  1796. begin
  1797.     fillchar(DeleterArray, RECORD_SIZE, DELETER);
  1798.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  1799.     reset(SourceFile);
  1800.     Offset := NumberOfSubscriber * RECORD_SIZE;
  1801.     seek(SourceFile, Offset);
  1802.     blockWrite(SourceFile, DeleterArray, RECORD_SIZE);
  1803.     closeFile(SourceFile);
  1804. end;
  1805.  
  1806. function toTelephoneNumber(Data: string): TTelephoneNumber;
  1807. var
  1808.     ResultArray: TTelephoneNumber;
  1809.     i: integer;
  1810. begin
  1811.     i := 1;
  1812.     while i <= length(Data) do
  1813.     begin
  1814.         ResultArray[i] := ansichar(Data[i]);
  1815.         inc(i);
  1816.     end;
  1817.     while i <= TELEPHONE_NUMBER_LENGTH do
  1818.     begin
  1819.         ResultArray[i] := ' ';
  1820.         inc(i);
  1821.     end;
  1822.     Result := ResultArray;
  1823. end;
  1824.  
  1825. function toSurname(Data: string): TSurname;
  1826. var
  1827.     ResultArray: TSurname;
  1828.     i: integer;
  1829. begin
  1830.     i := 1;
  1831.     while i <= length(Data) do
  1832.     begin
  1833.         ResultArray[i] := ansichar(Data[i]);
  1834.         inc(i);
  1835.     end;
  1836.     while i <= SURNAME_LENGTH do
  1837.     begin
  1838.         ResultArray[i] := ' ';
  1839.         inc(i);
  1840.     end;
  1841.     Result := ResultArray;
  1842. end;
  1843.  
  1844. function toName(Data: string): TName;
  1845. var
  1846.     ResultArray: TName;
  1847.     i: integer;
  1848. begin
  1849.     i := 1;
  1850.     while i <= length(Data) do
  1851.     begin
  1852.         ResultArray[i] := AnsiChar(Data[i]);
  1853.         inc(i);
  1854.     end;
  1855.     while i <= NAME_LENGTH do
  1856.     begin
  1857.         ResultArray[i] := ' ';
  1858.         inc(i);
  1859.     end;
  1860.     Result := ResultArray;
  1861. end;
  1862.  
  1863. function toPatronymic(Data: string): TPatronymic;
  1864. var
  1865.     ResultArray: TPatronymic;
  1866.     i: integer;
  1867. begin
  1868.     i := 1;
  1869.     while i <= length(Data) do
  1870.     begin
  1871.         ResultArray[i] := AnsiChar(Data[i]);
  1872.         inc(i);
  1873.     end;
  1874.     while i <= PATRONYMIC_LENGTH do
  1875.     begin
  1876.         ResultArray[i] := ' ';
  1877.         inc(i);
  1878.     end;
  1879.     Result := ResultArray;
  1880. end;
  1881.  
  1882. function toCity(Data: string): TCity;
  1883. var
  1884.     ResultArray: TCity;
  1885.     i: integer;
  1886. begin
  1887.     i := 1;
  1888.     while i <= length(Data) do
  1889.     begin
  1890.         ResultArray[i] := AnsiChar(Data[i]);
  1891.         inc(i);
  1892.     end;
  1893.     while i <= CITY_LENGTH do
  1894.     begin
  1895.         ResultArray[i] := ' ';
  1896.         inc(i);
  1897.     end;
  1898.     Result := ResultArray;
  1899. end;
  1900.  
  1901. function toDateOfPay(StartDate: TDate; Data: integer): TDateOfPay;
  1902. const
  1903.     FIRST_DOT = 3;
  1904.     SECOND_DOT = 6;
  1905.     MAX_DATE_STR = '23.11.9999';
  1906. var
  1907.     ResultArray: TDateOfPay;
  1908.     i, j: integer;
  1909.     NewDate: TDate;
  1910.     NewDateString: string;
  1911.     MaxDate: TDate;
  1912. begin
  1913.     MaxDate := strToDate(MAX_DATE_STR);
  1914.     NewDate := incDay(StartDate, Round(Data/(ServiceCost / 30)));
  1915.     NewDateString := dateToStr(NewDate);
  1916.     j := 1;
  1917.     if (CompareDate(NewDate, MaxDate) = 1) then
  1918.         NewDateString := dateToStr(StartDate);
  1919.     for i := 1 to (DATE_OF_PAY_LENGTH + 2) do
  1920.     begin
  1921.         if (i <> FIRST_DOT) and (i <> SECOND_DOT) then
  1922.         begin
  1923.             ResultArray[j] := ansichar(NewDateString[i]);
  1924.             inc(j)
  1925.         end
  1926.     end;
  1927.     Result := ResultArray;
  1928. end;
  1929.  
  1930. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement