Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Clarion's process template is a great tool for any kind of procedure that requires stepping through a filtered or unfiltered set of records. A little while ago I had a request to extract some data from a file, simply by stepping through records in primary key order, and my first thought was to go with a process template. But I also had a requirement to potentially restrict the records to a specific range of primary key values. So that meant popping up some kind of window to collect filter values. 

As I was processing records in primary key order I decided I could do everything more simply with a window procedure. And it turned out to be even easier than I expected, thanks to some useful progress bar property statements. I'll get to those a little later. 

In this article I'll show how to add a similar procedure to the venerable People.app. 

I start by adding a button to the browse from which I want to call the export process. (I won't actually do any exporting in this example; instead I'll just display data from the records I process.) I set the Action of that button to call a new procedure, which I create using the Window template. Feel free to use the Window wizard if you're more comfortable with it - the only difference is that the wizard lets you set styles and will create the window for you; with the template you'll create the window the first time you go to the window editor. 

I need the following elements on the form:

  • a starting primary key value
  • an ending primary key value
  • a progress bar
  • a start button
  • a cancel button

and just for fun:

  • a pause button

Here's the form with the UI elements complete:

Since this process won't do anything other than loop through the records (the XML export that inspired the original procedure is outside the scope of this article) all I'm doing is displaying the current record on screen. 

Changing control types

If you have entry fields you'd rather show as strings on a window, populate them as you normally would. The use the ellipsis button to edit the window definition directly.

Simply change the ENTRY to a STRING - everything else on the line can stay the same.

Once you get comfortable with Clarion Window structures you can make all kinds of changes. One I make regularly is change entry fields to spin boxes. It's less work than populating a new control and changing the use variable.

Setting up for sequential processing

When the window opens up, any timer event code will execute because I had to set a Timer attribute on my window in order to get the Event:Timer embed point. So I need to disable the timer. Right after Self.Open(WINDOW) I add this code:

    0{prop:timer} = 0  

The value of 0 before the property assignment means I am assigning to the currently active window. I could also use 

    Window{prop:timer} = 0  

but "0" takes less typing. And if you're ever writing code that needs to apply generically to a window using 0 means you don't need to know the window label. 

I have a little more setup code that executes around the same time (actually just before opening the window):

WindowManager Method Code Section priority 7800
    FirstPeopleID = PEO:ID
    clear(PEO:ID,1)
    set(PEO:KeyId,PEO:KeyId)
    previous(people)
    if errorcode() 
        LastPeopleID = 0
    else
        LastPeopleID = PEO:Id
    end
    clear(PEO:RECORD)

This code:

  • assumes the first record I want to process is in memory, and saves the ID of that record in FirstPeopleID
  • primes LastPeopleID with the hightest ID in the file 
  • clears the record so nothing displays when the window first opens

Using timer events

I'm going to use a timer event to step through the records I need to process. This is typically how Clarion reports and processes work,  - by processing a set number of records on each timer event the UI can remain relatively responsive and react to cancellation requests. 

The Event:Timer embed point only appears when the window has a Timer attribute, so be sure to set that value. Any non-zero value will do. 

Here's the Event:Timer code:

        next(People)
        if errorcode() or PEO:Id > LastPeopleID 
            0{prop:timer} = 0
            post(event:closewindow)
        else
            ?Progress{PROP:Progress} = PEO:Id
        end

 

When the start button is clicked this code executes:

?StartButton, Control Event Handling priority 8500
        TimerInterval = 50
        PEO:Id = FirstPeopleID
        set(PEO:KeyId,PEO:KeyId)
        0{prop:timer} = TimerInterval
        ?Progress{PROP:RangeLow} = FirstPeopleID 
        ?Progress{PROP:RangeHigh} = LastPeopleID
        disable(?StartButton)
        enable(?PauseButton)

First I set a local variable which is the value that will be applied to Prop:Timer. There are two places this happens (as you'll see); I use a local variable so that if I want to change the value I only need to do so in one place. A value of 50 means the timer will execute every half second, which is probably a lot less frequent than I'd really want it to happen but it allows the process to at a good demonstration speed. A common technique, and the one Clarion apps use, by default, is to process a fixed number of records for each timer event. 

 

 

  • No labels