dBUG Talk - Points from Meetings

Doggy Objects!

Definition of an "Object"

Do you get confused by explanations of new features using technical jargon? Paul Franks has contributed his description of an Object in more down-to-earth terms:

In fact objects are rather like dogs. You have to do something deliberate to get one (instantiate), it comes with basic functionality (inheritance) and you have to train (program) it. Then it has a mind of
its own, will react to certain events (if see cat, chase it) without further prompting and if you give it the wrong food (data) it will emit c**p in copious quantities and may bite you in tender places.


Setting column or header colours in a Grid

Meeting 11th January 2000

Many topics discussed, as usual, but only one item suitable for inclusion here. This arose from the practise by several present of allowing users to click the heading of a column in a Grid to select the Index order.

This can be achieved by placing a button over the heading and by exactly matching the size, completely concealing it. The a normal OnClick event function can include code to set the index order and optionally change button and/or column colours. An alternative is to use one of the Onleft... events of the Grid column headers itself. Both methods work well but where colour changes are required a lot of code is required. Largely repetitive for each column but still a bit tedious. A thread on the News Group had shown that using the OnLeftMouseDown event for the Column Header would automatically highlight the relevant column. This worked on a demo from the NG thread but not when applied to a Grid in an existing system. The reason turned out to be one of the grid properties:-      allowColumnMoving = false
Setting this to True (or deleting it altogether) allowed it to work. However it still does not seem to work as smoothly as changing colours in one's own code. perhaps that is why it is not documented as we can find no reference to this anywhere!


 

 

Comparison Operators (< & > )

 

 

Array Performance

 

 

Passing Queries etc. to Functions in Procedure or Custom Class files

Meeting 7th December 1999

First, two reports from members recent experience. Although it is documented, programmers may not realise that in v7 the comparison operators ( < and > ) no longer require expressions of the same Type. So, for example, a comparison of a variable of Type() Date with a string comprising a character date does not now produce a "Type mismatch" error message. Instead the Date variable is converted to a string and the two strings are compared. The result is unlikely to be what you are expecting!

The second report concerned the relative performance of an array and a temporary table. The example quoted required a list to be prepared, with three columns, of 800 unique references from a 3500 record table. The five further tables (ranging from 700 to 4000 records) had to check, for all their records, whether there was a match in the list. Initially an 800 x 3 array was used for the list and oRef.scan() used for the searching. This method took over an hour. So a temp. table with three fields was tried, using oRef.findKey() on an indexed field. This took just 58 seconds, over 60 times faster!

We then looked at ways of moving functions that processed data in tables out of main forms that were becoming unwieldy in size. We wanted to work on records in tables already used in the form and from within the same session. We found that if the external function was called with the Query or Datamodule passed as a parameter it worked fine. For example:

q = new Query()
q.sql = "Select * from Test.Dbf"
q. active = True

CalcFigs(q)

Or:

dm = new Test1DataModule()
dm.active = true

CalcFigs(dm)

In both cases you must of course have a Set procedure to ..... the file containing the CalcFigs function. No doubt this may already be obvious to many but it proved useful to work through the various ways this could be done as not all present were familiar with the scope and techniques.


Debugging

Meeting 5th October 1999

General experience was that the Debugger included in VdB7 was of little use. It was very slow, difficult to use and often led to an "Unstable" message. Various alternatives were discussed.

Simple temporary Message boxes sometimes sufficed but the information displayed had to be pre-set. The message box itself also "gotFocus()" which could have unintended effects. It was possible to run a program with the normal Command Window open and to enter commands in it. However this may not be to show values local to a form. In some circumstances inserting an Inspect(<oRef >) in a form or program at a suitable point can be useful as the inspector for the specified object (such as the Form) is then displayed.

Jon Webb showed a neat pseudo Command window facility that appeared to suit most debugging needs. It would normally be used by inserting a temporary "Debug" button on a form. By copying a standard (and supplied) block of code into the On_Click() event of this button it is possible to get the values of form objects such as entryfields, rowset field values and variables. Instructions for use are included in the Debug.prg file. This also includes the block of code that needs to be copied into any forms you wish to debug.

Jon Webb's Debugging programs (Debugit.zip) (5k)


DOS to Windows

Meeting 7th September

Advice was requested on the best route for changing an existing DOS system to Windows. Although in the short term migrating to 5.7 might be easier, the general view was that it was better to "bite the bullet" and go straight to v7. Suggested advantages included the extra features with v7, it's more robust nature and the prospect of a continuing upgrade path with the new subscription proposal.

To help those wishing to make such a change ( or starting with VdB from scratch), future meetings are likely to include a session on planning/starting new applications in v7.


Code Processing Sequence

Meeting 6th July 1999

The sequence in which code is processed. Personal experiences and questions raised on the NewsGroup all seemed to confirm that, unlike DOS programs, VdB does not always process each line in a function in strict sequence. It may well jump ahead and process lines further down the code before completing the current line. This seems to be a Windows, not VdB, practice as similar examples have been noted in Excel macros.

For example, a Message Box that reports the completion of a process may appear as soon as that process starts. A Setrange() line may fail if the relevant index is built with code a few lines previous. In other words, the SetRange() line is processed before the index is built and can be used. Code that calls other functions seems especially vulnerable. For example:

Function DoSomething
 CLASS::firstjob()
 CLASS::secondjob()
 CLASS::thirdjob()
 form.text1.text = form.mytable1.rowset.fields['NAME'].value

If within the three called functions a rowset pointer is moved or a value placed in the NAME field, it is likely that this will occur after the contents are placed into the text1 object. Which would therefore show incorrect data. Moreover, the three functions might be processed in parallel so if there is any dependency between them the results might prove unpredictable.

At times sequential processing is essential and ways of achieving this were discussed. An off-screen modal form that exists only to process functions is one possibility as program execution always awaits the closure of a modal form. However this may not prove practicable when reading or writing to tables as each form could be working on its own copy of a rowset.

A method that has proved successful so far is to place sections of code in Case ... statements within a Do Case that is itself in a Do While loop. A variable (such as cCounter) is initialised as "A". The first Case... tests for "A", runs its code and resets cCounter to "B". The program loops, the second Case... tests for "B" and so on.

There will be other ways of controlling program execution sequence. The important thing is to be aware of the problem and to be ready to deal with it.


The dFULP Custom Class Library


Custom Class Library
. Virtually every month an updated and enhanced version of the dUFLP is available for downloading. Or the dBASE Users Function Library to spell it out in full. Nowadays it is mostly Custom Classes rather than functions but it embraces every sort of useful addon or utility that can make a programmer's life easier. It now has its own Form and Table to help find what is available, just as well it has with no less than 562 different items listed and described. The Group plans to pick out items that seem of particular interest from time to time so that we can look at them together and identify their potential. Oh, and a really big thank you to Ken Mayer for maintaining the library and ensuring that it continues to grow.


A Class to write HTML pages


Htmlclas.cc
 This was the first eye opener. It is designed to enable Web pages to be created within a dBASE program! It comes with an example program that uses and demonstrates every feature available. Text of all kinds of course. And graphics - and backgrounds - and colours - and Tables - and, well, features most had not realised even existed. Including of course scope for looping through a DBF table and writing to an HTML table. Anyone wanting to create web pages from data in DBF files is going to love this. A subsequent test proved that it does work - but needed a lot of trial and error. What does not?

A class to Split a Form into several windows or panes


Splitter.cc
 Only a picture can easily explain what this does:

This example shows a Form split into three windows. Top left contains a Notebook, bottom left an Editor and to the right could be a Grid. Vertical or horizontal windows can be set, or both as in this example. Windows can be re-sized by the user. Unusually this Custom Class is a Visual Component and opens up all sorts of possibilities. It was written and demonstrated by one of our own members, Elwyn Rees.

Home Page 

Articles       Demos      Library       Meetings      Members       Tip & Tricks