Advertisement
believe_me

Untitled

May 17th, 2022
369
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 47.74 KB | None | 0 0
  1. unit WriteUnit;
  2.  
  3. interface
  4.  
  5. uses
  6.     System.SysUtils, ListUnit, ReadUnit, StartUnit;
  7.  
  8.     procedure clearFile();
  9.     procedure write(TelephoneNumber: TTelephoneNumber; Surname: TSurname;
  10.                               Name: TName; FatherName: TPatronymic;
  11.                               City: TCity; DateOfPay: TDateOfPay); overload;
  12.     procedure write(SubscriberIndex: TNumber; TelephoneNumber: TTelephoneNumber;
  13.                                     Surname: TSurname; Name: TName; FatherName: TPatronymic;
  14.                                   City: TCity; DateOfPay: TDateOfPay); overload;
  15.     function toTelephoneNumber(Data: string): TTelephoneNumber;
  16.     function toSurname(Data: string): TSurname;
  17.     function toName(Data: string): TName;
  18.     function toPatronymic(Data: string): TPatronymic;
  19.     function toCity(Data: string): TCity;
  20.     function toDateOfPay(StartDate: TDate; Data: integer): TDateOfPay;
  21.     procedure deleteSubscriber(NumberOfSubscriber: TNumber);
  22.     procedure removeDeleters();
  23.  
  24. implementation
  25.  
  26. uses
  27.     DateUtils, Math;
  28.  
  29. procedure clearFile();
  30. var
  31.     SourceFile: TBinaryFile;
  32. begin
  33.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  34.     rewrite(SourceFile);
  35.     closeFile(SourceFile);
  36. end;
  37.  
  38. procedure removeDeleters();
  39. const
  40.     TEMP_FILE_NAME = 'TempFile.bin';
  41. var
  42.     SourceFile, TempFile: TBinaryFile;
  43.     OneByte: ansichar;
  44.     BufferArray: Array[1..ONLY_DATA_SIZE] of ansichar;
  45.     offset: integer;
  46.     Number: longWord;
  47. begin
  48.     assign(SourceFile, GetCurrentDir + '\' + FILE_NAME);
  49.     assign(TempFile, GetCurrentDir + '\' + TEMP_FILE_NAME);
  50.     Number := 0;
  51.     rewrite(TempFile);
  52.     reset(SourceFile);
  53.     offset := START_SUBSCRIBER_OFFSET;
  54.     while not EOF(SourceFile) do
  55.     begin
  56.         blockRead(SourceFile, OneByte, 1);
  57.         if (OneByte <> DELETER) then
  58.         begin
  59.             Seek(SourceFile, Offset + 4);
  60.             blockRead(SourceFile, BufferArray, ONLY_DATA_SIZE);
  61.             blockWrite(TempFile, Number, 4);
  62.             blockWrite(TempFile,  BufferArray, ONLY_DATA_SIZE);
  63.             inc(Number);
  64.         end;
  65.         Offset := Offset + RECORD_SIZE;
  66.         seek(SourceFile, Offset);
  67.     end;
  68.     closeFile(SourceFile);
  69.     closeFile(TempFile);
  70.     deleteFile(GetCurrentDir + '\' + FILE_NAME);
  71.     RenameFile(GetCurrentDir + '\' + TEMP_FILE_NAME, GetCurrentDir + '\' + FILE_NAME);
  72. end;
  73.  
  74. procedure write(TelephoneNumber: TTelephoneNumber; Surname: TSurname;
  75.                                   Name: TName; FatherName: TPatronymic;
  76.                                   City: TCity; DateOfPay: TDateOfPay);
  77. const
  78.     MAX_SUBSCRIBER_NUMBER = 9999999;
  79. var
  80.     SourceFile: TBinaryFile;
  81.     SizeOfFile: integer;
  82.     NumberOfRecord: LongWord;
  83.     ArrayOfRecordNumber: TNumber;
  84. begin
  85.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  86.     reset(SourceFile);
  87.     SizeOfFile := fileSize(SourceFile) - START_SUBSCRIBER_OFFSET;
  88.     NumberOfRecord := SizeOfFile div RECORD_SIZE;
  89.     if NumberOfRecord < MAX_SUBSCRIBER_NUMBER then
  90.     begin
  91.         Seek(SourceFile, SizeOfFile);
  92.         blockWrite(SourceFile, NumberOfRecord, NUMBER_LENGTH);
  93.         blockWrite(SourceFile, TelephoneNumber, TELEPHONE_NUMBER_LENGTH);
  94.         blockWrite(SourceFile, Surname, SURNAME_LENGTH);
  95.         blockWrite(SourceFile, Name, NAME_LENGTH);
  96.         blockWrite(SourceFile, FatherName, PATRONYMIC_LENGTH);
  97.         blockWrite(SourceFile, City, CITY_LENGTH);
  98.         blockWrite(SourceFile, DateOfPay, DATE_OF_PAY_LENGTH);
  99.     end;
  100.     closeFile(SourceFile);
  101. end;
  102.  
  103. procedure write(SubscriberIndex: TNumber; TelephoneNumber: TTelephoneNumber;
  104.                                     Surname: TSurname; Name: TName; FatherName: TPatronymic;
  105.                                   City: TCity; DateOfPay: TDateOfPay);
  106. var
  107.     SourceFile: TBinaryFile;
  108.     ArrayOfRecordNumber: TNumber;
  109. begin
  110.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  111.     reset(SourceFile);
  112.     seek(SourceFile, START_SUBSCRIBER_OFFSET + SubscriberIndex * RECORD_SIZE);
  113.     blockWrite(SourceFile, SubscriberIndex, NUMBER_LENGTH);
  114.     blockWrite(SourceFile, TelephoneNumber, TELEPHONE_NUMBER_LENGTH);
  115.     blockWrite(SourceFile, Surname, SURNAME_LENGTH);
  116.     blockWrite(SourceFile, Name, NAME_LENGTH);
  117.     blockWrite(SourceFile, Fathername, PATRONYMIC_LENGTH);
  118.     blockWrite(SourceFile, City, CITY_LENGTH);
  119.     blockWrite(SourceFile, DateofPay, DATE_OF_PAY_LENGTH);
  120.     closeFile(SourceFile);
  121. end;
  122.  
  123. procedure deleteSubscriber(NumberOfSubscriber: TNumber);
  124. const
  125.     DELETER: ansichar = '/';
  126. var
  127.     SourceFile: TBinaryFile;
  128.     Offset: integer;
  129.     NumberOfRecord: LongWord;
  130.     ArrayOfRecordNumber: TNumber;
  131.     DeleterArray: array[1..RECORD_SIZE] of ansichar;
  132. begin
  133.     fillchar(DeleterArray, RECORD_SIZE, DELETER);
  134.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  135.     reset(SourceFile);
  136.     Offset := NumberOfSubscriber * RECORD_SIZE;
  137.     seek(SourceFile, Offset);
  138.     blockWrite(SourceFile, DeleterArray, RECORD_SIZE);
  139.     closeFile(SourceFile);
  140. end;
  141.  
  142. function toTelephoneNumber(Data: string): TTelephoneNumber;
  143. var
  144.     ResultArray: TTelephoneNumber;
  145.     i: integer;
  146. begin
  147.     i := 1;
  148.     while i <= length(Data) do
  149.     begin
  150.         ResultArray[i] := ansichar(Data[i]);
  151.         inc(i);
  152.     end;
  153.     while i <= TELEPHONE_NUMBER_LENGTH do
  154.     begin
  155.         ResultArray[i] := ' ';
  156.         inc(i);
  157.     end;
  158.     Result := ResultArray;
  159. end;
  160.  
  161. function toSurname(Data: string): TSurname;
  162. var
  163.     ResultArray: TSurname;
  164.     i: integer;
  165. begin
  166.     i := 1;
  167.     while i <= length(Data) do
  168.     begin
  169.         ResultArray[i] := ansichar(Data[i]);
  170.         inc(i);
  171.     end;
  172.     while i <= SURNAME_LENGTH do
  173.     begin
  174.         ResultArray[i] := ' ';
  175.         inc(i);
  176.     end;
  177.     Result := ResultArray;
  178. end;
  179.  
  180. function toName(Data: string): TName;
  181. var
  182.     ResultArray: TName;
  183.     i: integer;
  184. begin
  185.     i := 1;
  186.     while i <= length(Data) do
  187.     begin
  188.         ResultArray[i] := AnsiChar(Data[i]);
  189.         inc(i);
  190.     end;
  191.     while i <= NAME_LENGTH do
  192.     begin
  193.         ResultArray[i] := ' ';
  194.         inc(i);
  195.     end;
  196.     Result := ResultArray;
  197. end;
  198.  
  199. function toPatronymic(Data: string): TPatronymic;
  200. var
  201.     ResultArray: TPatronymic;
  202.     i: integer;
  203. begin
  204.     i := 1;
  205.     while i <= length(Data) do
  206.     begin
  207.         ResultArray[i] := AnsiChar(Data[i]);
  208.         inc(i);
  209.     end;
  210.     while i <= PATRONYMIC_LENGTH do
  211.     begin
  212.         ResultArray[i] := ' ';
  213.         inc(i);
  214.     end;
  215.     Result := ResultArray;
  216. end;
  217.  
  218. function toCity(Data: string): TCity;
  219. var
  220.     ResultArray: TCity;
  221.     i: integer;
  222. begin
  223.     i := 1;
  224.     while i <= length(Data) do
  225.     begin
  226.         ResultArray[i] := AnsiChar(Data[i]);
  227.         inc(i);
  228.     end;
  229.     while i <= CITY_LENGTH do
  230.     begin
  231.         ResultArray[i] := ' ';
  232.         inc(i);
  233.     end;
  234.     Result := ResultArray;
  235. end;
  236.  
  237. function toDateOfPay(StartDate: TDate; Data: integer): TDateOfPay;
  238. const
  239.     FIRST_DOT = 3;
  240.     SECOND_DOT = 6;
  241.     MAX_DATE_STR = '23.11.9999';
  242. var
  243.     ResultArray: TDateOfPay;
  244.     i, j: integer;
  245.     NewDate: TDate;
  246.     NewDateString: string;
  247.     MaxDate: TDate;
  248. begin
  249.     MaxDate := strToDate(MAX_DATE_STR);
  250.     NewDate := incDay(StartDate, Round(Data/(ServiceCost / 30 )));
  251.     NewDateString := dateToStr(NewDate);
  252.     j := 1;
  253.     if (CompareDate(NewDate, MaxDate) = 1) then
  254.         NewDateString := dateToStr(StartDate);
  255.     for i := 1 to (DATE_OF_PAY_LENGTH + 2) do
  256.     begin
  257.         if (i <> FIRST_DOT) and (i <> SECOND_DOT) then
  258.         begin
  259.             ResultArray[j] := ansichar(NewDateString[i]);
  260.             inc(j)
  261.         end
  262.         else
  263.             ResultArray[i] := ansichar(0);
  264.     end;
  265.     Result := ResultArray;
  266. end;
  267.  
  268. end.
  269.  
  270. unit ListUnit;
  271.  
  272. interface
  273.  
  274. uses
  275.     System.SysUtils, Vcl.ExtCtrls;
  276.  
  277. const
  278.     TELEPHONE_NUMBER_LENGTH = 13;
  279.     SURNAME_LENGTH = 14;
  280.     NAME_LENGTH = 11;
  281.     PATRONYMIC_LENGTH = 14;
  282.     CITY_LENGTH = 11;
  283.     DATE_OF_PAY_LENGTH = 8;
  284.     NUMBER_LENGTH = 4;
  285.     RECORD_SIZE = TELEPHONE_NUMBER_LENGTH + SURNAME_LENGTH + NAME_LENGTH +
  286.                  PATRONYMIC_LENGTH + CITY_LENGTH + DATE_OF_PAY_LENGTH + NUMBER_LENGTH;
  287.     ONLY_DATA_SIZE = TELEPHONE_NUMBER_LENGTH + SURNAME_LENGTH + NAME_LENGTH +
  288.                  PATRONYMIC_LENGTH + CITY_LENGTH + DATE_OF_PAY_LENGTH;
  289.  
  290. type
  291.  
  292.     TTelephoneNumber = array[1..TELEPHONE_NUMBER_LENGTH] of AnsiChar;
  293.     TSurname = array[1..SURNAME_LENGTH] of AnsiChar;
  294.     TName = array[1..NAME_LENGTH] of AnsiChar;
  295.     TPatronymic = array[1..PATRONYMIC_LENGTH] of AnsiChar;
  296.     TCity = array[1..CITY_LENGTH] of AnsiChar;
  297.     TDateOfPay = array[1..DATE_OF_PAY_LENGTH] of AnsiChar;
  298.     TNumberOfDays = integer;
  299.     TNumber = longWord;
  300.     TSubscriberPointer = ^TSubscriber;
  301.     TCompareMethod = function(Previous, Next: TSubscriberPointer): boolean of object;
  302.  
  303.     TSubscriber = record
  304.         next: TSubscriberPointer;
  305.         telephoneNumber: TTelephoneNumber;
  306.         surname: TSurname;
  307.         name: TName;
  308.         patronymic: TPatronymic;
  309.         city: TCity;
  310.         numberOfDays: TNumberOfDays;
  311.         number: TNumber;
  312.     end;
  313.  
  314.     TRequiredSubscriber = record
  315.         telephoneNumber, surname, name, patronymic, city: string;
  316.         numberOfDays: TNumberOfDays;
  317.         number: TNumber;
  318.     end;
  319.  
  320.     TSubscriberList = class
  321.         private
  322.             Header: TSubscriberPointer;
  323.         public
  324.             function getHeader(): TSubscriberPointer;
  325.             constructor NewSubscriberList();
  326.             procedure add(CurrentTelephoneNumber: TTelephoneNumber;
  327.               CurrentSurname: TSurname; CurrentName: TName;
  328.               CurrentFatherName: TPatronymic; CurrentCity: TCity;
  329.               CurrentNumberOfDays: TNumberOfDays; CurrentNumber: TNumber);
  330.             procedure deleteList();
  331.             function length(): integer;
  332.             function IsEmpty(): boolean;
  333.             function getLastPosition(): TSubscriberPointer;
  334.             procedure sort(CompareMethod: TCompareMethod);
  335.             class function compareByTelephoneNumber(Previous,
  336.               Next: TSubscriberPointer): boolean;
  337.             class function compareBySurname(Previous,
  338.               Next: TSubscriberPointer): boolean;
  339.             class function compareByName(Previous,
  340.               Next: TSubscriberPointer): boolean;
  341.             class function compareByPatronymic(Previous,
  342.               Next: TSubscriberPointer): boolean;
  343.             class function compareByCity(Previous,
  344.               Next: TSubscriberPointer): boolean;
  345.             class function compareByDate(Previous,
  346.               Next: TSubscriberPointer): boolean;
  347.             class procedure QuckSort(var headRef: TSubscriberPointer; CompareMethod: TCompareMethod);
  348.             class function getTail(Node: TSubscriberPointer): TSubscriberPointer;
  349.             class function quickSortRecur(head: TSubscriberPointer;
  350.                                         fin: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  351.             class function partition(head: TSubscriberPointer; Fin: TSubscriberPointer;
  352.                        var NewHead: TSubscriberPointer;
  353.                        var NewTail: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  354.     end;
  355.  
  356. implementation
  357.  
  358. uses
  359.     EditUnit, ReadUnit;
  360.  
  361. constructor TSubscriberList.NewSubscriberList();
  362. begin
  363.     new(Header);
  364.     Header^.next := nil;
  365. end;
  366.  
  367. function TSubscriberList.IsEmpty(): Boolean;
  368. begin
  369.     Result := (Header^.next = nil);
  370. end;
  371.  
  372. function TSubscriberList.getHeader(): TSubscriberPointer;
  373. begin
  374.     Result := Self.Header;
  375. end;
  376.  
  377. function TSubscriberList.length(): integer;
  378. var
  379.     ListLength: integer;
  380.     PTemp: TSubscriberPointer;
  381. begin
  382.     PTemp := getHeader();
  383.     ListLength := 0;
  384.     while (PTemp^.next <> nil) do
  385.     begin
  386.         PTemp := PTemp^.next;
  387.         inc(ListLength);
  388.     end;
  389.     Result := ListLength;
  390. end;
  391.  
  392. function TSubscriberList.getLastPosition(): TSubscriberPointer;
  393. var
  394.     PTemp: TSubscriberPointer;
  395. begin
  396.     PTemp := getHeader();
  397.     while (PTemp^.next <> nil) do
  398.         PTemp := PTemp^.next;
  399.     Result := PTemp;
  400. end;
  401.  
  402. procedure TSubscriberList.add(CurrentTelephoneNumber: TTelephoneNumber; CurrentSurname: TSurname;
  403.                               CurrentName: TName; CurrentFatherName: TPatronymic; CurrentCity: TCity;
  404.                               CurrentNumberOfDays: TNumberOfDays; CurrentNumber: TNumber);
  405. var
  406.     PLastSubscriber: TSubscriberPointer;
  407. begin
  408.     PLastSubscriber := getLastPosition();
  409.     new(PLastSubscriber^.next);
  410.     PLastSubscriber := PLastSubscriber^.next;
  411.     PLastSubscriber^.number := CurrentNumber;
  412.     PLastSubscriber^.telephoneNumber := CurrentTelephoneNumber;
  413.     PLastSubscriber^.surname := CurrentSurname;
  414.     PLastSubscriber^.name := CurrentName;
  415.     PLastSubscriber^.patronymic := CurrentFatherName;
  416.     PLastSubscriber^.city := CurrentCity;
  417.     PLastSubscriber^.numberOfDays := CurrentNumberOfDays;
  418.     PLastSubscriber^.next := nil;
  419. end;
  420.  
  421. procedure TSubscriberList.deleteList();
  422. var
  423.     PDeleter: TSubscriberPointer;
  424.     PTemp: TSubscriberPointer;
  425. begin
  426.     PTemp := Header^.next;;
  427.     while PTemp <> nil do
  428.     begin
  429.         PDeleter := PTemp;
  430.         PTemp := PTemp^.next;
  431.         dispose(PDeleter);
  432.     end;
  433.     Header^.next := nil;
  434. end;
  435.  
  436. class function TSubscriberList.compareByTelephoneNumber(Previous, Next: TSubscriberPointer): boolean;
  437. begin
  438.     Result := (Previous^.telephoneNumber > Next^.telephoneNumber);
  439. end;
  440.  
  441. class function TSubscriberList.compareBySurname(Previous, Next: TSubscriberPointer): boolean;
  442. begin
  443.     Result := (Previous^.surname > Next^.surname);
  444. end;
  445.  
  446. class function TSubscriberList.compareByName(Previous, Next: TSubscriberPointer): boolean;
  447. begin
  448.     Result := (Previous^.name > Next^.name);
  449. end;
  450.  
  451. class function TSubscriberList.compareByPatronymic(Previous, Next: TSubscriberPointer): boolean;
  452. begin
  453.     Result := (Previous^.patronymic > Next^.patronymic);
  454. end;
  455.  
  456. class function TSubscriberList.compareByCity(Previous, Next: TSubscriberPointer): boolean;
  457. begin
  458.     Result := (Previous^.city > Next^.city);
  459. end;
  460.  
  461. class function TSubscriberList.compareByDate(Previous, Next: TSubscriberPointer): boolean;
  462. begin
  463.     Result := (Previous^.numberOfDays > Next^.numberOfDays);
  464. end;
  465.  
  466.  
  467. class function TSubscriberList.getTail(Node: TSubscriberPointer): TSubscriberPointer;
  468. begin
  469.     while (Node <> nil) and (Node^.next <> nil) do
  470.         Node := Node^.next;
  471.     Result := Node;
  472. end;
  473.  
  474. class function TSubscriberList.partition(head: TSubscriberPointer; Fin: TSubscriberPointer;
  475.                        var NewHead: TSubscriberPointer;
  476.                        var NewTail: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  477. var
  478.     Pivot: TSubscriberPointer;
  479.     Previous: TSubscriberPointer;
  480.     Current: TSubscriberPointer;
  481.     Tail: TSubscriberPointer;
  482.     Temp: TSubscriberPointer;
  483. begin
  484.     Pivot := Fin;
  485.     Previous := nil;
  486.     Current := head;
  487.     Tail := Pivot;
  488.     while (Current <> Pivot) do
  489.     begin
  490.         if CompareMethod(Pivot, Current) then
  491.         begin
  492.             if (newHead = nil) then
  493.                 newHead := Current;
  494.             Previous := Current;
  495.             Current := Current^.next;
  496.         end
  497.         else
  498.         begin
  499.             if (Previous <> nil) then
  500.                 Previous^.next := Current^.next;
  501.             Temp := Current^.next;
  502.             Current^.next := nil;
  503.             Tail^.next := Current;
  504.             Tail := Current;
  505.             Current := Temp;
  506.         end;
  507.     end;
  508.     if (NewHead = nil) then
  509.         NewHead := Pivot;
  510.     NewTail := Tail;
  511.     Result := Pivot;
  512. end;
  513.  
  514. class function TSubscriberList.quickSortRecur(head: TSubscriberPointer;
  515.                  fin: TSubscriberPointer; CompareMethod: TCompareMethod): TSubscriberPointer;
  516. var
  517.     NewHead: TSubscriberPointer;
  518.     NewEnd: TSubscriberPointer;
  519.     tmp: TSubscriberPointer;
  520.     pivot: TSubscriberPointer;
  521. begin
  522.     // base condition
  523.     if ((not (head <> nil)) or (head = fin)) then
  524.         Result := head
  525.     else
  526.     begin
  527.         newHead := nil;
  528.         newEnd := nil;
  529.     // Partition the list, newHead and newEnd will be
  530.     // updated by the partition function
  531.         pivot := partition(head, fin, newHead, newEnd, CompareMethod);
  532.     // If pivot is the smallest element - no need to recur
  533.     // for the left part.
  534.         if (newHead <> pivot) then
  535.         begin
  536.             // Set the node before the pivot node as nullptr
  537.             tmp := newHead;
  538.             while (tmp^.next <> pivot) do
  539.                 tmp := tmp^.next;
  540.             tmp^.next := nil;
  541.             newHead := quickSortRecur(newHead, tmp,CompareMethod);
  542.             tmp := getTail(newHead);
  543.             tmp^.next := pivot;
  544.         end;
  545.     pivot^.next := quickSortRecur(pivot^.next, newEnd, CompareMethod);
  546.     Result := newHead;
  547.     end;
  548. end;
  549.  
  550. procedure TSubscriberList.Sort(CompareMethod: TCompareMethod);
  551. begin
  552.     QuckSort(Self.getHeader^.next, CompareMethod);
  553. end;
  554.  
  555. class procedure TSubscriberList.QuckSort(var headRef: TSubscriberPointer; CompareMethod: TCompareMethod);
  556. var
  557.     Tail: TSubscriberPointer;
  558. begin
  559.     Tail := getTail(headRef);
  560.     headRef := quickSortRecur(headRef, Tail, CompareMethod);
  561. end;
  562.  
  563. end.
  564.  
  565. unit ReadUnit;
  566.  
  567. interface
  568.  
  569. uses
  570.     System.SysUtils, ListUnit, EditUnit, DateUtils;
  571.  
  572. const
  573.     PathToFile = 'C:\t\SubscribersFile.bin';
  574.     FILE_NAME = 'SubscribersFile.bin';
  575.     DELETER: ansichar = '/';
  576.     START_SUBSCRIBER_OFFSET: LongWord = 0;
  577.  
  578. type
  579.     TBinaryFile = file of byte;
  580.  
  581.     procedure readSubscribers(var RequiredSubscriber: TRequiredSubscriber);
  582.     function getSubscriber(Index: longWord; var DateString: string): TSubscriber;
  583.     function isEqual(RequiredString: string; var CurrentArray: array of AnsiChar): boolean;
  584.     function isExist(var RequiredSubscriber: TRequiredSubscriber; var SameSubscriberIndex: integer): Boolean;
  585.     function isFileEmpty(): Boolean;
  586.     function dateArrayToString(var DateOfPayArray: TDateOfPay): string;
  587.     function dateToNumber(var DateOfPayArray: TDateOfPay): TNumberOfdays;
  588.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  589.                                       var TelephoneNumberArray: TTelephoneNumber): boolean; overload;
  590.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  591.                                       var SurnameArray: TSurname): boolean; overload;
  592.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  593.                                       var NameArray: TName): boolean; overload;
  594.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  595.                                       var FathernameArray: TPatronymic): boolean; overload;
  596.     function isRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  597.                                       var CityArray: TCity): boolean; overload;
  598.     function isRequiredSubscriber(var SourceFile: TBinaryFile; var TelephoneNumberArray: TTelephoneNumber;
  599.                                 var SurnameArray: TSurname; var NameArray: TName;
  600.                                   var PatromynicArray: TPatronymic; var CityArray: TCity;
  601.                                   var RequiredSubscriber: TRequiredSubscriber): boolean;
  602.  
  603. implementation
  604.  
  605. function dateArrayToString(var DateOfPayArray: TDateOfPay): string;
  606. begin
  607.     Result := copy(DateOfPayArray, 1, 2) + '.' + copy(DateOfPayArray, 3, 2) + '.' + copy(DateOfPayArray, 5, 4);
  608. end;
  609.  
  610. function dateToNumber(var DateOfPayArray: TDateOfPay): TNumberOfdays;
  611. var
  612.     NumberOfDaysLeft: integer;
  613.     WritenTime, NowTime: TDateTime;
  614.     StringTime: string;
  615.     Difference: TNumberOfDays;
  616.     DayDifferece: TNumberOfDays;
  617.     ComparisonResult: integer;
  618. begin
  619.     StringTime := dateArrayToString(DateOfPayArray);
  620.     WritenTime := strToDate(StringTime);
  621.     NowTime := Now();
  622.     ComparisonResult := compareDate(WritenTime, NowTime);
  623.     DayDifferece := daysBetween(WritenTime, NowTime);
  624.     Difference := DayDifferece * ComparisonResult;
  625.     Result := Difference;
  626. end;
  627.  
  628. procedure readSubscribers(var RequiredSubscriber: TRequiredSubscriber);
  629. var
  630.     SourceFile: TBinaryFile;
  631.     TelephoneNumberArray: TTelephoneNumber;
  632.     SurnameArray: TSurname;
  633.     NameArray: TName;
  634.     PatromynicArray: TPatronymic;
  635.     CityArray: TCity;
  636.     DateofPayArray: TDateOfPay;
  637.     Number: TNumber;
  638.     CurrentOffset, Offset: integer;
  639.     OneByte: ansichar;
  640.     NumberOfDays: longWord;
  641. begin
  642.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  643.     reset(SourceFile);
  644.     Offset := START_SUBSCRIBER_OFFSET;
  645.     Seek(SourceFile, Offset);
  646.     while not EOF(SourceFile) do
  647.     begin
  648.         blockRead(SourceFile, OneByte, 1);
  649.         if OneByte <> DELETER then
  650.         begin
  651.             Seek(SourceFile, Offset);
  652.             blockRead(SourceFile, Number, NUMBER_LENGTH);
  653.             if isRequiredSubscriber(SourceFile, TelephoneNumberArray,
  654.               SurnameArray, NameArray, PatromynicArray, CityArray,
  655.               RequiredSubscriber) then
  656.             begin
  657.                 blockRead(SourceFile, DateOfPayArray, DATE_OF_PAY_LENGTH);
  658.                 NumberOfDays := dateToNumber(DateOfPayArray);
  659.                 SubscriberList.add(TelephoneNumberArray, SurnameArray,
  660.                   NameArray, PatromynicArray, CityArray, NumberOfDays, Number);
  661.             end;
  662.         end;
  663.         Offset := Offset + RECORD_SIZE;
  664.         Seek(SourceFile, Offset);
  665.     end;
  666.     close(SourceFile);
  667. end;
  668.  
  669. function getSubscriber(Index: longWord; var DateString: string): TSubscriber;
  670. var
  671.     SourceFile: TBinaryFile;
  672.     Offset: integer;
  673.     CurrentSubscriber: TSubscriber;
  674.     DateOfPayArray: TDateOfPay;
  675.     NumberOfDays: longWord;
  676. begin
  677.      assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  678.      reset(SourceFile);
  679.      Offset := START_SUBSCRIBER_OFFSET + RECORD_SIZE * Index + NUMBER_LENGTH;
  680.      Seek(SourceFile, Offset);
  681.      blockRead(SourceFile, CurrentSubscriber.telephoneNumber, TELEPHONE_NUMBER_LENGTH);
  682.      blockRead(SourceFile, CurrentSubscriber.surname, SURNAME_LENGTH);
  683.      blockRead(SourceFile, CurrentSubscriber.name, NAME_LENGTH);
  684.      blockRead(SourceFile, CurrentSubscriber.patronymic, PATRONYMIC_LENGTH);
  685.      blockRead(SourceFile, CurrentSubscriber.city, CITY_LENGTH);
  686.      blockRead(SourceFile, DateOfPayArray, DATE_OF_PAY_LENGTH);
  687.      DateString := dateArrayToString(DateOfPayArray);
  688.      close(SourceFile);
  689.      Result := CurrentSubscriber;
  690. end;
  691.  
  692. function isExist(var RequiredSubscriber: TRequiredSubscriber; var SameSubscriberIndex: integer): boolean;
  693. var
  694.     IsExist: boolean;
  695.     SourceFile: TBinaryFile;
  696.     TelephoneNumberArray: TTelephoneNumber;
  697.     SurnameArray: TSurname;
  698.     NameArray: TName;
  699.     PatromynicArray: TPatronymic;
  700.     CityArray: TCity;
  701.     DateofPayArray: TDateOfPay;
  702.     Number: TNumber;
  703.     CurrentOffset, Offset: integer;
  704.     OneByte: ansichar;
  705. begin
  706.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  707.     reset(SourceFile);
  708.     Offset := START_SUBSCRIBER_OFFSET;
  709.     Seek(SourceFile, Offset);
  710.     IsExist := false;
  711.     while (not EOF(SourceFile)) and (not IsExist) do
  712.     begin
  713.         blockRead(SourceFile, OneByte, 1);
  714.         if OneByte <> DELETER then
  715.         begin
  716.             Seek(SourceFile, Offset);
  717.             blockRead(SourceFile, Number, NUMBER_LENGTH);
  718.               if isRequiredSubscriber(SourceFile, TelephoneNumberArray,
  719.                         SurnameArray, NameArray, PatromynicArray, CityArray, RequiredSubscriber) then
  720.               begin
  721.                   IsExist := true;
  722.                   SameSubscriberIndex := Number;
  723.               end;
  724.         end;
  725.         Offset := Offset + RECORD_SIZE;
  726.         Seek(SourceFile, Offset);
  727.     end;
  728.     close(SourceFile);
  729.     Result := IsExist;
  730. end;
  731.  
  732. function isRequiredSubscriber(var SourceFile: TBinaryFile; var TelephoneNumberArray: TTelephoneNumber;
  733.                                 var SurnameArray: TSurname; var NameArray: TName;
  734.                                   var PatromynicArray: TPatronymic; var CityArray: TCity;
  735.                                   var RequiredSubscriber: TRequiredSubscriber): boolean;
  736. begin
  737.     Result := isRequiredData(SourceFile, RequiredSubscriber.telephoneNumber, TelephoneNumberArray)
  738.               and isRequiredData(SourceFile, RequiredSubscriber.surname, SurnameArray)
  739.               and isRequiredData(SourceFile, RequiredSubscriber.name, NameArray)
  740.               and isRequiredData(SourceFile, RequiredSubscriber.patronymic, PatromynicArray)
  741.               and isRequiredData(SourceFile, RequiredSubscriber.city, CityArray);
  742. end;
  743.  
  744. function isFileEmpty(): Boolean;
  745. var
  746.     SourceFile: TBinaryFile;
  747.     IsEmpty: boolean;
  748.     SizeOfFile: integer;
  749. begin
  750.     assign(SourceFile, getCurrentDir + '\' + FILE_NAME);
  751.     Reset(SourceFile);
  752.     SizeOfFile := FileSize(SourceFile);
  753.     close(SourceFile);
  754.     Result := (SizeOfFile = 0);
  755. end;
  756.  
  757. function isEqual(RequiredString: string; var CurrentArray: array of AnsiChar): Boolean;
  758. var
  759.     IsSame: boolean;
  760.     i: integer;
  761. begin
  762.     IsSame := true;
  763.     i := 1;
  764.     while IsSame and (i <= length(RequiredString)) do
  765.         if (RequiredString[i] <> char(CurrentArray[i - 1])) then
  766.             IsSame := false
  767.         else
  768.             inc(i);
  769.     Result := IsSame;
  770. end;
  771.  
  772. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  773.                                           var TelephoneNumberArray: TTelephoneNumber): boolean;
  774. var
  775.     IsRequiredData: boolean;
  776. begin
  777.     blockRead(SourceFile, TelephoneNumberArray, TELEPHONE_NUMBER_LENGTH);
  778.     Result := isEqual(RequiredString, TelephoneNumberArray);
  779. end;
  780.  
  781. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  782.                                           var SurnameArray: TSurname): boolean;
  783. var
  784.     IsRequiredData: boolean;
  785. begin
  786.     blockRead(SourceFile, SurnameArray, SURNAME_LENGTH);
  787.     Result := isEqual(RequiredString, SurnameArray);
  788. end;
  789.  
  790. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  791.                                           var NameArray: TName): boolean;
  792. var
  793.     IsRequiredData: boolean;
  794. begin
  795.     blockRead(SourceFile, NameArray, NAME_LENGTH);
  796.     Result := isEqual(RequiredString, NameArray);
  797. end;
  798.  
  799. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  800.                                           var FathernameArray: TPatronymic): boolean;
  801. var
  802.     IsRequiredData: boolean;
  803. begin
  804.     blockRead(SourceFile, FathernameArray, PATRONYMIC_LENGTH);
  805.     Result := isEqual(RequiredString, FathernameArray);
  806. end;
  807.  
  808. function IsRequiredData(var SourceFile: TBinaryFile; var RequiredString: string;
  809.                                           var CityArray: TCity): boolean;
  810. var
  811.     IsRequiredData: boolean;
  812. begin
  813.     blockRead(SourceFile, CityArray, CITY_LENGTH);
  814.     Result := isEqual(RequiredString, CityArray);
  815. end;
  816.  
  817. end.
  818.  
  819. unit CorrectUnit;
  820.  
  821. interface
  822.  
  823. uses
  824.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  825.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.Samples.Spin, DateUtils, AddUnit, EditUnit;
  826.  
  827. type
  828.   TCorrectForm = class(TForm)
  829.     NameLabel: TLabel;
  830.     SurnameLabel: TLabel;
  831.     PatronumicLabel: TLabel;
  832.     CityLabel: TLabel;
  833.     TelephoneLabel: TLabel;
  834.     TelephoneEdit: TEdit;
  835.     NameEdit: TEdit;
  836.     SurnameEdit: TEdit;
  837.     PatronymicEdit: TEdit;
  838.     CItyEdit: TEdit;
  839.     TaskLabel: TLabel;
  840.     SaveButton: TButton;
  841.     MainMenu: TMainMenu;
  842.     InstructionMenu: TMenuItem;
  843.     PayLabel: TLabel;
  844.     ResetButton: TButton;
  845.     DateLabel: TLabel;
  846.     DateOfPayLabel: TLabel;
  847.     PaySpinEdit: TSpinEdit;
  848.     SuccessLabel: TLabel;
  849.     WrongDataLabel: TLabel;
  850.     UpdateMenu: TMenuItem;
  851.     SubscriberExistsLabel: TLabel;
  852.     procedure ResetButtonClick(Sender: TObject);
  853.     procedure TurnLabelsOff();
  854.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  855.     procedure FormShow(Sender: TObject);
  856.     procedure SaveButtonClick(Sender: TObject);
  857.     procedure showSavedInfo();
  858.     procedure UpdateMenuClick(Sender: TObject);
  859.     procedure deleteSpaces();
  860.     procedure InstructionMenuClick(Sender: TObject);
  861.     procedure TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  862.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  863.     procedure TextEditKeyPress(Sender: TObject; var Key: Char);
  864.     function areEditsCorrect(): boolean;
  865.     procedure SomeEditChange(Sender: TObject);
  866.   private
  867.     { Private declarations }
  868.   public
  869.     { Public declarations }
  870.   end;
  871.  
  872. var
  873.   CorrectForm: TCorrectForm;
  874.  
  875. implementation
  876.  
  877. {$R *.dfm}
  878.  
  879. uses
  880.     ReadUnit, WriteUnit, ListUnit;
  881.  
  882.  
  883. procedure TCorrectForm.ResetButtonClick(Sender: TObject);
  884. var
  885.     TelephoneNumber: TTelephoneNumber;
  886.     Surname: TSurname;
  887.     Name: TName;
  888.     Patronymic: TPatronymic;
  889.     City: TCity;
  890.     DateofPay: TDateOfPay;
  891. begin
  892.     DateOfPayLabel.caption := dateToStr(Now);
  893.     PaySpinEdit.Value := 0;
  894.     turnLabelsOff();
  895. end;
  896.  
  897. function TCorrectForm.areEditsCorrect(): boolean;
  898.  
  899. begin
  900.     Result := (EditForm.IsCorrectNumberData(TelephoneEdit) and EditForm.IsCorrectTextData(SurnameEdit) and
  901.                EditForm.IsCorrectTextData(NameEdit) and EditForm.IsCorrectTextData(PatronymicEdit) and
  902.                EditForm.IsCorrectTextData(CityEdit) and
  903.                AddForm.areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, PatronymicEdit, CityEdit));
  904. end;
  905.  
  906. procedure TCorrectForm.SaveButtonClick(Sender: TObject);
  907. var
  908.     TelephoneNumber: TTelephoneNumber;
  909.     Surname: TSurname;
  910.     Name: TName;
  911.     Patronymic: TPatronymic;
  912.     City: TCity;
  913.     DateofPay: TDateOfPay;
  914.     SameSubscriberIndex: integer;
  915.     RequiredSubscriber: TRequiredSubscriber;
  916. begin
  917.     SameSubscriberIndex := -1;
  918.     TelephoneNumber := toTelephoneNumber(TelephoneEdit.text);
  919.     Surname := toSurname(SurnameEdit.Text);
  920.     Name := toName(NameEdit.Text);
  921.     Patronymic := toPatronymic(PatronymicEdit.Text);
  922.     City := toCity(CityEdit.Text);
  923.     DateOfPay := toDateOfPay(strToDate(DateOfPayLabel.Caption), PaySpinEdit.Value);
  924.     PaySpinEdit.Value := 0;
  925.     EditForm.getRequiredSubscriber(RequiredSubscriber,  TelephoneEdit.text, SurnameEdit.text, NameEdit.text,
  926.                                 PatronymicEdit.text, CityEdit.text);
  927.     if isExist(RequiredSubscriber, SameSubscriberIndex)
  928.         and (not(SubscriberIndex = SameSubscriberIndex)) then
  929.         SubscriberExistsLabel.Visible := true
  930.     else
  931.     begin
  932.         if (not areEditsCorrect()) then
  933.             WrongDataLabel.Visible := true
  934.         else
  935.         begin
  936.             write(SubscriberIndex, TelephoneNumber, Surname, Name, Patronymic, City,
  937.                   DateofPay);
  938.             showSavedInfo();
  939.             SuccessLabel.Visible := true;
  940.         end;
  941.     end;
  942. end;
  943.  
  944. procedure TCorrectForm.FormClose(Sender: TObject; var Action: TCloseAction);
  945. begin
  946.     EditForm.enabled := true;
  947.     PaySpinEdit.value := 0;
  948. end;
  949.  
  950. procedure TCorrectForm.FormKeyPress(Sender: TObject; var Key: Char);
  951. begin
  952.     if key = #27 then
  953.         AddForm.Close()
  954.     else
  955.         if Key = #13 then
  956.             SaveButtonClick(Sender);
  957. end;
  958.  
  959. procedure TCorrectForm.FormShow(Sender: TObject);
  960. begin
  961.     showSavedInfo();
  962. end;
  963.  
  964. procedure TCorrectForm.InstructionMenuClick(Sender: TObject);
  965. begin
  966.     MessageDlg('This is the correction window. Here you can change current subscriber''s data.'
  967.                             + #13#10 + 'After clicking "Save" you will see label with result:'
  968.                             + #13#10 + '1. "Changes saved" - you succesfully changed.'
  969.                             + #13#10 + '2. "Subscriber exists" - subscriber with this data already exists.'
  970.                             + #13#10 + '3. "Wront input" - some fileds are filled incorrectly.' + #13#10 +
  971.                             'Right input:' + #13#10 +
  972.                             'a) Telephone number field: first char - "+" or digit and next are digits; length = 13;'
  973.                             + #13#10 + 'b) Text fields: first char - big letter and next are small letters. Length:'
  974.                             + #13#10 + 'City -11, Surname - 14, Name - 11, Patronymic - 14.' + #13#10
  975.                             + #13#10 + 'Field can not be empty.' + #13#10
  976.                             + #13#10 + 'In the field "Payment" you should input the amount of money paid'
  977.                             + #13#10 + 'Use menu button "Update" or press "ctrl + r" to show saved data;'
  978.                             + #13#10 + 'Use button "Reset payment" to change payment day for today''s date;'
  979.                             + #13#10 + #13#10 + 'Press "ctrl + i" to open instruction;'
  980.                             + #13#10 + 'Press "enter" to save changes;' +
  981.                             #13#10 +  'Press "esc" to go back to edit widnow.', MtInformation, [mbOk], 0);
  982. end;
  983.  
  984. procedure TCorrectForm.deleteSpaces();
  985. var
  986.     Edit: TEdit;
  987.     i: integer;
  988.     BufferString: string;
  989. begin
  990.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  991.     begin
  992.         BufferString := Edit.text;
  993.         Edit.text := '';
  994.         for i := 1 to length(BufferString) do
  995.             if BufferString[i] <> ' ' then
  996.                 Edit.text := Edit.text + BufferString[i];
  997.     end;
  998. end;
  999.  
  1000. procedure TCorrectForm.showSavedInfo();
  1001. var
  1002.     CurrentSubscriber: TSubscriber;
  1003.     DateString: string;
  1004. begin
  1005.     CurrentSubscriber := getSubscriber(SubscriberIndex, DateString);
  1006.     TelephoneEdit.text := CurrentSubscriber.telephoneNumber;
  1007.     SurnameEdit.text := CurrentSubscriber.surname;
  1008.     NameEdit.text := CurrentSubscriber.name;
  1009.     PatronymicEdit.text := CurrentSubscriber.patronymic;
  1010.     CityEdit.text := CurrentSubscriber.city;
  1011.     deleteSpaces;
  1012.     DateOfPayLabel.caption := DateString;
  1013.     PaySpinEdit.Value := 0;
  1014.     turnLabelsOff();
  1015. end;
  1016.  
  1017. procedure TCorrectForm.TextEditKeyPress(Sender: TObject; var Key: Char);
  1018. begin
  1019.     AddForm.TextEditKeyPress(Sender, Key);
  1020. end;
  1021.  
  1022. procedure TCorrectForm.SomeEditChange(Sender: TObject);
  1023. begin
  1024.     turnLabelsOff();
  1025. end;
  1026.  
  1027. procedure TCorrectForm.TelephoneEditKeyPress(Sender: TObject; var Key: Char);
  1028. begin
  1029.     AddForm.TelephoneKeyPress(Sender, Key);
  1030. end;
  1031.  
  1032. procedure TCorrectForm.TurnLabelsOff();
  1033. begin
  1034.     SuccessLabel.visible := false;
  1035.     WrongDataLabel.visible := false;
  1036.     SubscriberExistsLabel.visible := false;
  1037. end;
  1038.  
  1039. procedure TCorrectForm.UpdateMenuClick(Sender: TObject);
  1040. begin
  1041.     showSavedInfo();
  1042. end;
  1043.  
  1044. end.
  1045.  
  1046. unit AddUnit;
  1047.  
  1048. interface
  1049.  
  1050. uses
  1051.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  1052.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.Samples.Spin, EditUnit;
  1053.  
  1054. type
  1055.   TAddForm = class(TForm)
  1056.     NameLabel: TLabel;
  1057.     SurnameLabel: TLabel;
  1058.     PatronymicLabel: TLabel;
  1059.     CityLabel: TLabel;
  1060.     DateLabel: TLabel;
  1061.     TelephoneLabel: TLabel;
  1062.     TelephoneEdit: TEdit;
  1063.     NameEdit: TEdit;
  1064.     SurnameEdit: TEdit;
  1065.     PatronymicEdit: TEdit;
  1066.     CItyEdit: TEdit;
  1067.     TaskLabel: TLabel;
  1068.     AddButton: TButton;
  1069.     MainMenu: TMainMenu;
  1070.     InstructionMenu: TMenuItem;
  1071.     SubscriberAddedLabel: TLabel;
  1072.     PaymentEdit: TSpinEdit;
  1073.     WrongDataLabel: TLabel;
  1074.     SubscriberExistsLabel: TLabel;
  1075.     procedure AddButtonClick(Sender: TObject);
  1076.     procedure SomeEditChange(Sender: TObject);
  1077.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  1078.     procedure turnLabelsOff();
  1079.     procedure InstructionMenuClick(Sender: TObject);
  1080.     procedure TextEditKeyPress(Sender: TObject; var Key: Char);
  1081.     procedure TelephoneKeyPress(Sender: TObject; var Key: Char);
  1082.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  1083.     procedure FormShow(Sender: TObject);
  1084.     function areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, FathernameEdit, CityEdit: TEdit): boolean;
  1085.     function areEditsCorrect(): boolean;
  1086.   private
  1087.     { Private declarations }
  1088.   public
  1089.     { Public declarations }
  1090.   end;
  1091.  
  1092. var
  1093.   AddForm: TAddForm;
  1094.  
  1095. implementation
  1096.  
  1097. {$R *.dfm}
  1098.  
  1099. uses
  1100.     ReadUnit, WriteUnit, ListUnit, StartUnit;
  1101.  
  1102. const
  1103.     BIG_LETTERS = ['A'..'Z'];
  1104.     SMALL_LETTERS = ['a'..'z'];
  1105.     DIGITS = ['0'..'9'];
  1106.  
  1107. procedure TAddForm.AddButtonClick(Sender: TObject);
  1108.  
  1109. var
  1110.     TelephoneNumber: TTelephoneNumber;
  1111.     Surname: TSurname;
  1112.     Name: TName;
  1113.     Patronymic: TPatronymic;
  1114.     City: TCity;
  1115.     DateofPay: TDateOfPay;
  1116.     Buff: integer;
  1117.     SameSubscriberIndex: integer;
  1118.     RequiredSubscriber: TRequiredSubscriber;
  1119. begin
  1120.     TelephoneNumber := toTelephoneNumber(TelephoneEdit.text);
  1121.     Surname := toSurname(SurnameEdit.Text);
  1122.     Name := toName(NameEdit.Text);
  1123.     Patronymic := toPatronymic(PatronymicEdit.Text);
  1124.     City := toCity(CityEdit.Text);
  1125.     buff := PaymentEdit.value;
  1126.     DateOfPay := toDateOfPay(Now, PaymentEdit.value);
  1127.     TurnLabelsOff();
  1128.     EditForm.getRequiredSubscriber(RequiredSubscriber,  TelephoneEdit.text, SurnameEdit.text, NameEdit.text,
  1129.                                 PatronymicEdit.text, CityEdit.text);
  1130.     if isExist(RequiredSubscriber, SameSubscriberIndex) then
  1131.         SubscriberExistsLabel.Visible := true
  1132.     else
  1133.     begin
  1134.         if not areEditsCorrect() then
  1135.             WrongDataLabel.Visible := true
  1136.         else
  1137.         begin
  1138.             write(TelephoneNumber, Surname, Name, Patronymic, City, DateofPay);
  1139.             SubscriberAddedLabel.Visible := true;
  1140.         end;
  1141.     end;
  1142. end;
  1143.  
  1144.  
  1145. function TAddForm.areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, FathernameEdit, CityEdit: TEdit): boolean;
  1146.  
  1147. begin
  1148.     Result := ((TelephoneEdit.text <> '') and (SurnameEdit.text <> '') and (FathernameEdit.text <> '')
  1149.                 and (NameEdit.text <> '') and (CityEdit.text <> ''));
  1150. end;
  1151.  
  1152. function TAddForm.areEditsCorrect(): boolean;
  1153.  
  1154. begin
  1155.     Result := (EditForm.IsCorrectNumberData(TelephoneEdit) and EditForm.IsCorrectTextData(SurnameEdit) and
  1156.                EditForm.IsCorrectTextData(NameEdit) and EditForm.IsCorrectTextData(PatronymicEdit) and
  1157.                EditForm.IsCorrectTextData(CityEdit) and
  1158.                areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, PatronymicEdit, CityEdit));
  1159. end;
  1160.  
  1161. procedure TAddForm.FormClose(Sender: TObject; var Action: TCloseAction);
  1162.  
  1163. var
  1164.     Edit: TEdit;
  1165.  
  1166. begin
  1167.     EditForm.enabled := true;
  1168.     TurnLabelsOff();
  1169.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  1170.         Edit.text := '';
  1171.     PaymentEdit.value := 0;
  1172. end;
  1173.  
  1174. procedure TAddForm.FormKeyPress(Sender: TObject; var Key: Char);
  1175. begin
  1176.     if key = #27 then
  1177.         AddForm.Close()
  1178.     else
  1179.         if Key = #13 then
  1180.             AddButtonClick(Sender);
  1181. end;
  1182.  
  1183. procedure TAddForm.FormShow(Sender: TObject);
  1184. var
  1185.     Edit: TEdit;
  1186. begin
  1187.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  1188.         Edit.text := '';
  1189. end;
  1190.  
  1191. procedure TAddForm.InstructionMenuClick(Sender: TObject);
  1192. begin
  1193.     MessageDlg('This is the add window. Here you can add a new subscriber to database.' + #13#10
  1194.                             + #13#10 + 'After clicking "add" you will see label with result:'
  1195.                             + #13#10 + '1. "Subscriber added" - you succesfully added a new person.'
  1196.                             + #13#10 + '2. "Subscriber exists" - subscriber with this data already exists.'
  1197.                             + #13#10 + '3. "Wront input" - some fileds are filled incorrectly.' + #13#10
  1198.                             + 'Right input:' + #13#10 +
  1199.                             'a) Telephone number field: first char - "+" or digit and next are digits; length = 13;'
  1200.                             + #13#10 + 'b) Text fields: first char - big letter and next are small letters. Length:'
  1201.                             + #13#10 + 'City - 11, Surname - 14, Name - 11, Patronymic - 14.'
  1202.                             + #13#10 + 'Field can not be empty.' + #13#10
  1203.                             + #13#10 + 'In the field "Payment" you should input the amount of money paid'
  1204.                             + #13#10 + #13#10 + 'Press "ctrl + i" to open instruction;'
  1205.                             + #13#10 + 'Press "enter" to add subscriber;'
  1206.                             + #13#10 +  'Press "esc" to go back to edit widnow.', MtInformation, [mbOk], 0);
  1207. end;
  1208.  
  1209. procedure TAddForm.SomeEditChange(Sender: TObject);
  1210. begin
  1211.     turnLabelsOff();
  1212. end;
  1213.  
  1214. procedure TAddForm.TextEditKeyPress(Sender: TObject; var Key: Char);
  1215. begin
  1216.     if (Key <> #08) then
  1217.     begin
  1218.         if length((Sender as TEdit).text) = 0 then
  1219.         begin
  1220.             if not (Key in BIG_LETTERS) then
  1221.                 Key := #0
  1222.         end
  1223.         else if not(Key in SMALL_LETTERS) then
  1224.             Key := #0;
  1225.     end;
  1226. end;
  1227.  
  1228. procedure TAddForm.TelephoneKeyPress(Sender: TObject; var Key: Char);
  1229. begin
  1230.     if (Key <> #08) then
  1231.     begin
  1232.         if length((Sender as TEdit).text) = 0 then
  1233.         begin
  1234.             if ((not(Key in DIGITS)) and (Key <> '+')) then
  1235.                 Key := #0
  1236.         end
  1237.         else if not(Key in DIGITS) then
  1238.             Key := #0;
  1239.     end;
  1240. end;
  1241.  
  1242. procedure TAddForm.TurnLabelsOff();
  1243. begin
  1244.     SubscriberAddedLabel.Visible := false;
  1245.     SubscriberExistsLabel.Visible := false;
  1246.     WrongDataLabel.Visible := false;
  1247. end;
  1248.  
  1249. end.
  1250.  
  1251. unit AddUnit;
  1252.  
  1253. interface
  1254.  
  1255. uses
  1256.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  1257.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.Samples.Spin, EditUnit;
  1258.  
  1259. type
  1260.   TAddForm = class(TForm)
  1261.     NameLabel: TLabel;
  1262.     SurnameLabel: TLabel;
  1263.     PatronymicLabel: TLabel;
  1264.     CityLabel: TLabel;
  1265.     DateLabel: TLabel;
  1266.     TelephoneLabel: TLabel;
  1267.     TelephoneEdit: TEdit;
  1268.     NameEdit: TEdit;
  1269.     SurnameEdit: TEdit;
  1270.     PatronymicEdit: TEdit;
  1271.     CItyEdit: TEdit;
  1272.     TaskLabel: TLabel;
  1273.     AddButton: TButton;
  1274.     MainMenu: TMainMenu;
  1275.     InstructionMenu: TMenuItem;
  1276.     SubscriberAddedLabel: TLabel;
  1277.     PaymentEdit: TSpinEdit;
  1278.     WrongDataLabel: TLabel;
  1279.     SubscriberExistsLabel: TLabel;
  1280.     procedure AddButtonClick(Sender: TObject);
  1281.     procedure SomeEditChange(Sender: TObject);
  1282.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  1283.     procedure turnLabelsOff();
  1284.     procedure InstructionMenuClick(Sender: TObject);
  1285.     procedure TextEditKeyPress(Sender: TObject; var Key: Char);
  1286.     procedure TelephoneKeyPress(Sender: TObject; var Key: Char);
  1287.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  1288.     procedure FormShow(Sender: TObject);
  1289.     function areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, FathernameEdit, CityEdit: TEdit): boolean;
  1290.     function areEditsCorrect(): boolean;
  1291.   private
  1292.     { Private declarations }
  1293.   public
  1294.     { Public declarations }
  1295.   end;
  1296.  
  1297. var
  1298.   AddForm: TAddForm;
  1299.  
  1300. implementation
  1301.  
  1302. {$R *.dfm}
  1303.  
  1304. uses
  1305.     ReadUnit, WriteUnit, ListUnit, StartUnit;
  1306.  
  1307. const
  1308.     BIG_LETTERS = ['A'..'Z'];
  1309.     SMALL_LETTERS = ['a'..'z'];
  1310.     DIGITS = ['0'..'9'];
  1311.  
  1312. procedure TAddForm.AddButtonClick(Sender: TObject);
  1313.  
  1314. var
  1315.     TelephoneNumber: TTelephoneNumber;
  1316.     Surname: TSurname;
  1317.     Name: TName;
  1318.     Patronymic: TPatronymic;
  1319.     City: TCity;
  1320.     DateofPay: TDateOfPay;
  1321.     Buff: integer;
  1322.     SameSubscriberIndex: integer;
  1323.     RequiredSubscriber: TRequiredSubscriber;
  1324. begin
  1325.     TelephoneNumber := toTelephoneNumber(TelephoneEdit.text);
  1326.     Surname := toSurname(SurnameEdit.Text);
  1327.     Name := toName(NameEdit.Text);
  1328.     Patronymic := toPatronymic(PatronymicEdit.Text);
  1329.     City := toCity(CityEdit.Text);
  1330.     buff := PaymentEdit.value;
  1331.     DateOfPay := toDateOfPay(Now, PaymentEdit.value);
  1332.     TurnLabelsOff();
  1333.     EditForm.getRequiredSubscriber(RequiredSubscriber,  TelephoneEdit.text, SurnameEdit.text, NameEdit.text,
  1334.                                 PatronymicEdit.text, CityEdit.text);
  1335.     if isExist(RequiredSubscriber, SameSubscriberIndex) then
  1336.         SubscriberExistsLabel.Visible := true
  1337.     else
  1338.     begin
  1339.         if not areEditsCorrect() then
  1340.             WrongDataLabel.Visible := true
  1341.         else
  1342.         begin
  1343.             write(TelephoneNumber, Surname, Name, Patronymic, City, DateofPay);
  1344.             SubscriberAddedLabel.Visible := true;
  1345.         end;
  1346.     end;
  1347. end;
  1348.  
  1349.  
  1350. function TAddForm.areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, FathernameEdit, CityEdit: TEdit): boolean;
  1351.  
  1352. begin
  1353.     Result := ((TelephoneEdit.text <> '') and (SurnameEdit.text <> '') and (FathernameEdit.text <> '')
  1354.                 and (NameEdit.text <> '') and (CityEdit.text <> ''));
  1355. end;
  1356.  
  1357. function TAddForm.areEditsCorrect(): boolean;
  1358.  
  1359. begin
  1360.     Result := (EditForm.IsCorrectNumberData(TelephoneEdit) and EditForm.IsCorrectTextData(SurnameEdit) and
  1361.                EditForm.IsCorrectTextData(NameEdit) and EditForm.IsCorrectTextData(PatronymicEdit) and
  1362.                EditForm.IsCorrectTextData(CityEdit) and
  1363.                areEditsFilled(TelephoneEdit, SurnameEdit, NameEdit, PatronymicEdit, CityEdit));
  1364. end;
  1365.  
  1366. procedure TAddForm.FormClose(Sender: TObject; var Action: TCloseAction);
  1367.  
  1368. var
  1369.     Edit: TEdit;
  1370.  
  1371. begin
  1372.     EditForm.enabled := true;
  1373.     TurnLabelsOff();
  1374.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  1375.         Edit.text := '';
  1376.     PaymentEdit.value := 0;
  1377. end;
  1378.  
  1379. procedure TAddForm.FormKeyPress(Sender: TObject; var Key: Char);
  1380. begin
  1381.     if key = #27 then
  1382.         AddForm.Close()
  1383.     else
  1384.         if Key = #13 then
  1385.             AddButtonClick(Sender);
  1386. end;
  1387.  
  1388. procedure TAddForm.FormShow(Sender: TObject);
  1389. var
  1390.     Edit: TEdit;
  1391. begin
  1392.     for Edit in [SurnameEdit, NameEdit, PatronymicEdit, TelephoneEdit, CityEdit] do
  1393.         Edit.text := '';
  1394. end;
  1395.  
  1396. procedure TAddForm.InstructionMenuClick(Sender: TObject);
  1397. begin
  1398.     MessageDlg('This is the add window. Here you can add a new subscriber to database.' + #13#10
  1399.                             + #13#10 + 'After clicking "add" you will see label with result:'
  1400.                             + #13#10 + '1. "Subscriber added" - you succesfully added a new person.'
  1401.                             + #13#10 + '2. "Subscriber exists" - subscriber with this data already exists.'
  1402.                             + #13#10 + '3. "Wront input" - some fileds are filled incorrectly.' + #13#10
  1403.                             + 'Right input:' + #13#10 +
  1404.                             'a) Telephone number field: first char - "+" or digit and next are digits; length = 13;'
  1405.                             + #13#10 + 'b) Text fields: first char - big letter and next are small letters. Length:'
  1406.                             + #13#10 + 'City - 11, Surname - 14, Name - 11, Patronymic - 14.'
  1407.                             + #13#10 + 'Field can not be empty.' + #13#10
  1408.                             + #13#10 + 'In the field "Payment" you should input the amount of money paid'
  1409.                             + #13#10 + #13#10 + 'Press "ctrl + i" to open instruction;'
  1410.                             + #13#10 + 'Press "enter" to add subscriber;'
  1411.                             + #13#10 +  'Press "esc" to go back to edit widnow.', MtInformation, [mbOk], 0);
  1412. end;
  1413.  
  1414. procedure TAddForm.SomeEditChange(Sender: TObject);
  1415. begin
  1416.     turnLabelsOff();
  1417. end;
  1418.  
  1419. procedure TAddForm.TextEditKeyPress(Sender: TObject; var Key: Char);
  1420. begin
  1421.     if (Key <> #08) then
  1422.     begin
  1423.         if length((Sender as TEdit).text) = 0 then
  1424.         begin
  1425.             if not (Key in BIG_LETTERS) then
  1426.                 Key := #0
  1427.         end
  1428.         else if not(Key in SMALL_LETTERS) then
  1429.             Key := #0;
  1430.     end;
  1431. end;
  1432.  
  1433. procedure TAddForm.TelephoneKeyPress(Sender: TObject; var Key: Char);
  1434. begin
  1435.     if (Key <> #08) then
  1436.     begin
  1437.         if length((Sender as TEdit).text) = 0 then
  1438.         begin
  1439.             if ((not(Key in DIGITS)) and (Key <> '+')) then
  1440.                 Key := #0
  1441.         end
  1442.         else if not(Key in DIGITS) then
  1443.             Key := #0;
  1444.     end;
  1445. end;
  1446.  
  1447. procedure TAddForm.TurnLabelsOff();
  1448. begin
  1449.     SubscriberAddedLabel.Visible := false;
  1450.     SubscriberExistsLabel.Visible := false;
  1451.     WrongDataLabel.Visible := false;
  1452. end;
  1453.  
  1454. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement