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!

Assigning child tables

Status
Not open for further replies.

woodyinoz

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

I am currently running a form in which I specify the master table to be used in a table frame.
However, I would now also like to specify the tables to be used in the child table frames.....
Is this possible and if it is how do I do it?! If anyone can think of a work aroud for this then I'd be very grateful!!

Thanks,

Woody.
 
I'm not really clear on what you want. Are you trying to do this progammatically? If so, look at dmAddTable(). It looks like the example there could be easily changed to do what you want.

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,

It is possible, but it can be a pain to set up and pull off.

I know of two main ways to approach this:

I. Replace the data that's presented by the detail table in the data model.

II. Actually swap the detail table at runtime

The following looks at each approach in more detail.


I. Replacing the Data:

The first approach assumes that your different details tables share the same structure. In this case, you don't actually replace the table in the data model, you replace the data presented by that table.

The basic idea is to

1) Devise a mechanism for selecting between the tables, such as a menu or a set of button.

2) Use ObjectPAL to empty the current contents of the detial table.

3) Use ObjectPAL to add the data from the new table into the table that's in the data model.

This is usually done by creating a temporary table in the user's :pRIV: folder and adding that to the form's data model.

You have to be careful in setting this up, for you need to make certain that your development system actually contains a compatible copy of the temp. table in your own :pRIV:. Otherwise, you'll run into errors when you try to modify or update the form.


II. Replacing the table in the data model:

Now, if the detail tables you're trying to choose between have different structures, then you need to actually remove the old table from the data model, add the new table to the data model, and then bind the data aware objects to the new table.

The following walkthrough demonstrates this technique using the "classic" Paradox tables, e.g. CUSTOMER.DB, BIOLIFE.DB, and so on. It's pretty involved, so please be patient and take your time. There are three main "phases" of the walkthrough:

-- Phase 1 creates a table for the demonstration. We'll use the existing Customer and Orders tables, but we need another table to swap Orders with.

-- Phase 2 lays out the initial form design. It looks worse than it actually is.

-- Phase 3 adds the code for this technique. It's a fairly straightforward process, but you need to perform some specific tasks, so review it carefully to understand what's going on.


Phase 1: Creating a table to display.

1. Change your working directory to the one containing the classic Paradox samples, e.g.

2. We need to create a table we can use for the example. To do that, create and run the following QBE query (be warned, it's a bit hairy):

Code:
Query

ANSWER: :PRIV:ANSWER.DB

FIELDORDER: customer.db->"Customer No", lineitem.db->"Order No", 
            lineitem.db->"Stock No", lineitem.db->"Selling Price",
            lineitem.db->"Qty", lineitem.db->"Total"

lineitem.db | Order No  | 
    Check   | _on       |

orders.db | Order No | Customer No | 
          | _on      | _cn         | 

customer.db | Customer No | 
            | Check _cn   | 

EndQuery

3. Run the query. You should have an ANSWER table containing 1037 records. Make certain that "Customer No" is the first field your Answer table. If not, use Query | Properties to control the structure and then re-run your query.

4. Now, we need to rename ANSWER to make sure it sticks around. Use Tools | Utilities | Rename to rename :pRIV:ANSWER to :WORK:CUSTITEMS.

5. Next, we need to define a primary key for CUSTITEMS. Use Tools | Utilities | Restructure to key the first three fields of CUSTITEMS. Make certain you choose all three fields as the primary key; otherwise, you'll lose records.

Got that? Good. Now that you've created your new table, you now have a detail table you can swap.

Phase 2: Creating the initial form layout:

To demonstrate this technique, we'll create a form that shows all orders for each customer or all items ordered by a customer. (This is, BTW, why we created that table. It's a coerced example design to demonstrate this technique.)

OK, let's do the initial design work:

1. From the Paradox main menu, choose File | New | Form. When the New Form dialog appears, choose Data Model.

2. Add :WORK:CUSTOMER to the form's data model and then right-click the title bar of the table's field list.

3. When the shortcut menu appears, choose Table Alias, type master as the new alias, and then choose OK.

4. Add :WORK:ORDERS to the data model, set its table alias to detail, and then drag the field list so you can see both table field lists.

5. Use the mouse to link Master's Customer No field to the same field in Detail.

6. When finished, choose OK to specify initial layout for the form.

7. When the Design Layout dialog appears, choose the Tabular style in the Style panel and then choose OK. This provides the form with two table frames, one bound to each table in the data model.

8. Select the bottom table frame and change its Name property to tfDetail.

9. This is a good time to save your form. Please do so.


Phase 3: Adding the code that makes this work:

Now, we're finally ready to demonstrate the technique:

1. Drop a button on your form and change its label to Show Items.

2. Add the following code to the button's pushButton event():

Code:
   swapDetail( ":work:custitems" )

3. Add a second button to your form and change its label to Show Orders.

4. Add the following code to the new button's pushButton event():

Code:
   swapDetail( ":work:orders" )

5. Now, select the page object by clicking a blank area of the form and then press Ctrl+Space to display the Object Explorer.

6. If you don't see the tabbed pane on the right of the Object Explorer, choose either View | Tabbed Pane or View | Both from the Explorer's menu.

7. Choose the Methods tab and then double-click the <New Method> line.

8. When prompted for the name of your new method, type SwapDetail and then choose OK. This opens an editor window for your new method.

9. Update your method to use the following code:

Code:
method swapDetail( strNewTable String )
var
   astrField  Array[] String  ; Holds Linking field names
   fmActive   Form            ; The form running this code
   uiTFrame   UIObject        ; The detail table frame (TF)

   liX, liY,                  ; Upper left Corner of TF
   liW, liH   LongInt         ; Bottom right corner of TF
endVar

const
   k_ALIAS = &quot;detail&quot;
endConst

   uiTFrame.attach( tfDetail )
   uiTFrame.getPosition( liX, liY, liW, liH )

   ; remove references to table being replaced.
   uiTFrame.Tablename = &quot;&quot;
   dmUnlink( &quot;master&quot;, k_ALIAS )
   dmRemoveTable( k_ALIAS )

   ; add new table to data model and then
   ; bind the table frame to it.
   dmAddTable( strNewTable )
   dmSetProperty( strNewTable, &quot;Name&quot;, k_ALIAS )

   astrField.addLast( &quot;Customer No&quot; )
   dmLinkToFields( &quot;master&quot;, astrField,
                   k_ALIAS, astrField );
   uiTFrame.Tablename = k_ALIAS;
   uiTFrame.setPosition( liX, liY, liW, liH );

   ; Now, reset the &quot;dirty form&quot; flag, so
   ; the user doesn't accidentally overwrite
   ; our changes.
   fmActive.attach()
   fmActive.designModified = FALSE

endMethod

Please note a strNewTable parameter has been added to the declaration of the swapDetail method. You'll need to add this before your form will compile.

10. Save your form and then try to run it. Correct your code as needed.

When you run this form, you should be able to click either button to change the detail table on the fly.

I know it's a fairly long example, but I wanted to make sure it was as clear as possible under the circumstances.

Either approach works well, but you need to make sure you're using the one appropriate for the task.

Hope this helps...

-- Lance
 
Thanks both,

However, I'm not sure that any of the approaches listed are what I'm looking for..... The problem with creating a table in the :pRIV: directory is that multiple users may want to work on the same information at the same time across a network so they really need to be using the live tables.

Woody.
 
Actually you can have the form create the :pRIV: directory tables in the form method &quot;open.&quot; Alternatively you can have the tables created from the pushbutton method (if you are opening this form from another form) of the calling form.
 
Woody,

>> multiple users may want to work on the same information at
>> the same time across a network so they really need to be
>> using the live tables.

The second approach would support this.

Hope this helps...

-- Lance
 
Lance,

Can I use the second method if the child table is not linked to the master table through keyed fields?

The problem I have is that my master table is not keyed!

Woody.
 
Woody,

Sure, just remove the bits of code that manage the linking, e.g. dmUnlink and dmLinkToFields, though I'm fairly certain that only the detail table needs to be keyed in order to define a link in Paradox for Windows.

The key to my second approach is careful object design, which is why I had you assign table aliases to the table references.

You just need to make certain you remove all bindings to the second table (by setting TableName to an empty string) before trying to remove it from the data model. If any object is bound to the table, dmRemoveTable() fails.

Hope this helps...

-- Lance
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top