-1

Trying to have some main template to change visibility of groupboxes based on the number in main editbox. EditDay is the edit box, where only numbers are in it

day:=DayOfTheYear(Now); 
EditDay.Text:=day;

so it's basicaly the day of the year. Anyway, I need a groupbox (with a few memos) for everyday of the year. Since this is a file with records, which another program will read off for everyday different infos, I need that file writer first, so I can even make one. That's what this one is Since I'm doing a record file, there has to be all boxes firstly filled up before I'll write to a file, so I need to have Groupboxes to be visible one at a time, each one for a day I specify in a main TEdit. Right now I'm stuck with setting the visibility of the groupboxes; The code below gives me Access violation error.

x is the number specified in TEdit named EditDay. I wanted to make an y every other day but the day in EditDay box so all but x;

x : Integer;     
y : Integer;

procedure TWriteForm.DayCheckTimer(Sender: TObject);
begin
  x:=StrToInt(EditDay.Text);
  y:=Not x;
  (FindComponent('GroupBox'+IntToStr(x)) as TGroupBox).Visible := True;
  (FindComponent('GroupBox'+IntToStr(y)) as TGroupBox).Visible := False;

Tried to set y:=[1..365] and not x; [1..365] - x; and several others, but none of them worked.

Where am I wrong? .. Any help will be appreciated. :))

[I'm kinda beginner, yes..]

user1500049
  • 993
  • 7
  • 15
That Marc
  • 1,134
  • 3
  • 19
  • 42
  • 1
    thanks to user1500049 for editing code in real code view ;) – That Marc Nov 05 '12 at 23:35
  • You don't really want to have 365 Groupboxes and all are not visible except one? You only need one Groupbox and the information which day of the year. – Sir Rufo Nov 05 '12 at 23:57
  • No, I need 365 of them, since that way I imagined to do a record, because haven't figured any other way yet. :) I have that much groupboxes, with 4 memos in each, what will make 1500 memos approx., (I know it's a lot! and I'll have to change my code or it will go really slow). The reason I need them is because I'm going to do Write action in Record to write down strings to a file. I could append them, but I want it that way, so there's always only one record for each day in a file I will use the read record procedure at formopen though, so I'll have most filled up already. Any better Ideas? :D – That Marc Nov 06 '12 at 00:05
  • 1
    don't use visual controls to keep your data. their intent use is to show and receive informations. you can store your data internally in a list. read the entire file into the list, put the data form one item to the controls to edit, store the new information into the item and then save all list items back to file. my advice: go and get some basic tutorials for delphi – Sir Rufo Nov 06 '12 at 00:13
  • I'll definitely go and learn about the list right away, thanks for that info. I'll see if I'll better understand your suggestion after finding out info about list. It's true, I could use some basics for delphi, but I just rather learn directly on examples, and so just make (basically useless) applications instead of watching tutorials. It's more of a challenge :) Thanks! – That Marc Nov 06 '12 at 00:22
  • I give up on it. Can't find anything that would seem as what I need by your suggestion. Could you maybe please give me any pointers, any article or q/a already made, which would have what I need to do..? Thank you a lot! – That Marc Nov 06 '12 at 22:32

2 Answers2

1

view y:=Not x; in the debugger x=1 will be y=-2, you won't find a Compoentr with this name.

You will have to iterate over your componets

For i := 1 to mCount

and set visibilty by condtition

(FindComponent('GroupBox'+IntToStr(i)) as TGroupBox).Visible := y = i;
bummi
  • 27,123
  • 14
  • 62
  • 101
  • Thank you for your reply. Let me try this out. Just, if I'm not asking too much, could you maybe a little more accurate explain this code above? I don't but would like to understand why set boolean type to integer; does it work eitherway, True or 1 as a value? And, mCount is any bigger number, I guess..? Thanks! – That Marc Nov 05 '12 at 23:56
  • y = i is a boolean expression if y = i then visible else not. Next "NOT" with integers has to be unterstood binary, lets take a byte ist shorter 00001010 = 10 DEC NOT Flips all Bytes 11110101 which is unsigned 245 and sigend -11 – bummi Nov 06 '12 at 00:14
  • huh, ok, I think I understand now what was the problem in my code. But can't get rid of the mCount error - undeclared identifier when pasting For x := 1 to mCount , it's expected to have only the integer value in it. Where's the hinch :/? – That Marc Nov 06 '12 at 00:17
  • I don't know your Code I guess mCount will be 365 for Groupbox365 ? But look at Sir Rufos comment. – bummi Nov 06 '12 at 00:24
0

Here a small sample project to deal with a lot (365) of records.

unit RecordEdit_ViewU;

interface

uses
  SysUtils,
  Controls, Forms, Dialogs, StdCtrls, System.Classes;

type
  TPerson = record
    Firstname : string[50]; // shortstring !!
    Lastname : string[50];  // shortstring !!
  end;

  TRecordEdit_View = class( TForm )
    Current_Edit : TEdit;
    Data_Firstname_Edit : TEdit;
    Data_Lastname_Edit : TEdit;
    Data_Prev_Button : TButton;
    Data_Next_Button : TButton;
    Data_Save_Button : TButton;
    procedure FormCreate( Sender : TObject );
    procedure Current_EditChange( Sender : TObject );
    procedure Data_Prev_ButtonClick( Sender : TObject );
    procedure Data_Next_ButtonClick( Sender : TObject );
    procedure Data_Save_ButtonClick( Sender : TObject );
  private
    FData :    array [1 .. 365] of TPerson;
    FCurrent : Integer;
    procedure SetCurrent( const Value : Integer );
    procedure InitData;
    procedure StoreCurrent;
    procedure LoadCurrent;
    procedure SaveData;
  public
    property Current : Integer read FCurrent write SetCurrent;
  end;

var
  RecordEdit_View : TRecordEdit_View;

implementation

{$R *.dfm}

procedure TRecordEdit_View.Current_EditChange( Sender : TObject );
begin
  Current := StrToIntDef( Current_Edit.Text, 0 ); // convert text to integer
end;

procedure TRecordEdit_View.Data_Next_ButtonClick( Sender : TObject );
begin
  Current := Current + 1; // next record
end;

procedure TRecordEdit_View.Data_Prev_ButtonClick( Sender : TObject );
begin
  Current := Current - 1; // prev record
end;

procedure TRecordEdit_View.Data_Save_ButtonClick( Sender : TObject );
begin
  SaveData;
end;

procedure TRecordEdit_View.FormCreate( Sender : TObject );
begin
  InitData;
end;

procedure TRecordEdit_View.InitData;
begin
  FCurrent := Low( FData ); // first record
  LoadCurrent;              // load data from record
end;

procedure TRecordEdit_View.LoadCurrent;
begin
  // Data from record to controls
  Data_Firstname_Edit.Text := FData[Current].Firstname;
  Data_Lastname_Edit.Text  := FData[Current].Lastname;
  // Update the Current-Edit
  Current_Edit.Text := IntToStr( Current );
end;

procedure TRecordEdit_View.SaveData;
begin
  ShowMessage( 'Needs to be implemented!' );
end;

procedure TRecordEdit_View.SetCurrent( const Value : Integer );
begin
  // check, if we have a change and if we can change to the new index
  if ( Value <> Current ) and ( Value >= Low( FData ) ) and ( Value <= High( FData ) )
  then
    begin
      StoreCurrent;      // store data from controls
      FCurrent := Value; // change current index
      LoadCurrent;       // load data from record
    end;
end;

procedure TRecordEdit_View.StoreCurrent;
begin
  // Data from controls to record
  FData[Current].Firstname := Data_Firstname_Edit.Text;
  FData[Current].Lastname  := Data_Lastname_Edit.Text;
end;

end.

And the form

object RecordEdit_View: TRecordEdit_View
  Left = 0
  Top = 0
  Caption = 'RecordEdit_View'
  ClientHeight = 337
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Current_Edit: TEdit
    Left = 107
    Top = 16
    Width = 75
    Height = 21
    TabOrder = 0
    Text = 'Current_Edit'
    OnChange = Current_EditChange
  end
  object Data_Firstname_Edit: TEdit
    Left = 80
    Top = 56
    Width = 129
    Height = 21
    MaxLength = 50
    TabOrder = 1
    Text = 'Data_Firstname_Edit'
  end
  object Data_Lastname_Edit: TEdit
    Left = 80
    Top = 83
    Width = 129
    Height = 21
    MaxLength = 50
    TabOrder = 2
    Text = 'Data_Lastname_Edit'
  end
  object Data_Prev_Button: TButton
    Left = 80
    Top = 16
    Width = 21
    Height = 21
    Caption = '<'
    TabOrder = 3
    OnClick = Data_Prev_ButtonClick
  end
  object Data_Next_Button: TButton
    Left = 188
    Top = 16
    Width = 21
    Height = 21
    Caption = '>'
    TabOrder = 4
    OnClick = Data_Next_ButtonClick
  end
  object Data_Save_Button: TButton
    Left = 80
    Top = 118
    Width = 129
    Height = 25
    Caption = 'Save Data'
    TabOrder = 5
    OnClick = Data_Save_ButtonClick
  end
end

You can get the complete Source and Executable here

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
  • Thank you A LOT. Really, don't know how to make it up to you! I'm on it for adjustments to fit my code and form, and will get back to you when finished. I guess I'll only have to figure out how to connect it to save to a file, as AssignFile and Write probably won't do the job, I guess...? – That Marc Nov 07 '12 at 17:07
  • Ok, I seriously tried to find anything like your code, since I really don't understand the initdata, store, load, and savedata procedures (where they came from), but I googled every possible word that came on my mind. Can you give me please any hint on this? I don't want to ask you for code, even though that would save me a lot probably, but just a hint where to look to understand it, would be more than enough. I did implemented it in my code successfully, adding more elements of a record, and everything works perfect, except for writing the whole thing to a file. – That Marc Nov 08 '12 at 00:06
  • As far as I found, I DO need the Write command after AssignFile and Rewrite command, but I can't find what to "show" to the Write(FileVar, FData[Current])... With this so far I always get empty file created, no matter what I show him to do before... And I really appreciate your help. These are stuff I've never seen before but as far as I get, I should know them urgently.. ;) – That Marc Nov 08 '12 at 00:09
  • What do you mean with "I really don't understand the initdata, store, load, and savedata procedures (where they came from)"? It is all in the code you see in my answer. Nothing else. And to save the Data to a file you have to step through all records from 1 to 365 and write them to the file. But that is beyond your initial question. And SO is also not for teaching basics from scratch. – Sir Rufo Nov 08 '12 at 00:24
  • I know, but from which unit are they pulled, that's what I can't find... :/ I've tryed for current : 1 to 365 do Write(FileVar, FData(Current), but I'm missing sommething there.. :/ – That Marc Nov 08 '12 at 00:39
  • Open your eyes and you will find something like "procedure TRecordEdit_View.InitData;" there is no other unit – Sir Rufo Nov 08 '12 at 01:34
  • You write 365 times the current record, nice catch for i := 1 to 365 do Write( FileVar, FData[ i ] ); OMG – Sir Rufo Nov 08 '12 at 01:35
  • Yeah, I found that, but what I meant was, from which "uses" unit that procedure comes from... I'm just trying to figure where it actually stores and loads from all this data. And also, I write the same current record? I thought that the "for" loop would take it through all records and write them down in for Current := 1 to 365 do begin FData[Current].FirstName := Data_Firstname_Edit.Text; Write(FileVar, FData[Current]); end; But I guess there's something I dind't get right way about that "for" loop.. :/ – That Marc Nov 08 '12 at 01:59
  • I wrote that procedure and i gave the name i liked more. I could have named InitData also MaryDanceLikeWild, it comes only out of my mind. So get in touch with Programming, OOP and Delphi Basics. This is like explaining colour to blind people – Sir Rufo Nov 08 '12 at 02:09
  • I just must tell you: I'm kinda embarrassed of myself right now. Because it took me 2 days for me, an idiot, to figure out that leaving one of the timers on the other form enabled was the problem, since it has rewrote my file every second, and therefore I always got an empty file instead of what I wanted to have in there!!! :S So, the mistake way my sloppiness and nothing else! :( I did found the right code only shortly after you wrote me that part, and the for loop was/is right, only that the integer for loop should be i not current, and in every loop I needed Current:=i;, and – That Marc Nov 09 '12 at 17:49
  • that now works GREAT! :) Thank you, Sir Rufo for all the help, and I'm sorry if I made you really nervous, and you must hate me, a kid who wants to be expert without reading any book ;), but that's really not the deal. Trust me. :)) I do read, but only what for what I'm in a need of, not everything. It's just who I am. :)) Really deeply thanks again!! – That Marc Nov 09 '12 at 17:53