Jump to content
Registration disabled at the moment Read more... ×
Freeeee

Memo lines{i] to labelv ok. Labels to Memo lines nope

Recommended Posts

this works:               //  <-------
 LblFirstName.Caption       := Memo1.lines [0];
 LblMiddleName.Caption  := Memo1.Lines [1];
 LblLastName.Caption       := Memo1.Lines [2];
each memo line ends up where expected.
 
this doesn't work.    // <------
Memo1.Lines [0] :=  LblFirstName.Caption;
Memo1.Lines [1] :=  LblMiddleName.Caption;
Memo1.Lines [2] :=  LblLastName.Caption;
two buttons.  1st invokes the Memo to labels
2nd the Labels back to the memo
 
The firstName field shows up in Memo.lines [0]
Usually nothing in [1] or [2], but some times all 3 show up.  Usually just [0] or [0] & [1]
very sporadic.  
why do I do this?
1st.   It gives the user a look at what the data will be when moved to 
a record. 
2nd.  the original data is still in Memo and can be corrected an moved again.
3rd it will allow the App to read an old record into  Memo and correct it in the same way ti was  created.
Kind of "Oh! I know how this works." for the User.
Edited by Freeeee
mistype memo

Share this post


Link to post

The Memo could have fewer than three lines in it. If you want to update lines make sure they exist first. 

while Memo1.Lines.Count < 3 do Memo1.lines.Add('');

 

Edited by Brian Evans

Share this post


Link to post

In a VCL TMemo, if you try to read from a line index that doesn't exist then the output string will be blank, and if you try to write to a line index that doesn't exist then the input string will be ignored.  No errors are raised.  So, in your case, for example, if you try to write to Memo1.Lines[2] when Memo1 does not have at least 3 lines, then your LblLastName.Caption string will be ignored.

 

So, like Brian said, you have to make sure a given line actually exists before you can read/write it.

 

That being said, using a TMemo probably isn't the best choice for this task to begin with. Why not use 3 TEdit's instead?  Or maybe a TStringGrid, or a TValueListEditor, or an editable TListView instead?  There are many choices, depending on your UI needs.

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

Thanks again Remy.

as usual, your answer are precise and lead me to a better understanding of what's available.

I had just discovered string grids, last nigh.  🙂  thinking there has to be a better way for Users to input names and dates.

 

Do you know of a resource online where I could page thru the available resources.?

 

Share this post


Link to post

This is interesting.  The move from the TMemo to the Tlabels works fine.

Every time.  too. 

Actually there are  14 lines in the TMemo in the 'real' program.

The example I used was from a test program.  Three seemed like enough.

 

It's moving the same labels (all 14 of them) in the same program back into the TMemo for editing.

a ?? second later?? that doesn't work.  where did the TMemo lines go? 

 

Hitting the button that does the move from TLabel to TMemo several times seems to 'use up' Lines

until there's only 1 left.  

 

Does moving lines To a TMemo, from the Tlabels,  make the number of lines available smaller?

Why?    That doesn't make much sense.  typing into the TNemo from the keyboard still works.

 

is there a command to make sure the TMemo has 14 lines in it.??? 

 

I Thought from reading the description of TMemo,  that the number of lines was more or less "Very" large.

It says 'infinite' but  that's a stretch.

Edited by Freeeee
correct from Tmemo to 'To Tmemo

Share this post


Link to post

 Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button1: TButton;
    Button2: TButton;
    memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
end;

 

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin     // FROM LABELS  this does not work reliabley
Memo1.lines.delete (0);    // will cleaning help?
Memo1.Lines.Delete (1);    // nope each B1 clk removed
memo1.lines.Delete (2);    // another line.
Memo1.lines [0] := Label1.caption;
Memo1.lines [1] := Label2.Caption;
Memo1.lines [2] := Label3.caption;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin         // FROM MEMO LINES this works
Label1.caption := Memo1.lines [0];
Label2.Caption := Memo1.lines [1];
Label3.Caption := Memo1.lines [2];
end;


end.

Share this post


Link to post

This comment is wrong: 

FROM LABELS  this does not work reliabley

 

That does work reliabley. You are assuming that the TStrings (lines) will add new lines where it will not. Try this one:

 

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.lines.clear; // delete old values
  Memo1.lines.Add(Label1.caption);
  Memo1.lines.Add(Label2.Caption);
  Memo1.lines.Add(Label3.caption);
end;

 

Share this post


Link to post

thanks.  that was my question.


"is there  a procedure/function that makes sure there are enough lines?"
 

Nice bit of succinct code too.    🙂

 

 

Share this post


Link to post

nope.  did you try it?

I just added the code

the move from Tlabels to Tmemo

still doesn't work

first line is missing on move back.

??

 

Share this post


Link to post

Procedure TForm1.Button1Click(Sender: TObject);
begin     // FROM LABELS  this does not work reliabley
  Memo1.lines.clear; // delete old values
  Memo1.lines.Add(Label1.caption);
  Memo1.lines.Add(Label2.Caption);
  Memo1.lines.Add(Label3.caption);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin         // FROM MEMO LINES this works
Label1.caption := Memo1.lines [0];
Label2.Caption := Memo1.lines [1];
Label3.Caption := Memo1.lines [2];
end;

Share this post


Link to post

Note 1: if you delete items from a list, you always have to do it from the end!
Note 2: in such cases I use a list of components. Your TLabel. Then you just need to do everything in a loop. And not list every Tlabel and line of the Tmemo.

Share this post


Link to post

This code works "properly" even though as others mentioned not the best user interface to do it:
 

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.lines.clear; // delete old values
  Memo1.lines.Add(Label1.caption);
  Memo1.lines.Add(Label2.Caption);
  Memo1.lines.Add(Label3.caption);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Label1.caption := Memo1.lines[0];
  Label2.Caption := Memo1.lines[1];
  Label3.Caption := Memo1.lines[2];
end;

Steps to test it:

 

1.) Click button1

2.) Edit the memo make sure all 3 lines remain.

3.) Click button2 - the captions will change on labels.

 

Share this post


Link to post

steps to test it.

enter first name linefeed, Second Name l/f, 3rd name.  

You now have 3 Tmemo lines.

It';s important that the lines in the TMemo line up with the Tlabels..

button1 move the Tmemo lines to the Tlabels.

examine the Name.   There are errors in it.

Button2 move the 3 names back to the TMemo. 

correct the errors

Button1 move names back into Tlabels.

Repeat until names are correct.

 

 

 

Share this post


Link to post
1 hour ago, Stano said:


Note 2: in such cases I use a list of components. Your TLabel. Then you just need to do everything in a loop. And not list every Tlabel and line of the Tmemo.

By switching to Static text like a label but the advantage of windows handle so it be selected then you add a event to the win control like so.  F2 is an Edit control.  I'm sure Marco Cantu has much examples in his books.

procedure  TForm16.Clicker(Sender: Tobject);
begin
  EZ := F2.Text;
  (Sender as TStaticText).Caption := EZ;
  end;

procedure TForm16.RzButton1Click(Sender: TObject);
 var Labels: Array[0..9] of TStaticText;
 var stlabela: TStaticText;
begin
 var count:= 0;
 for var stlabel in Labels do
   begin

     Labels[Count] := TStaticText.Create(Self);

     stlabela := Labels[Count];
     stlabela.Parent := self;
     stlabela.SetBounds(24,20*count,50,23);
     stlabela.onClick := Clicker;
     stlabela.Caption := count.ToString;
     stlabela.Show;
     Inc(count);
   end;
end;

 

Share this post


Link to post
2 hours ago, Freeeee said:

procedure TForm1.Button1Click(Sender: TObject);
begin     // FROM LABELS  this does not work reliabley
Memo1.lines.delete (0);    // will cleaning help?
Memo1.Lines.Delete (1);    // nope each B1 clk removed
memo1.lines.Delete (2);    // another line.
Memo1.lines [0] := Label1.caption;
Memo1.lines [1] := Label2.Caption;
Memo1.lines [2] := Label3.caption;
end;

Why are your DELETING lines you are trying to WRITE to? Also, you are not taking into account that the line indexes will CHANGE when you delete lines, so you are actually deleting the 1st 3rd 5th lines, not the 1st 2nd 3rd lines. 

 

Simply don't do this. You don't need the Delete() calls. 

 

procedure TForm1.Button1Click(Sender: TObject);

begin

  Memo1.Lines [0] := Label1.Caption;

  Memo1.Lines [1] := Label2.Caption;

  Memo1.Lines [2] := Label3.Caption;

end;

 

procedure TForm1.Button2Click(Sender: TObject);

begin

  Label1.Caption := Memo1.Lines [0];

  Label2.Caption := Memo1.Lines [1];

  Label3.Caption := Memo1.Lines [2];

end;

 

But, if you must delete lines, then you can simply Insert() them back in, eg:

 

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Delete (0);
  Memo1.Lines.Delete (0);
  Memo1.Lines.Delete (0);
  Memo1.Lines.Insert(0, Label1.Caption);
  Memo1.Lines.Insert(1, Label2.Caption);
  Memo1.Lines.Insert(2, Label3.Caption);
end;

 

But, I still stand by my earlier comment that this is really the wrong UI choice to use in the first place.

Share this post


Link to post

I added those to see if I could solve the problem.

they were not there originally.

It works from the keyboard with C.r/Lf added to each line,

 

I sent the code for the entire program.

 

Moving the data back and forth seems to delete lines from the memo box

until there's only one left.

 

It's possible it was a bug in 12.1 and may have been corrected.

I'd still like to know if there;'s a "Reset" button for a Memo box

that would let it accept data programmatically rather than the keyboard?

 

I understand that this IS NOT the way to do this.  It wasn't under MSDos and Delphi 5 either.

 

Then you could clear (what is now the form) programmatically with a single command "CLS" in turbo Pascal.

Then set up a completely new Page  using indexed GotoXY (x,y) and strings in one array in a loop. complete with new tab stops 

at data entry points.   If you worked in Assembly language you could setup the Pages in 23x80 Byte arrays in memory and just move it

to the O/S screen memory.  But memory was short in those days so it was  'Better' doing it the first way.  

 

I had 6 or 7 ways of displaying all of the data in various formats on a single screen one at a time.

 

I suppose with the "visible " property on buttons, labels, and boxes It would be possible to do that now but the Form design 

"Form" would be impossible to read with all of the labels (etc) over top of one another.   It would be possible if you

did all of your page design in the text version rather than on the form design screen.  You'd have to name your labels etc 

carefully/   But that would satisfy the one form per unit requirement.

 

Things have changed since Delphi 5,  and I'm still learning 12.   

 

 

 

Share this post


Link to post

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×