Category Archives: Foxpro

Table based definition of Parent-Child relationships in wwBusinessPro

The wwBusinessPro data access library supports table-based definitions of the Business Objects used in an application. This also allows you to define Parent-Child relationships between the records and tables in your app.

You can download wwBusinessPro from the project hosted on BitBucket.org.

The default table name for the Business Object definition table is “wwBusinessObjects”.dbf”. Just make sure the Path includes the location of this table, and run the form “wwDictionary.scx” to open and edit the rows in this maintenance form.

Here is a screenshot of the Business Object Dictionary form included in wwBusinessPro:

SNAGHTML201d0768

Visual FoxPro on Windows 8

Want to know if Visual FoxPro 9 will run on Windows 8?  Well, find out below…

I downloaded the Windows 8 Developer Preview the first evening that Microsoft made it available to the public. I had watched the BUILD keynote during the first day of the conference on September 14, 2011, and I was impressed with most of what Microsoft has done on the developer platform for their new OS. So, sure, Windows 8 looks all cool and I am sure we’ll all have some fun building these new “Metro” style apps for it. I’m looking forward to it, just as I’ve looked forward to every new programming journey I’ve tackled lately, like learning C#, WPF, ASP.Net MVC, and Ruby on Rails. I love it all. Bring on more!

However, I am a long-time FoxPro developer, and I imagine I’ll still be developing and maintaining my primary corporate app in FoxPro for a few more years, so I wanted to make sure that Visual FoxPro 9 SP2 + HotFixes would install and run properly in Windows 8. Let’s see if it does (I’ll give you the answer now…. It does!)

image

According to http://fox.wikis.com/wc.dll?Wiki~CurrentVersion~SoftwareEng , the latest, fully patched version of Visual FoxPro 9 is 09.00.0000.7423.

image

So, the answer is YES, Visual FoxPro 9 SP2 works in Windows 8.

Now, I’m just waiting for the release of the “Metro for FoxPro” framework on VFPx. Anyone?

 

Anyone?

I Love Me Some Business Objects

Here is the beautiful stack of Business Object classes for my Line of Business CRUD app (see image below).

The Job object (highlighted in the screenshot), in particular, is populated with tons of little worker methods to handle all the processes my Job oriented forms need. Most of these methods were created by taking little bits of procedural code from various forms and procedure files that had become strewn about all over my app code, and tucking it away into methods on the Job class.

Now, I can easily create a Job object with one line of code, and then call any of its handy methods to quickly create a cursor containing the desired child records, or return a value from some other calculation, or any other tasks that my business app needs to handle. 

So follow this rule: If you’re writing processing code in form methods or methods on UI controls (yikes!), you should consider creating a Business Object and adding methods to it instead. It will be much more re-usable and maintainable.

 

Code sample:

oJob = CreateBusObject(‘Job’) && Call a Dictionary method to get the class

oJob.Get(‘TheJobNumber’)

If oJob.lFound = .T.

   oJob.GetLineItemsForInvoice(‘CursorName’)

Else

   *– Handle Not Found situation

EndIf

 

SNAGHTML9aff7fe7

Creating a Parent Business Object with wwBusinessPro

When using a wwBusProParent, you set properties on the Parent that tell it about the Child class.
Then, the Parent will create the Child class for you.
You do not create the Child when writing your code, let the Parent do that.

You need to create a VCX library and put a Child class for each Child collection in there,
with its Child properties already set up. This allows the Parent to create the Child when he
needs it. If you follow the path of the Get() method, you will see that the Parent creates a
Child class object and attaches it to its oLineItems property. So, once your Child classes are
configured in a VCX, you will not actually have to write any code to access them (unless you are
doing some special case, custom coding), you just set up the Parent so he can find them.
The Parent will handle all that for you, including the fetching of the related Child records.

You can also put your Parent objects in the VCX and set their properties in the VCX file.
This sample code is shown here simply to show which properties are required to make it all work.


*=================================
* == Sample to  show a Parent BO configured to use a String lookup and work with related Child Records
*=================================

Local loSrHead AS ‘cSrHead’

Set ClassLib To MyMainLibrary Additive
Set ClassLib To MyBoLibrary Additive  && Include your Business Object ClassLibrary

loSrHead = CreateObject(‘MyInvoiceBoClass’) &&  A Parent class found in your BO Library VCX

*– These settings are native to the base wwBusiness operation
loSrHead.cFileName = ‘tblSrHead’ && The table name (.dbf file or Sql Server table name)
loSrHead.cAlias = ‘csrSrHead’  &&  Local alias name to use when opening file
loSrHead.nDataMode = 0  && Data access mode for the business object. 0 – Native Fox dbf, 2 – SQL Server
loSrHead.cPKFIeld= ‘PK’    && Points to the unique Key value column in the table. Usually an Integer column.

*– This code section is part of wwBusinessPro feature set wwBusinessPro allows for String-based lookups and related Child cursors…
loSrHead.cLookupField = ‘storeno+docno’  && This is an example of a compound string unique key lookup value.
loSrHead.cAdditionalFilter = ‘mtype = [0]’  && (Optional) Provides a way to further filter the record locating process.
loSrHead.cPKFIeld= ‘storeno+docno’           && Set to same value as cLookupField if no Integer PK is available in the table.

loSrHead.lLoadLineItems = .t. && Tells it load Child records when getting the Parent record.
loSrHead.lAllowEditLineItems = .t.  && Tells it create a ReadWrite cursor when creating the Child record cursor

*– Setup the Child properties on the Parent
loSrHead.cLineItemsClass = ‘cSrItems’  && Child class must exist in the MyBoLibrary.vcx
loSrHead.cLineItemsAlias = ‘curSrItems’ && Cursor name where you want the Child records to be stored

*– Fetch the Parent and create a Child Cursor
loSrHead.Get(‘TWU STORE RN2009100003’) && For String lookups
loSrHead.Get(12345) && For Integer lookups

If loSrHead.lFound = .f.
*– Add any Not Found handling code here
Endif

If loSrHead.nErrorCount > 0
*– Add any Error handling code here, if not already handled in your classes.
Endif

*– Make some changes to the loSeHead.oData object and to the Child cursor
*– and save the changes…
loSrHead.Save(.t.) && .t. Tells it to save changes to the Child records also

 

One more thing about the Child classes…

When setting up your Child in the VCX, these are the properties you need to set on it:

cFilename (Required. Name of the dbf or Sql Server table)
cAlias (Optional. Will use cFilename by default)
cPKField (Must be an Integer. See “Important Note” below)
cFKField (Must be an Integer. Maps to Parents PK field)
cLookupField (Optional. Maps to Parents cLookupField. Use when Parent uses for String lookups)
cOrderFld (Optional. Can be used to set the ordering of child records. i.e. a sequnce field)

These properties provide the info needed by the LoadLineItems() method work out of the box.
Sometimes you may want to overwrite the LoadLineItems() method with custom code, but the default
should work in basic configurations.

IMPORTANT NOTE:
In order to save changes on the Child records, they need a unique PK that can be used. See cPKField.
String cLookupField works fine to load the records in, but it does not guarantee uniqueness when
trying to save changes back.

Again, you can use cLookupField Stings for loading the records, but you must have Integer PKs
on your Child records to allow saving changes back.

wwBusinessPro–Parent Child collections in a wwBusiness business object

Note: This post if part of a complete series on the West Wind wwBusiness library.
Click here to see the full index

 

Before we start digging into parent/child data access with wwBusinessPro, let’s have a review of the basics. Suppose we want a Invoice object, and child set of Invoice Line Items that belong to that invoice. This is possible, even simple, with wwBusninessPro. In fact, in this post I’ll also show you how to handle a second child collection, like Invoice Payments, related to the Invoice. If you follow the example shown here, you’ll be able to handle cases where you have a single business objust with MULTIPLE child collections.

For example, here is what a really complex “aggregate” business object can look like. In my main business app, I have one complex business object that loads 4 additional child cursors in addition to the base oLineItems collection, and, it also loads customer and user info into oCustomer and oUser objects that I added onto the BO.

clip_image006

So let’s get started…

Parent and One Child Cursor

Parent class – Create your Invoice class as subclass of wwBusProParent.

At this point, you will see that it has *ONE* child collection object and related properties already built in. The oLineItems object will hold a object reference to the child item class. To make it active (so that it fetches child records every time you fetch a new parent object), you will need to set the cLineItemsClass, cLineItemsAlias, and lLoadtems properties.

The cLineItemsClassproperty points to a lineitems class that you must define in your VCX and it holds the table name of where the child records live and the key field name which links it to the PK on the parent.

The cLineItemsAliasproperty is the name of the cursor that where the child records will live.

Finally, be sure you set the lLoadLineItems property to .t. to make sure the main BO will load the line items each time you call the Get() method on the Parent.

Child Class – Create your InvoiceLineItems child class as a subclass of wwBusProItemList.

Set the properties cFilename and cFKField, which identify the Child table, and the field in the table that links back to the Parent PK in the invoice class.

So that’s it.  You’ve just set up the built-in functionality for the wwBusinessProParent class to handle the Parent BO and its set of child objects.

 

Need to handle MULTIPLE sets of child records?

Let’s say you also want to fetch all InvoicePayments records every time you load up an Invoice object…

After you’ve configured your “Invoice” and “InvoiceLineItems” classes as described above, and add the following properties and one method to cover the “Payments” collection:

New Properties:

  • cPaymentItemsClass
  • cPaymentItemsAlias
  • lLoadPayments
  • lAllowEditPaymentItems (optional, but something I include on my so I can enable or disable stuff in the UI layer)

New Method:

  • GetPaymentItems()

Now you need write two simple code blocks:

1. To populate the PaymentItems cursor (in addition to the LineItems cursor) every time you fetch an Invoice, you need to override the LoadRelatedData() method on the Invoice class like this:

 image

 

2. Define the GetPaymentItems() method like this:

image

That’s it.

Once you have brought this Invoice object to life, you will have 3 classes in your VCX:

Invoice (based on wwBusProParent)

InvoiceLineItems (based on wwBusProItemList) (this is what the default oLineItems will point to)

InvoicePaymentItems (based on wwBusProItemList) (this is what the above new properties and methods will point to)

When complete, your “Aggregate” Invoice Business Object will look like this:

Invoice

.oLineItems

.oPaymentItems

I know it might seem complicated at first, but once you understand what’s happening, it really not hard.

FoxPro Report FRX Table Structure

Visual FoxPro 9 Report (FRX) Table Structure

Here is a link to a table showing all the field names and details for Visual FoxPro 9 Report (FRX) files. This table also applies to Label (LBX) files.

Click here: FoxPro-Report-FRX-Structure.html

The HTML table in the above link was generated from the 90Frx.frx report in the Tools\Filespec folder of the Visual FoxPro installation folder.

Preview:

7-6-2011 10-07-41 PM

Here is a nice article with some deep technical info on advanced programming of Reports in VFP 9:

http://spacefold.com/articles/RSFundaments_part1.aspx

FoxPro Report FRX Table Schema

Here is a basic view of the table schema, but it does not contain all the field details of the full report above. 

The schema contains 75 fields:

Field Name Data Type
PLATFORM C(8)
UNIQUEID C(10)
TIMESTAMP N(10)
OBJTYPE N(2)
OBJCODE N(3)
NAME M
EXPR M
VPOS N(9,3)
HPOS N(9,3)
HEIGHT N(9,3)
WIDTH N(9,3)
STYLE M
PICTURE M
ORDER M
UNIQUE L
COMMENT M
ENVIRON L
BOXCHAR C(1)
FILLCHAR C(1)
TAG M
TAG2 M
PENRED N(5)
PENGREEN N(5)
PENBLUE N(5)
FILLRED N(5)
FILLGREEN N(5)
FILLBLUE N(5)
PENSIZE N(5)
PENPAT N(5)
FILLPAT N(5)
FONTFACE M
FONTSTYLE N(3)
FONTSIZE N(3)
MODE N(3)
RULER N(1)
RULERLINES N(1)
GRID L
GRIDV N(2)
GRIDH N(2)
FLOAT L
STRETCH L
STRETCHTOP L
TOP L
BOTTOM L
SUPTYPE N(1)
SUPREST N(1)
NOREPEAT L
RESETRPT N(2)
PAGEBREAK L
COLBREAK L
RESETPAGE L
GENERAL N(3)
SPACING N(3)
DOUBLE L
SWAPHEADER L
SWAPFOOTER L
EJECTBEFOR L
EJECTAFTER L
PLAIN L
SUMMARY L
ADDALIAS L
OFFSET N(3)
TOPMARGIN N(3)
BOTMARGIN N(3)
TOTALTYPE N(2)
RESETTOTAL N(2)
RESOID N(3)
CURPOS L
SUPALWAYS L
SUPOVFLOW L
SUPRPCOL N(1)
SUPGROUP N(2)
SUPVALCHNG L
SUPEXPR M
USER M

Go To File – A quick Open File dialog for Visual Foxpro

Here’s a new tool I’ve written for Foxpro to add a cool feature for quickly opening a file by entering part of its filename. It’s a fast heads-down way to navigate files in your Project or the Current Directory. Just type a few characters of the filename and it will begin to filter the list of files based on a partial match. When you see the file you want, just click on it, or use the arrows keys and press enter. You can also filter on basic file types such as SCX, VCX, PRG, and FRX.

Think of it as a quick way that you can tell FoxPro “Hey, I want to open a file… I know part of the filename, but I want you to find it for me.”

For now, you can download it here: Download GoToFile.zip (Note: future updates may be posted on VFPx in the Thor Tool Repository package.)

Please send comments or suggestions to me in the comments area at the bottom of this post.

This tool is just a basic FoxPro form that can be invoked from the command window, added to your custom menu, or invoked by a keyboard macro. However, I recommend invoking it with the new Thor add-in manager for Visual Foxpro. You can learn more about Thor here: Thor add-in manager for Visual FoxPro. Once you have Thor installed in VFP, you can just drop these files into the “Tools” folder and then you will see GoToFile in the tool list where you can easily assign a hotkey to it.

 

SNAGHTML6beaf702

FoxPro class to generate SCCText for all files in a Project

Version control for FoxPro source code

If you want to place your FoxPro source code files in a Source Code Repository of some sort, you usually need to generate text file versions of your table-based FoxPro files like SCX, VCX, and FRX. These text versions of the binary FoxPro files are necessary for the versioning features of code repository tools work properly. FoxPro is unique in having binary source code files in a projects, whereas most other languages use raw text for all of their code files.

We’ve long had a tool to generate these text versions of our Forms, Classlibs, and Reports (see the updated SCCText app here: http://vfpx.codeplex.com/wikipage?title=Alternate%20SCCText). However, using this file is still a tedious way to get your SCC files generated if you try to do it by hand. Sure, the FoxPro IDE can hook into this app if you set it all up and are working on one of the source control systems that VFP was natively designed to work with. But VFP is getting kind of old, and there are many options that exist today the VFP simply cannot work with out of the box.

I recently wanted to use the Mercurial source control repository to manage the development of my GoFish 4 Code Search project. I set up a free project hosting account on BitBucket.org and installed the Tortiose Hg software on my Windows machine, and then I was able to commit code changes to this magic repo in the sky and share it with the whole world.

Sadly, VFP does not have support for this newer Distributed Version Control System, so I can’t “hook up” FoxPro to use SCCText and then “check in” my code in the VFP way.

VFP Version Control with Mercurial

Rick Borup presented a session at SWFox 2011 on using Mercurial version control with FoxPro source code. You can get a free PDF copy of the whitepaper here:

http://www.ita-software.com/papers/Borup_Mercurial_Published.pdf

The CreateSCCText Class

To automate creation of the SCC files, I have created a custom class with a method that recursively calls SCCText for each file in a VFP Project. It’s a snap to use this simple class in a PRG and run it each time right before you commit  changes up to your repo. You can also create a ProjectHook class and include a call this class in the AfterBuild(). It will then automatically create updated SCC files every time you build your VFP project.

It’s DateTime aware for each file, so it will only re-generate the SCC files if the date of the VFP source file is newer than the existing SCC file. This way, when you post your commits, you’re only pushing up SCC files that have changed since the last push. There is also support for skipping over certain files that you may not want to process with SCCText.

I owe a lot of credit to Paul for getting me started on that SCCTextGeneration stuff.  He gave me some helpful code in a UT message when I asked a question about running a process on every file in a Project.  He basically gave me the code to do it in his reply (see message# 1507894).  I just bundled it all up in a class/module and made some noise about it.

You can get the source code for this simple class here: http://codepaste.net/9yy1gm

Other sources for getting and using SccTextX

*UPDATE*  Here’s newer way that I’ve begun to automate the generation of text files from the FoxPro binaries – *before each commit*, I run this code below which calls a Thor Procedure to generate the text files from the pass project (I wrote this Thor Proc and passed it on to Jim and he included it in Thor.)  You can get Thor Tool Manager for FoxPro from the VFPx site. It adds lots of great developer tools to the Visual FoxPro IDE.

 

 

Basically, you pass in your project path, and it generates the text files by calling a slightly modified-for-Thor verison of SccTextX that we’ve included with Thor.

Writing tests for Business Objects in FoxPro

I’ve blogged before about converting my FoxPro apps from application forms to the Business Object based programming approach (thereby moving away from forms based heavily on open tables, work areas, and relations). I used the West Wind wwBusiness classes to make this transformation, and it is the most exciting VFP work I have ever done. A Business Object framework like West Wind wwBusiness automatically gives you basic niceties such as methods like Load() and Save() right there on the BO to do all the back end data handling for you. This feature alone allowed me to greatly reduce the amount of code I had piled up in click events all over my *forms* for many years. No more worrying about the the record pointers, or relations, or binding my form UI controls directly to table names and fields. I promise you, once you go BO’s you’ll never go Back!  (Don’t get sidetracked from this post yet, but you can read my original review of the West Wind wwBusiness library here.

Another benefit of BO classes is that you can now programmatically drive your application’s activities by making method calls into the various methods on the BO. No UI forms required… Just good old procedural code! For instance, on my Job Business Object, I have lots of methods to fetch records into a local cursor, array, or collection, as well as other methods that change or examine data on the BO, or return scalar values, etc.  I started out forcing myself to  test my BO’s from the command line to make sure I could manually orchestrate everything I wanted my forms to do. This would ensure that it would require very little code in the UI forms to make the app work. With all the essential code tucked away in methods on BO classes you can then basically create the same app in SCX Forms, or web frameworks, or just good old procedural programming in various PRGs. Plus, the ease of maintenance improves greatly, since all your code lives in one class, rather that splashed all over the place inside a form.

So I’ve had this vision, after hearing more and more about all this “Test First” buzz in other coding circles like .Net and Rails, that I could write a suite of PRGs that serve as tests I can run at any time on my entire collection of BO’s. This allows me to immediately test every BO in my library any time I make code changes anywhere in the class hierarchy, or even if the table schemas changed too. I can’t tell you how many times I’ve made low level changes in the base classes, or added a new top level method to a concrete class, or changed a field name in a table, and the only real way I’ve had to test the changes is to throw out a beta version of the app, and drive it around like a real user to see if it works correctly, or has errors.

 

Here is a peek at one of my Business Objects; the “Job” Business Object which is a vital part of many forms in my app. There are perhaps 20 or more granular methods that can be called to do all kinds of fancy stuff on a Job in our system.

Every method  can be called directly from the Command Window, or from methods in forms, or from within PRGs. Just create an instance of the Job object, and off you go. Most of this code once lived in a SCX form somewhere, until I pulled it all out and put it in this Job Business Object.

image

And shown below is a sample of the test code I have written which creates a Job Business Object, and then tests a particular method (the GetActiveJobs() method in this example). You’ll see in the comment that this method can accept up to 5 parameters, so I’ve written tests for many possible combinations of parameters and values. Even with this many test calls, I’m sure there are a few combinations that I may have missed. This shows how tedious a full test suite can become. In this testing approach, you basically *TRY* to break your code by passing in every possible combination of parameters that these business classes might see in real application usage. Remember, you want to write these classes with the idea that you or someone on your team will be working with these classes for years, you simply expect them to work without knowing all the do’s and don’ts about calling into these methods.

SNAGHTML19918d5

What you don’t see here is that the test method calls likes BeginningOfTest(), TestProgress(), and EndOfTest(), record logging info to a results file that I can then review to study the return values, processing time, etc.

Now, the bad thing is that if I complete this exercise, there are perhaps 20 or more methods that I must write tests for, and that’s just on the Job Business Object. Then I’ll have to tackle all the other Business Objects in my libraries (PurchaseOrder object, Quote object, Part object, etc. About 15 Business Objects in all). So this is no trivial amount of work, and you have to remember to write a test for every new method you add to a Business Object, otherwise, you’re letting the thing fall apart. It’s very easy to look at your code and think you’ve got everything or every situation covered, but certainly creating a formal test suite for your classes will help identify problems before you take your app to production. Oh, you’ll also notice that CreateWWBO() is a factory method that returns a Business Object based on the passed key, so there’s some other coding in my architecture that resolves this tag and the class name as well as the class library.

And here is the output to the log file. If there were any errors returned from the Business Object, or if the return results were not the expected results, then I’d see reporting to this effect in the log file. Now, there is some coupling here between these tests and test data that I’m running against, so the test could appear to break if some of the test data changed, so this is no magical solution and requires some attention to this detail when preparing and running these tests. To me, the main effort is to find broken code in the classes given a predictable data set.

image

 

This is just one code sample. I have other tests that test the basic Load(), New(), Save(), and Delete() methods as well.

 

By the way, you can read my original review of the West Wind wwBusiness library here