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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Removing a table from a datamodel to sort

Status
Not open for further replies.

woodyinoz

IS-IT--Management
Jan 8, 2002
215
GB
Hi all,

I am attempting to run the following code upon a form in order to remove a table from the forms data maodel, sort upon user specified criteria on the table and then add the table back into the data model.


method pushButton(var eventInfo Event)

var

strName String

endvar

strName = ("PartReport.db")

if dmHasTable(strName) then

dmRemoveTable(strName)

dlgsort(strName)

dmAddTable(strname)

endif

endMethod


The problem with this code is that it tries to run the dlgsort before the table has been removed, therefore telling me that the table is in use. Is there anyway I can adapt this code, adding some kind of segmentation, executing each part of code before the next is run.

Any help is much appreciated!

Thanks,

Woody.

 
Have you tried adding a sleep() statement after teh dmRemove to pause execution? I'd start with a big number first, like sleep(5000) - 5 seconds - then pare it down if it works. Mac :)

"There are only 10 kinds of people in this world... those who understand binary and those who don't"

langley_mckelvy@cd4.co.harris.tx.us
 
Woody,

As you've discovered, Paradox's interactive dialogs tend to get in the way of automated (ObjectPAL) approaches, for the dialogs wait until you close them while ObjectPAL continues processing in the background.

There are a few different ways to approach this:

1. Add code to get ObjectPAL to wait until after the Sort dialog goes away.

2. Take a different approach, one that doesn't use the interactive dialogs.

3. Create secondary indexes to provide the sort orders you want to use and then use the siwtchIndex code I gave you earlier to change the active index on the fly.

Based on your code (and from some hunches about what I think you're trying to accomplish), I still think the third approach is best--primarilly because it appears you want to be able to change the sort order from within the form you're viewing the data in.

However, if you want to try the second approach, here's how I see it working. The basic idea is to separate the process to a "ask then perform" approach, e.g. choose the sort order from a dialog box, open the form using that sort order, and then close the form to change the sort order.

Here's one way to do this:

1. Write down a list of of the sort orders you want your form to be able to handle, e.g. a list of fields outlining the sort order.

2. Design a query that selects all records from PartReport.db and sorts them in one of the orders you write down.

3. Save the query and then open it with Notepad to see how it recorded your sort order choices. It should be pretty straightforward, as saved queries (QBE or SQL) are simply text files and you can easily modify them on the fly by changing the text within the query itself.

4. Write a pushButton method that runs the same query from a QBE or SQL variable, as appropriate. Paste in the saved query to get the initial definition. This code will then use a formOpenInfo variable to change the form's masterTable to :pRIV:ANSWER.DB, as I outlined in my earlier messages. Get things working so it works with initial the sort order you've chosen.

5. Once everything's working, modify your code so the sort order is specified using a query variable (also called a tilde variable). Basically, cut the sort order specification, paste it into the definitaion of a variable, and then modify your query code to insert the contents of that variable into the actual query at runtime.

6. Next, determine the changes you'll need to set the query variable to the supported sort orders and add code to the process that updates the variable based on the user's feedback. You can use menus, drop down combos, or even radio buttons. (For examples, see the articles I pointed you to earlier; they should be easily adaptable.)

7. Work with it until you get it set up to change the sort order on the fly.

This will take some time, but once you've finished it, I think you'll have a better idea of how Paradox lets you break difficult tasks into smaller problems that are easier to handle.

And, yes, this is a lot of work--more than what you might do if you tried the index based approach I outlined earlier.

Part of the problem you're running into is that Paradox considers the data model to be fairly sacrosanct, e.g. once the form is opened, it really doesn't want you to muck about too heavily with the data model. Thus, the easiest way to handle problems like this is to find ways of changing the underlying considtions without changing the data model.

Yes, you can change the data model at runtime, but you need to be very careful about how you do so, for Paradox uses the data model to set up locking and relationships. So, it tends to resist changes to those assumptions.

Now, if you want to try the first approach, e.g. "pause" ObjectPAL while the sort dialog is active, you'll need to setup a condition that can be evaluated at runtime. A useful condition, in this case, is to see whether or not the top-most Paradox window, e.g. the one with focus, is the Sort Order dialog.

You can do this using a timer and a couple of functions from the Windows API. The following example demonstrates this by creating something that you can detect at runtime to see if the top most window is the Sort Order dialog.

1. Create a new form containing a tableframe bound to a table, e.g. PartOrder.db or one of the Paradox sample tables.

2. Drop a table frame on the form and bind it to the master table.

3. Drop a button on the form and then add the following code to its pushButton method:

Code:
method pushButton(var eventInfo Event)
var
   frm  Form
endVar

   frm.attach()
   dlgSort( frm.TableName )

endMethod

4. Drop an ellipse on the form and then add the following code to its open() event:

Code:
method open(var eventInfo Event)

   doDefault
   self.color = Green
   self.setTimer( 250 )

endMethod

5. Now, add the following code to the ellipse's close()event:

Code:
method close(var eventInfo Event)

   self.killTimer()

endMethod

6. Finally, add the following code to the ellipse's timer() event:

Code:
uses USER32
   GetActiveWindow() CWORD
   GetWindowTextA( hWndForm CWORD, winTitle CPTR, numChars CWORD ) CWORD
endUses

method timer(var eventInfo TimerEvent)
var
   hWndForm  SmallInt
   myResult  SmallInt
   winTitle  String
   numChars  SmallInt
endVar

   ;// get the caption of the top-most window
   hWndForm = GetActiveWindow()
   numChars = 255
   winTitle = fill( " ", numChars )
   myResult = GetWindowTextA( hWndForm, winTitle, numChars )

   ;// eval the caption and set the condition you
   ;// you can detect.
   if winTitle.subStr( 1, 4 ) = "Sort" then
      self.Color = Red
   else
      self.color = Green
   endIf

endMethod

7. Save, then run your form. You'll notice the ellipse stays green until you click the button. When you click the button, the Sort Table dialog appears and the ellipse turns red.

You may be able to use this in your existing code by simply testing the color of the ellipse after calling dlgSort.

The reason I didn't suggest this immediately has to do with actually incorporating such a loop into a production application. If you're not careful, you can create an endless loop that can only be terminated by terminating Paradox itself using Task Manager. This is very dangerous, for it can corrupt tables.

You need to be very careful to create a "fall-back" plan that terminates the loop. You also need to allow Paradox some time to actually sort the data after the dialog disappears. This is where the earlier suggestion of adding a sleep will be useful. You'll need to experiment with time to sleep (perhaps starting with five to ten seconds).

I don't like this particular approach for there are too many unknowns; however, it can provide a quick workaround so you can get things into use while you work on a more appropriate solution for the long term.

Hope this helps...

-- Lance
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top