Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

simple vfox9 program MAIN (template) 3

Status
Not open for further replies.

johan3000

MIS
Dec 17, 2010
18
ID
hi All,

is there any example the proper way to write the MAIN program of vfox9, where it includes menu and many form ? How do you break down the program (sub program) ? what is the main window style ? etc...

PUBLIC..
ON KEY...
SET command ...

WITH _screen
.Caption =
.....
ENDWITH

DO myMenu.mpr
READ events


thx..
 
This is not an easy question to answer in a forum post. There's a lot of stuff that usually goes into a main program.

But just to give you a general idea:

Code:
* Main.PRG

* PART 1 -  Initialisation
* e.g. SET commands, ON ERROR, ON SHUTDOWN, etc.

* PART 2 - Launch the top-level user interface
* This is usually a menu or a main form
* e.g. DO MyMenu.MPR

* PART 3 - Go into the event loop
READ EVENTS

* PART 4 - Clean up
* Close all open tables, etc.

In addition, you need CLEAR EVENTS in the button or menu command that closes the application. In the above example, it would be in the Exit command (or similar) in MyMenu.MPR.

This is a highly simplified explanation, but it should start you off.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
thanks so muck Mike,

on the subprogram (in vfox9 we called it FORM/documents)
do we do the :

open database
use table1
use table2...
..............
close databses


most form have this kind of activity ? and can we reindex and do the sorting/packing anytime ?



 
Johan,

I'm not sure what you mean by "subprogram". Is it a PRG that's called from Main.PRG? If so, you can certainly open your database there, but you must remember that it will only be open in the default data session.

It's more common to open the required tables in each form. You can either do that programmatically, for example in the Load event. Or you can add the tables to the form's data environment. Either way, the tables will only be open in the form's own data session, which is good because it helps keeps each form self-contained.

Also, in general you don't need to do OPEN DATABASE or CLOSE DATABASE. When you open a table, the database (if any) will be opended automatically if it's not already open. But there are occasions where you might need to explicitly open and close the database.

Does that answer your question?

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Hi MikeLewis,

in a form, I let the user do the entering/editing in journalEntry table and also inside this form, there is a commandButton to do the sorting/packing unused record of journalEntry....

I think this is a mistake... should let the user exit the journalEntry form then do the sorting/packint at the mainform (window).

If an table with index is running, can we sort that table ?
that table is also attach to a grid.

please help, not sure what to do....


ok, subprogram is a function in the same file as main.prg

and all the tables will be close if we exit from a form ?

thanks, all of you are very helpful.

thanks jrbbldr, I will taka good look at it..

have a nice day..
 
Ask 4 Foxpro programmers how to do a main.prg or application start in general, and you get 12 answers ;).

When using an application framework to build your application it's simpler, as you simply apply to the rules of that framework.

Even though the FFC "framework" and wizards coming with foxpro are in general not a good one, you can have a look at the project templates in the component gallery. You find it in the Tools menu.

Start it, then choose Visual Foxpro Catalog->Templates->Applications

Choosing the Books Template, specifying a project name "mybooks" and a directory where to generate this you get a main prg named as you name the project in the code tab.

This could be a starter. It has some good things in it, like setting an errorhandler and creating an application object.

Some things are not that obvious, as they are done within that application object goApp or better said are coded in the cApplication class. For example the main menu and main form are shown in the show() method of the cApplication class and the READ EVENTS is in there, too. Actually quite clever.

One thing in a typically main.prg also is the end code of the application. The template projects have a cleanup routine in their main.prg I wouldn't do. I prefer ON SHUTDOQN QUIT instead of such a cleanup routine, as most things are done automatically anyway on exit of the foxpro runtime, like closing all file handles to tables, databases etc., rolling back all open transactions and more. Even in case of an ungracful shutdown via C5 error.

I rather prefer a decent Destroy code in the individual classes, which means holding on to the OOP principle of encapsulation of course. If a class or an instance of it does not know how to cleanup itself, then who should?

In general going the oop route, you can put quite much of such a main.prg into an application class instead of doing it seperate before going into "OOP mode" so to say.

But one thing is actually very strong and stable: Because the main.prg is the start and does not finish (or else the application would exit right away), it's the one thing always on the call stack (see SYS(16,0)).

Any private variable you set here is quasi public. That also is true for procedures and functions and class definitions in main.prg, nevertheless this does not mean to put everything into it you could use in general, keep it lean.

If you want a procedure ON SHUTDOWN triggers, this should actually be in here, as you can be sure nothing but the runtime exit puts that code off the stack. In contrast: A false CLEAR CLASS in your code, and some cleanup class would fail to instanciate.

Basics are of course setting up errorhandling and shutdown behavior, environment settings, classlibs and procedures. But all this could also be done by objects, either goApp or subobjects of it.

Eg setting classlibs could also be done by a factory (see design patters), which is an object used for all other object generation throughout the whole application.

Also environment settings (SET commands) I'd not do in main.prg, but in a class which does store the previous values in it's init and reverts to these values in it's destroy. This also helps repeating the settings in any private datasession, as some settings are done per datasession.

No matter where you put things, of course you need some things done in the right order, eg READ EVENTS as last thing of the start (but of course any finishing code afterwards, if you want).

First I'd be caring for errorhandling and shutdown (either QUIT or some cleanup), then you need some way of setting classlibs - unless always working with Newobject() - and procedures, before you can create an object, of course.

Then you make some environment settings, directly or in an object. Finally start a menu (if), start a main form (if) and READ EVENTS. And don't forget you need something to also trigger CLEAR EVENTS.

Bye, Olaf.
 
inside this form, there is a commandButton to do the sorting/packing unused record of journalEntry....

There's never a reason to sort any VFP table. If you need to access the data in a particular order, either create an index for that order, or use SQL SELECT to create a cursor with the data in the order you want. Indexes are used for general processing. Queries (SQL SELECT) are used for reporting or when you need to extract some data from a table as part of a larger process.

As for packing, that should be done as rarely as possible, and thus definitely doesn't belong in your form. Remember that packing tables requires exclusive access, so all other users need to be out of the application. Packing should be an administrative option that gets run once a month or once a year or something like that.

Tamar
 
As for packing, that should be done as rarely as possible... once a month or once a year"
The topic of PACKing probably deserves another thread, Tamar, but since it's been mentioned here - here's my 2 cents:

It all depends on the file size of the DBF and - most of all! - FPT files. With the latter, there's always a danger of what's called "Memo bloating". But even without that, if one's program is supposed to process and/or store large amounts of data - "memento mori" (that is 2GB limit)!

Therefore, it would be wise to include some "watchdog" utility into your program (can be a class) that would check the beforesaid files' sizes, and either warn the user "Your table files are close to 2GB limit, maintenance is due!" Or - "You have 20% (or whatever the arbitrary number) of the records marked for deletion, maintenance is due!" Thus, PACKing may be needed once a year but, if you're in data processing business, it very well may be every 3 days, depending - again! - on the volume of data processed and stored.

Yours truly struggled with this 2GB limit for many years, while working for the data archiving company, and I am speaking from experience. So - set the rule, write a program and PACK it when you need it, colleagues! ("I grant you my permission to PACK, ladies and sirs." ;-) )


Regards,

Ilya
 
While somewhat off the original posting question, but still related to a subsequent topic that Johan raised.....

Ilya - "Thus..., PACKing very well may be every 3 days"

If this were the situation, then some SERIOUS thought should be put into examining the data table Architecture for appropriate table Normalization and/or Archiving off a good portion of the data (as Ilya struggled with) into another table.

While not 100% applicable, in most cases, by doing either of these it should greatly reduce the individual table (and associated CDX & FPT file) sizes and reduce the need to PACK.

And for those occasions where not applicable, changing to another database 'backend' such as SQL Server would eliminate the 2GB limitation - although queries into those 'backend' tables would still be limited to < 2GB results.

johan - Good Luck,
JRB-Bldr
 
I'm with JRB on this. If you have an app that requires packing every 3 days, then something in the architecture ought to be changed.

Remember that, for a DBF, packing only matters if you're deleting records. Ilya, you mentioned memos. A combination of SET BLOCKSIZE and a strategy that writes to the memo as few times as possible (that is, build the string and do a single REPLACE) should keep memo bloat under control.

If there's so much traffic to memos that the FPT is constantly butting up against the 2GB limit, then a server back-end may be a better choice.

Tamar
 
Tamar, Johan,

I was talking about creating the customer's data archives, not archiving the data. The difference being that customer needs to have all the data for certain period back from today, like auto or home insurance policies, claims, delivery slips, individual time sheets (for H/R dept.), handwritten documents and such. All these meant - scanning and saving images into a memo file. And, if it was, again, an insurance company, then it's 7 years retention period, meaning they have to keep 7 years worth of data as an active data (and I even do not know what is the retention period for the legal and/or lawsuit data).

Yes, we had found the way around this 2GB issue, and that was not my point. It was when we added (APPEND FROM), say, a dozen files, totalling 200 MB worth of data, into a 1.3 GB Memo file - and all of a sudden it was 1.9 GB in size! This is what I am talking about. So, I had to run PACK and/or PACK MEMO after every data merging session.

And that is not it: one of our big customers (certain fast-food chain's H/Q) always requested to delete some data that was already merged 10-15 days ago (and we processed their data 2-ce a week) and add the "corrected" data instead... I hope you've got the picture.

Anyhow, for you to understand in full where I'm coming from, you'd have to sit down with me and listen to me for 3-5 hours (trust me!) telling you about the business this my former company was in. 'Naf said!

Regards,

Ilya
 
all people in this forum are very helpfull. Thanks alot...

Happy Valentine!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top