LAZARUS/ DELPHI COURSE - - / - - / - - Other material for programmers

Second "database" example... preparation for something better

Page URL: DataB2.htm

This page is information rich, and a has search button at the bottom of the page.

Please don't dismiss it because it isn't full of graphics, scripts, cookies, etc!

You will probably find the text easier to read if you make your browser window much narrower than usual. You may also want to change your browser's zoom level, to enlarge the text. Opera (at least) lets you change zoom level easily. The text will adapt nicely to the settings you decide give the best results for your needs!

The lines of sample Lazarus/ Delphi code in these pages will not "wrap". I.e., if a line is too long to show in the width you have set your browser too, parts of the line will be "off the page". Those lines will still copy/paste properly, at least in Opera. Please feel free to send feedback on the choices I've made! (Will you forgive me for not forcing upon you a column of links on the left and a column of ads on the right?)

This is just one exercise in a series of Lazarus / Delphi exercises. You will probably be best served by doing them in sequence... each assumes some prior knowledge. Material © TK Boyd, sheepdogsoftware.co.uk, 4/05-6/20.

Heavily re-worked, June 2020, to bring it up to date for Windows 10/ Lazarus 2.0.0 Based on earlier Delphi page. Probably still useful to Delphi programmers, too.

In this lesson, you make an application to look up data.

You should learn how to...
--- Declare an array

You should learn about....
--- The form's OnCreate event
--- Global and local variables

Pascal: the language behind both Lazarus and Delphi:
--- Arrays
--- Comments marked off with {} and (* *)

This lesson will produce a small program which lets you look up data from inside the computer. It will be similar to our earlier "database" program, but it will be able to give us "Spain" from "Madrid" or "Madrid" from "Spain". It will also use the OnChange event handler, just as it was used in the first converter application. Start a new application. Put an edit box and a label on it. Rename form data2f1. Save the unit as data2u1.pas. Save the project as data2.dpr, in its own folder.

Make the edit box's OnChange handler...
procedure Tdata2f1.Edit1Change(Sender: TObject);
  label1.caption:='- - - -';
  if edit1.text='Madrid' then label1.caption:='Spain';
  if edit1.text='Spain' then label1.caption:='Madrid';

  if edit1.text='Rome' then label1.caption:='Italy';
  if edit1.text='Italy' then label1.caption:='Rome';

  if edit1.text='Lima' then label1.caption:='Peru';
  if edit1.text='Peru' then label1.caption:='Lima';

You should now have a program which, rather crudely, lets you look up what country a given city is in, and will give you a major city if you enter the name of a country.

Note that the application is case sensitive. It won't "realize" that "madrid" is, to sloppy humans, "the same" as "Madrid". This time we won't add the distraction of making it recognise words regardless of the letter case. See the first "database" program for how to do that.

So far, so good.

We're now going to rewrite the application somewhat. A user will not be able to tell the difference. For the moment, the reason for the re-write will not be clear.

You already know something about variables. To date, you have only used local variables. Variables are a place where you can put things, and they will still be available later. In this lesson, we're going to make a very crude use of a special sort of variable called an array element. Besides meeting arrays, we're going to meet our first global variables. Global variables are, generally speaking A Bad Thing.... but everyone uses them. The trick is to use them in moderation. (We'll come back to "local" and "global" at the end of the lesson.)

Near the beginning of the program, you will find....
  { Tdata2f1 }
  Tdata2f1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    procedure Edit1Change(Sender: TObject);


(The text between the curly brackets is a comment. You've already learned to make comments on the ends of lines with //. The curly brackets are another way to make some text a comment.) On a new line, just after the word "private", add...
sCountry,sCity: array [0..2] of string;
(Indent it nicely... put the "s" of "sCountry" under the "i" in "private".

What you have added has made the following available:
Each is like a variable. You can put things in each of them. This will become more clear in a moment.

sCountry is an array. sCity is a separate array. Each of them has three elements. Each element can hold a string.

And people say I move too slowly sometimes!

Somewhere on the form, not on the edit box, not on the label, and not on the title bar, double click. The following should come up..
procedure TData2f1.FormCreate(Sender: TObject);
Insert the following between the Begin and the End...
Put "//FormCreate" after the "end;" to mark it as the end of the FormCreate event handler.

Don't be confused by the fact that the first array element is element "number zero". This may be a little different from your usual way of "numbering" things, but it works fine, and there are reasons why computer people tend to count from zero.

Try running that much. Nothing new will be apparent, but you can fix any typos now, before new ones arise.

You've done a fair bit of work by now. If you haven't already done so save your work and do a backup. I'll be leaving it to you to remember these important matters before long. Make you laugh? 8 Jun 20., while working on a re-write of this page for you, just after I'd written "do a backup" (which of course I didn't do myself) I somehow totally crashed what I'd done so far, and had to start again!

The OnCreate event occurs when the form is first created, in other words, as the application starts up. Put things that need to happen before the rest of the application starts working in the OnCreate event handler.

Now change the OnChange event handler for the edit box. Make it....
procedure Tdata2f1.Edit1Change(Sender: TObject);
label1.caption:='- - - - - -';
if edit1.text=sCountry[0] then label1.caption:=sCity[0];
if edit1.text=sCountry[1] then label1.caption:=sCity[1];
if edit1.text=sCountry[2] then label1.caption:=sCity[2];
if edit1.text=sCity[0] then label1.caption:=sCountry[0];
if edit1.text=sCity[1] then label1.caption:=sCountry[1];
if edit1.text=sCity[2] then label1.caption:=sCountry[2];
... and run the application again. It should work as before.

Do you see what we've done? (Don't worry about why we've done it.) In a nutshell, we've make things a little less direct.

First, while the application is starting up, we fill two arrays, sCountry and sCity. In sCountry[0] and sCity[0], we have a country and a city of that country. In sCountry[1] and sCity[1], we have a different country and a city of that country.

During the event handler for the edit box, we look to see if what's in the edit box's text property matches what we have in any of the array elements. If we find a match, we report the paired data, e.g. if we find Italy, the contents of sCountry[0], we return Rome, the contents of sCity[0].

An immediate benefit is as follows:

Suppose we want to take Italy/Rome out of the "database", replacing it with Bejing/China. I trust you see how you would do that? (sCountry[0]:='China';sCity[0]:='Bejing';)

At least that's all you have to do with this version of the program. previously, the following would have been part of the edit box's OnChange....
if edit1.text='Rome' then label1.caption:='Italy';
if edit1.text='Italy' then label1.caption:='Rome';
If we were still using that version of the application, subsituting Bejing/China would have required two substitutions of "Bejing", two substitutions of "China". Not an earthshaking chore, admittedly, but any time you can make something more tidy, more elegant... do!

This program will be developed further in a later lesson. At that point the use of the arrays will be unavoidable.

Just before we finish, we are going to hark back to the difference between local and global variables. Change the edit box's OnChange event handler as follows:
procedure TData2f1.Edit1Change(Sender: TObject);
var sInput,sOutPut:string; // new 1
sOutPut:='- - - - - -'; //modified 1
sInput:=edit1.text; // new 2
if sInput=sCountry[0] then sOutput:=sCity[0]; // modified 2
if sInput=sCountry[1] then sOutput:=sCity[1];
if sInput=sCountry[2] then sOutput:=sCity[2];
if sInput=sCity[0] then sOutput:=sCountry[0];
if sInput=sCity[1] then sOutput:=sCountry[1];
if sInput=sCity[2] then sOutput:=sCountry[2];
label1.caption:=sOutput; //new
The application should still work as before, even though, yet again, why it works that way has changed, under the application's skin. (Get it working, if it isn't.)

sInput and sOutput are examples of local variables. You can only use them within the procedure Edit1Change, the edit box's OnChange event handler. Generally speaking, you try to make all of your variables local. They are local to Edit1Change because they were declared within Edit1Change. (The line starting "var" is where they were declared, where we told the compiler to provide variables of those names, of the given type.)

The elements of the arrays sCountry and sCity, on the other hand, are global variables. The arrays were declared just after the comment { Public declarations }. (Note no "var" is used in this context.) You can use, say sCity[2] anywhere in the program, because it is a global variable. We put 'Lima' into the array element "sCity[2]" during FormCreate, and we fetch 'Lima' from it during Edit1Change.

If you are ready for more advanced stuff about arrays, you might find what I wrote about a Sudoku solving application, in my Delphi Tutorials (I have a separate collection of Lazarus tutorials. Anything in either should work... more or less!... with either IDE) The Lazarus tutorials are separate from the Delphi Tutorials. This, my Laazarus / Delphi Course covers both IDEs.

One last little detail....

Not only can things be made mere comments by enclosing them between curly brackets, as Delphi did with...
{ Public declarations }
... but if anything is enclosed between (* and *), then it is also a comment. The enclosed material can extend over several lines. It is as well to put some notes at the start of the sourcecode. In the case of this program, my notes might be...
(*An example in support of Sheepdog Guides Delphi Lessons
  Version: 8 Jun 2020
  Started 2 April 2005.
  Derived from a draft written on trip to Costa Rica*)
The last is, of course, just for my fun... but it is fun to have a note of such things sometimes!

Search just this site without using forms,
Or... again to search just this site, use...

Powered by FreeFind

Site search Web search

The search engine merely looks for the words you type, so....
  *!  Spell them properly   !*
  Don't bother with "How do I get rich?" That will merely return pages with "how", "do", "I", "get" and "rich".

I have other sites...
   SheepdogSoftware site.
   My site at Arunet.

Ad from page's editor: Yes.. I do enjoy compiling these things for you... I hope they are helpful. However.. they don't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated.
Click here to visit editor's Sheepdog Software freeware, shareware page.
Link to Tutorials main page Link to Lazarus/ Delphi Course index

To email this page's editor, Tom Boyd.... Editor's email address. Suggestions welcomed! Please cite "datab2.htm".

Click for W3.org HTML validity test Page has been tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org. Mostly passes.

AND passes... Click to check CSS validity

One final suggestion: Be sure you know all you need to about spyware.

. . . . . P a g e . . . E n d s . . . . .