Freeeee 0 Posted Wednesday at 07:50 PM (edited) 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 Wednesday at 07:52 PM by Freeeee mistype memo Share this post Link to post
Brian Evans 128 Posted Wednesday at 09:08 PM (edited) 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 Wednesday at 09:17 PM by Brian Evans Share this post Link to post
Remy Lebeau 1636 Posted Wednesday at 09:55 PM (edited) 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 Wednesday at 10:02 PM by Remy Lebeau 1 Share this post Link to post
Freeeee 0 Posted yesterday at 11:59 AM 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
Freeeee 0 Posted 23 hours ago (edited) 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 23 hours ago by Freeeee correct from Tmemo to 'To Tmemo Share this post Link to post
Lajos Juhász 325 Posted 23 hours ago You should provide some code you are testing. Not even Remy can see your monitor or debug inside your IDE. Share this post Link to post
Freeeee 0 Posted 23 hours ago 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
Lajos Juhász 325 Posted 23 hours ago 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
Freeeee 0 Posted 23 hours ago 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
Freeeee 0 Posted 23 hours ago 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
Freeeee 0 Posted 23 hours ago 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
Stano 145 Posted 23 hours ago 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
Lajos Juhász 325 Posted 22 hours ago 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
Freeeee 0 Posted 22 hours ago 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
Pat Foley 54 Posted 21 hours ago 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
Remy Lebeau 1636 Posted 20 hours ago 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
Freeeee 0 Posted 18 hours ago 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