Recent

Author Topic: Convert String To Date catch EConvertError  (Read 5704 times)

krull

  • New Member
  • *
  • Posts: 12
Convert String To Date catch EConvertError
« on: June 07, 2017, 09:12:07 am »
Hello again,

i have a new Program underway. It is a vocabulary tester. In the following procedure witch handles the random generator to find some Words out of the Stringgrid which have the correct Date value. So far so good. But if i run the program it gives me during runtime an EConvertError back, directly at a complex until statement. (line 30,37,46...).

Thanks

Code: Pascal  [Select][+][-]
  1. procedure TForm3.BeginButtonClick(Sender: TObject);
  2. label 3;
  3. var some : TDateTime;
  4. begin
  5.   randomize;
  6.   if (tryStrToDate(FromEdit.Text,some,'.')=false) and not (FromEdit.Text='now') and not (FromEdit.Text='all') then
  7.   begin
  8.     ShowMessage('Incorrect the Date-Time format. Format is DD.MM.YYYY.');
  9.     Goto 3;
  10.   end
  11.   else if (tryStrToDate(ToEdit.Text,some,'.')=false) and not (ToEdit.Text='now') and not (ToEdit.Text='all') then
  12.   begin
  13.     ShowMessage('Incorrect the Date-Time format. Format is DD.MM.YYYY.');
  14.     GoTo 3;
  15.   end;
  16.   if (EngDeuBox.Text='Eng->Deu') then
  17.   begin
  18.     if ((FromEdit.text='all') and (ToEdit.text='all')) or ((FromEdit.text='now') and (ToEdit.text='all')) or ((FromEdit.text='all') and (ToEdit.text='now'))then
  19.     begin
  20.       j:=1+random(Form1.VokabelGrid.RowCount-1);
  21.       WordLbl.Caption:=Form1.VokabelGrid.Cells[0,j];
  22.     end
  23.     else if (FromEdit.Text='now') and (ToEdit.Text='now') then
  24.     begin
  25.     end
  26.     else if (FromEdit.Text='now') and not (ToEdit.Text='now') then
  27.     begin
  28.       repeat
  29.         j:=1+random(Form1.VokabelGrid.RowCount-1);
  30.       until (Date>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(ToEdit.text));
  31.       WordLbl.Caption:=Form1.VokabelGrid.cells[0,j];
  32.     end
  33.     else if not (FromEdit.Text='now') and  (ToEdit.Text='now') then
  34.     begin
  35.       repeat
  36.         j:=1+random(Form1.VokabelGrid.RowCount-1);
  37.       until (Date>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(FromEdit.text));
  38.       WordLbl.Caption:=Form1.VokabelGrid.cells[0,j];
  39.     end
  40.     else if (tryStrToDate(FromEdit.text,some,'.')) and  (tryStrToDate(ToEdit.text,some,'.')) then
  41.     begin
  42.       if (StrToDate(FromEdit.text)>StrToDate(ToEdit.Text))then
  43.       begin
  44.         repeat
  45.           j:=1+random(Form1.VokabelGrid.RowCount-1);
  46.         until (StrToDate(FromEdit.Text)>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(ToEdit.text));
  47.         WordLbl.Caption:=Form1.VokabelGrid.cells[1,j];
  48.       end;
  49.       if(StrToDate(FromEdit.text)<StrToDate(ToEdit.Text))then
  50.       begin
  51.         repeat
  52.           j:=1+random(Form1.VokabelGrid.RowCount-1);
  53.         until (StrToDate(ToEdit.Text)>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(FromEdit.text));
  54.         WordLbl.Caption:=Form1.VokabelGrid.cells[1,j];
  55.       end;
  56.     end;
  57.   end
  58.   else
  59.   begin
  60.     if ((FromEdit.text='all') and (ToEdit.text='all')) or ((FromEdit.text='now') and (ToEdit.text='all')) or ((FromEdit.text='all') and (ToEdit.text='now'))then
  61.     begin
  62.       j:=1+random(Form1.VokabelGrid.RowCount-1);
  63.       WordLbl.Caption:=Form1.VokabelGrid.Cells[1,j];
  64.     end
  65.     else if (FromEdit.Text='now') and (ToEdit.Text='now') then
  66.     begin
  67.     end
  68.     else if (FromEdit.Text='now') and not (ToEdit.Text='now') then
  69.     begin
  70.       repeat
  71.         j:=1+random(Form1.VokabelGrid.RowCount-1);
  72.       until (Date>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(ToEdit.text));
  73.       WordLbl.Caption:=Form1.VokabelGrid.cells[1,j];
  74.     end
  75.     else if not (FromEdit.Text='now') and  (ToEdit.Text='now') then
  76.     begin
  77.       repeat
  78.         j:=1+random(Form1.VokabelGrid.RowCount-1);
  79.       until (Date>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(FromEdit.text));
  80.       WordLbl.Caption:=Form1.VokabelGrid.cells[1,j];
  81.     end
  82.     else if (tryStrToDate(FromEdit.text,some,'.')) and  (tryStrToDate(ToEdit.text,some,'.')) then
  83.     begin
  84.       if (StrToDate(FromEdit.text)>=StrToDate(ToEdit.Text))then
  85.       begin
  86.         repeat
  87.           j:=1+random(Form1.VokabelGrid.RowCount-1);
  88.         until (StrToDate(FromEdit.Text)>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(ToEdit.text));
  89.         WordLbl.Caption:=Form1.VokabelGrid.cells[1,j];
  90.       end;
  91.       if(StrToDate(FromEdit.text))<=(StrToDate(ToEdit.Text))then
  92.       begin
  93.         repeat
  94.           j:=1+random(Form1.VokabelGrid.RowCount-1);
  95.         until (StrToDate(ToEdit.Text)>=StrToDate(Form1.VokabelGrid.Cells[2,j])) and (StrToDate(Form1.VokabelGrid.Cells[2,j])>=StrToDate(FromEdit.text));
  96.         WordLbl.Caption:=Form1.VokabelGrid.cells[1,j];
  97.       end;
  98.     end;
  99.   end;
  100.   GroupBox1.Enabled:=false;
  101.   GroupBox2.Enabled:=true;
  102. 3:
  103. end;
  104.  

Handoko

  • Hero Member
  • *****
  • Posts: 5150
  • My goal: build my own game engine using Lazarus
Re: Convert String To Date catch EConvertError
« Reply #1 on: June 07, 2017, 10:56:32 am »
Hello krull.

Can you please provide more information? What you want to do or maybe some screenshots.

I tried to run the code you provided, but I can't make it works, you did not provide the contents of the VokabelGrid.

It will be much better if you are willing to provide the whole source code. But if for some reasons you are not willing to publicize your project, you can make a test project that shows us the issue. Compress the source code including all the necessary files, except the exe and the lib folder. Zip them and attach it to this forum.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: Convert String To Date catch EConvertError
« Reply #2 on: June 07, 2017, 11:13:28 am »
There is still a strtodate in there that can generate econversionerror.

krull

  • New Member
  • *
  • Posts: 12
Re: Convert String To Date catch EConvertError
« Reply #3 on: June 07, 2017, 11:21:54 am »
O.K. here the whole code espacally in Form3 there are still Building Sites.
Thank you for your help. I think i learn a lot in this Forum.

Thaddy

  • Hero Member
  • *****
  • Posts: 14364
  • Sensorship about opinions does not belong here.
Re: Convert String To Date catch EConvertError
« Reply #4 on: June 07, 2017, 11:26:04 am »
There is still a strtodate in there that can generate econversionerror.

I would be more worried about the randomize call....
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Handoko

  • Hero Member
  • *****
  • Posts: 5150
  • My goal: build my own game engine using Lazarus
Re: Convert String To Date catch EConvertError
« Reply #5 on: June 07, 2017, 12:45:27 pm »
I put this:

Code: Pascal  [Select][+][-]
  1. ShowMessage(Form1.VokabelGrid.Cells[2,j]);

just before the line that causes exception, and the result is an empty string. I enabled range check, but no out of bound error happened. Still testing. But one thing is sure, the code provide bad input for StrToDate. Because:

Code: Pascal  [Select][+][-]
  1. StrToDate('');

will cause exception.

Handoko

  • Hero Member
  • *****
  • Posts: 5150
  • My goal: build my own game engine using Lazarus
Re: Convert String To Date catch EConvertError
« Reply #6 on: June 07, 2017, 01:01:28 pm »
More tests and I found that VokabelGrid.RowCount did not 'really' return the correct row count. I used this code:

Code: Pascal  [Select][+][-]
  1.   for i := 0 to Form1.VokabelGrid.RowCount-1 do
  2.     ShowMessage(Form1.VokabelGrid.Cells[2,i]);

By using the code above, I got the last row with empty cells.

After some inspections I think this is the culprit:

Code: Pascal  [Select][+][-]
  1. // on TForm1.OnCreate
  2.       VokabelGrid.Cells[0,j]:=first;
  3.       VokabelGrid.Cells[1,j]:=second;
  4.       VokabelGrid.Cells[2,j]:=third;
  5.       VokabelGrid.InsertColRow(false,j+1);
  6.       inc(j);

It inserts a row after cells update. It is wrong, it should be insert a row when needed.

krull

  • New Member
  • *
  • Posts: 12
Re: Convert String To Date catch EConvertError
« Reply #7 on: June 07, 2017, 03:18:11 pm »
Good I try to eleminate this additional row. But with this are ten other faults opening.
For example in Form2 the entry for new Words (line 87) is throwing with GridExeptions.
And I don't find correct implementation.

Thaddy

  • Hero Member
  • *****
  • Posts: 14364
  • Sensorship about opinions does not belong here.
Re: Convert String To Date catch EConvertError
« Reply #8 on: June 07, 2017, 03:36:41 pm »
You can also validate first. By using DateUtils.IsValidDate.... And get rid of the randomize in that spot.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Handoko

  • Hero Member
  • *****
  • Posts: 5150
  • My goal: build my own game engine using Lazarus
Re: Convert String To Date catch EConvertError
« Reply #9 on: June 07, 2017, 04:16:46 pm »
I tested the code again, sorry it has too much bugs.

You tried to add a new record after update an item. That is the issue in TForm2.Button1Click. The correct flow should be like this:

01. User provide a new item
02. Check if the item already existed
03. If yes then show an error and exit (I noticed you use goto 1)
04. If no then continue the the flow below
05. Add a new record
06. Update/save the record using the values provided by the user

What you did are not correct:
05. Update/save the record
06. Add a new record (to be used for future usage)

I want to try to fix the bugs, but it is easier to write from a fresh start.

Your code cannot run properly on countries outside yours. I saw you use a dot as date separator. But my country uses a minus sign as date separator. There are basically 2 ways to solve it. The easier way, I recommend you to put this line at the very beginning of the program.

Code: Pascal  [Select][+][-]
  1.    DefaultFormatSettings.DateSeparator := '.';

Also here are some non-critical issues:

Code: Pascal  [Select][+][-]
  1.       if something then
  2.       begin
  3.         Form1.VokabelGrid.cells[1,j]:=Form1.VokabelGrid.cells[1,j]+','+EditDeu.Text;
  4.         Form1.VokabelGrid.cells[2,j]:=DateToStr(Date);
  5.         GoTo 1;
  6.         break;
  7.       end;

Don't use break after goto statement. The break will never be executed.

It is not a sin using goto statement. But I recommend you to use Exit statement. It is less typing and more readable.

https://www.freepascal.org/docs-html/rtl/system/exit.html
« Last Edit: June 07, 2017, 04:19:08 pm by Handoko »

krull

  • New Member
  • *
  • Posts: 12
Re: Convert String To Date catch EConvertError
« Reply #10 on: June 08, 2017, 08:37:11 am »
Thank you all,

I've got it now. The code wasn't so bugy. The only problem were (RowCount-1).

 

TinyPortal © 2005-2018