Recent

Author Topic: need help with calender  (Read 49807 times)

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #30 on: September 21, 2017, 04:41:32 am »
In the last complete project given the name and date were shortstrings so that should be a problem.

I don't see a whole lot wrong with this code.
Unless you skipped the empty records when filling in the listbox. In that case you get the wrong record if you choose a goal after a "deleted" record.

Show us the code where you fill in your listview.
(Or upload the whole project with your goalfile)

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #31 on: September 21, 2017, 05:13:30 am »
click on 21st, 22nd and 23rd of september and try to double click the goal on listbox. if i click 22nd and 23rd goals, 21st goal is shown.

please find the attachment

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #32 on: September 21, 2017, 10:01:26 am »
click on 21st, 22nd and 23rd of september and try to double click the goal on listbox. if i click 22nd and 23rd goals, 21st goal is shown.
That is because you only fill in the listbox with goals for one date.
If you use itemindex it is 0..x for the items in the list.
So if you only fill in for one date, you get that clicking 22nd, that 1 goal will get itemindex 0 in your listbox.
And you CAN'T use that itemindex anymore to seek() and overwrite a record in your file because the listbox doesn't have the correct position.
(do you understand that??)

If you really want the listbox to only show the goals for that date you need to add another integer to the itemlist for the absolute (and correct) position of that record within your goalfile.

You can do that by adding a Cnt counter to your while loop in Calendar1DayChanged(). Set it to 0 before the while loop and increase it by one at the end.
Then, instead of listbox1.items.add() you use this
Code: Pascal  [Select][+][-]
  1. listbox1.items.addObject(info.Name + ' ' + IntToStr(info.goal), TObject(IntPtr(Cnt))); // save with filecounter

Now in the Button2Click() where you want to delete the goal you need to clear the information in info and write to the saved Cnt pointer.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. begin
  3.   // empty out info to delete record
  4.   info.Name := '';
  5.   info.date := '';
  6.   info.goal := 0;
  7.   reset(goalsfile);
  8.   seek(goalsfile, PtrInt(ListBox1.Items.Objects[ListBox1.ItemIndex])); // convert Cnt-counter back to index for seek() within file
  9.   Write(goalsfile, info);
  10.   closefile(goalsfile);
  11. end;

(So with ListBox1.Items.Objects[ListBox1.ItemIndex] you can access the pointer-object for the selected ItemIndex).

Of course you need to refresh the Listbox again after this because otherwise the deleted record is still shown in the listbox.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #33 on: September 21, 2017, 10:25:50 am »
wow thank you very very much you're legend
are you a lazarus teacher or something?
did you learn lazarus by yourself?

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #34 on: September 21, 2017, 10:30:38 am »
are you a lazarus teacher or something?
Well, I am on this forum (kind of) :D

No, I like to help around on the forum and have a lot of experience in Delphi and Lazarus.
I use Delphi for developing software for my clients and use Lazarus in my free time.

I began learning Turbo Pascal back in the late 80s so everything is kinda self-learned but with time comes experience :)
(Google helps a lot too  8) )

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #35 on: September 21, 2017, 12:11:47 pm »
Thank you so much for helping me and other people on this website. i really respect you

can you help me with one more thing?

so i added edit button to put number in the label to show that how much progress is done in the goal.
For example the goal is 10 and if i put 5 in the Tedit and press the button, the label will show 5 and i coded and info.progress will be 5.

but when i press the button, new item is added in the listbox on that day. It has the same name but if you double click it it has the previous info.progress.(btw you have to click other day and click the day again to see the new added item with the same name)

please find the attachment

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #36 on: September 21, 2017, 12:39:50 pm »
In the EditClick() you have this line:
Code: Pascal  [Select][+][-]
  1. seek(goalsfile,filesize(goalsfile));
  2. write(goalsfile, info);
That means that when you click the "Update" that the info is written to the end of the file. You want it to overwrite the current record.

So you need to seek to the place of the item you clicked. It's the same as with the "Delete" button. You need to use the Items.Object to seek() the correct place and then overwrite the record.
Code: Pascal  [Select][+][-]
  1. seek(goalsfile, PtrInt(ListBox1.Items.Objects[ListBox1.ItemIndex]));
  2. write(goalsfile, info);

After that you need to refresh your Listbox to see the percentage.
B.T.W. the percentage calculation is wrong.
info.progress div info.goal * 100
When progress is 30 and goal is 100 you get 30 div 100 which is 0, times 100 which is still 0
Try to fix that.

I've also noticed another weird thing. Look at this:
Code: Pascal  [Select][+][-]
  1.   else
  2.     edit3.visible:=true;
  3.     Edit.caption:='Update';
You see that edit3.visible line belongs to the else but you also indented Edit.Caption line. Which is wrong because that one isn't inbetween begin/end so it does not belong to the else statement.

My advise is to use correct indentation.
To help you with that you can install the jcfidelazarus package.
Package > Install/Uninstall packages. Choose jcfidelazarus from the right panel if it's not already at the left and click Install selection. Click Save and rebuild IDE.
After you installed that package you can press Ctrl+D to automatically use the correct indentation.

Now you see your code
Code: Pascal  [Select][+][-]
  1.   end
  2.   else
  3.     edit3.Visible := True;
  4.   Edit.Caption := 'Update';
and you see directly places where your code is incorrect. It will help you a lot to analyse your code and spot errors.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #37 on: September 21, 2017, 12:50:43 pm »
wow thank you very much :)
do you think there are something that i can do to improve this program? can you give me some advice?

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #38 on: September 21, 2017, 01:03:02 pm »
do you think there are something that i can do to improve this program? can you give me some advice?
Well, I forgot to mention that you included a corrupt goalssssfile.dat file in your upload.
The file you included had records where the progress-field (integer) wasn't present.
If you change the record format (like you did), the entire current file is useless and needs to be converted (or deleted).
That is the major downside of using a record-file like this. When changing the record-format everything goes to hell.

There are a lot of things you can improve. I didn't want to mention them right off the bat because that could overwhelm you and distract from the question at hand.

But some possible improvements would be:
  • Converting the entire thing to a database. That way it's easier to delete, add and edit records. Although it might be a bit beyond beginner level. But eventually you would go that route anyway (maybe at a later stage).
  • As your program is now you don't have checks on reading the file. reset() or read() could fail and your program would crash. Proper error-handling would be needed to catch those things.
  • You now need to double-click the listbox-item to edit it. When you single click and choose edit, it adds a record. Either make the listbox-click a single click or only enable the edit-button when you double click the listbox and have a real valid item.
  • I already mentioned using proper indentation. It will really help you spot potential problems in your program.
  • Also already mentioned, refresh the listbox when choosing Update and Submit button.
  • Adding type yes/no with a goal gives an exception.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #39 on: September 21, 2017, 01:10:41 pm »
what is database? can you show me small short example please?

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #40 on: September 21, 2017, 01:33:46 pm »
A database is a piece of software/library which you can call to handle the saving of records.

As it is now you handle the opening, closing, reading and saving of the file yourself. That is quite low-level. If you want to sort the records, or delete records, you need to do a lot of writing to do that. A database handles all that for you.

https://en.wikipedia.org/wiki/Database

An easy to use database would be SQLite
Using SQLite with Lazarus: http://wiki.freepascal.org/SQLite
http://wiki.freepascal.org/SQLdb_Tutorial1

Like I said... it might be a bit much for an absoute beginner but if you read up about it a little it will become clear.

Some simple code snippet would be:
Code: Pascal  [Select][+][-]
  1. SQLQuery1.SQL.Text := 'SELECT * FROM GOALS';
  2. SQLQuery1.Open;
  3. while not SQLQuery1.EOF do
  4. begin
  5.   // do something the SQLQuery1 like SQLQuery1.FieldByName('Name').asInteger etc.
  6.   SQLQuery1.Next;
  7. end;

Another snippet to create the database (simplest form):
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   SQL: string;
  4. begin
  5.   Deletefile('test.db'); // remove if you want to keep de db
  6.   if not FileExists('test.db') then
  7.   begin
  8.     SQL := 'CREATE TABLE GOALS(goaldate date, goalname varchar(25), goal int, progress int);';
  9.     SQLite3Connection1.ExecuteDirect(SQL);
  10.     SQLite3Connection1.ExecuteDirect('INSERT INTO GOALS VALUES ("2017-09-21", "test1", 100, 30);');
  11.     SQLite3Connection1.ExecuteDirect('INSERT INTO GOALS VALUES ("2017-09-22", "test2", 100, 0);');
  12.     SQLite3Connection1.ExecuteDirect('INSERT INTO GOALS VALUES ("2017-09-23", "test3", 100, 0);');
  13.     SQLite3Connection1.Transaction.Commit;
  14.   end;
  15.   SQLQuery1.SQL.Text := 'select * from goals';
  16.   SQLQuery1.Open;
  17. end;
(screenshots attached)

You need to see if you understand this code a bit or it goes beyond your head (in which case you need to study it some more) :)

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #41 on: September 21, 2017, 01:38:52 pm »
Oh wow that seems really hard but i will try it :)) thank you so much for your support

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #42 on: September 21, 2017, 02:00:28 pm »
hi rvk i when i click the delete button after i select the item on listbox, the infos are are i click the button, but it is gone when i click another date and click the date i deleted the item. can i delete it as i click the button?

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: need help with calender
« Reply #43 on: September 21, 2017, 02:14:25 pm »
hi rvk i when i click the delete button after i select the item on listbox, the infos are are i click the button, but it is gone when i click another date and click the date i deleted the item. can i delete it as i click the button?
Yes, that is what I meant with refreshing the ListBox.
You need to reread the same date so when you click the Delete button and the record is deletes, the listbox refreshes and the deleted record isn't shown anymore.

So at the end of Button2Click (the delete button) you would call Calendar1DayChanged(nil); again to reread the listbox.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #44 on: September 21, 2017, 02:26:40 pm »
hi rvk i when i click the delete button after i select the item on listbox, the infos are are i click the button, but it is gone when i click another date and click the date i deleted the item. can i delete it as i click the button?
Yes, that is what I meant with refreshing the ListBox.
You need to reread the same date so when you click the Delete button and the record is deletes, the listbox refreshes and the deleted record isn't shown anymore.

So at the end of Button2Click (the delete button) you would call Calendar1DayChanged(nil); again to reread the listbox.


what is that nil do in the bracket?

 

TinyPortal © 2005-2018