RefreshAll error - no tData record avail (91)

Posted by doug.macmillan on 29-Feb-2012 11:55

I am getting this error when calling RefreshAll.

I have a probinding source defined which is the datasource for an IG ultragrid.  The datasource is two temp tables (tData and tData1) that have a relation defined (the temp table and dataset def is below).

For performance reasons only the top level table (tData) is populated along with a single record in the child table (tData1).

In the BeforeRowExpanded event for the grid, addition child records (tData) may be populated.

The procedure that populates the additional child records is RefreshData1 and exists in a persistent procedure (myProcHandle) that can be run locally or on the appserver.

The dataset dsData is passed as an input-output param.

I have changed the code in RefreshData1 so that it does nothing but return (IF TRUE THEN RETURN at the top of the procedure) and the error still persists even thought the contents of the dataset remain unchanged.

I suspect that there is some data condition that is causing the behavior because if I eliminate some of the records in the initial fill of the top level temp table, the error does not occur.

WHAT I AM LOOKING FOR IS SCENARIOS THAT WOULD CAUSE THIS ERROR.

Currently, I don't know what approach to take.

Here is the guts of the code...

RefreshData1 method is called from the BeforeRowExpanded event method...

IF VALID-HANDLE(myProcHandle) THEN DO:
            RefreshData1(INPUT rRowid, INPUT cPoNum, INPUT cWhsNum).
            bindingSource1:RefreshAll().
            ultraGrid1:Refresh().
            ultraGrid1:Rows:Refresh(Infragistics.Win.UltraWinGrid.RefreshRow:ReloadData).
END.          

METHOD PRIVATE VOID RefreshData1
        ( INPUT rRowid AS ROWID,
          INPUT cPoNum AS CHARACTER,
          INPUT cWhsNum AS CHARACTER).
                 
        RUN RefreshData1 IN myProcHandle
            ( INPUT rRowid,
              INPUT cPoNum,
              INPUT cWhsNum,
              INPUT FormGlobals:gApGroup,
              INPUT-OUTPUT DATASET dsData).
        
        RETURN.        
        
END METHOD. /* RefreshData1 */

Here is the datasource definition...

DEFINE TEMP-TABLE tData NO-UNDO
    FIELD tDbRowid AS ROWID
    FIELD tWhsNum AS CHARACTER
    FIELD tPoNum AS CHARACTER
    FIELD tQtyOrd AS DECIMAL
    FIELD tQtyRet AS DECIMAL
    FIELD tDispUm AS CHARACTER
    FIELD tVendNum AS CHARACTER
    FIELD tVendName AS CHARACTER
    FIELD tPoType AS CHARACTER
    FIELD tPoStat AS CHARACTER
    FIELD tPoDate AS DATE
    FIELD tPoExpectDate AS DATE
    FIELD tDateFirm AS LOGICAL
    FIELD tBuyer AS CHARACTER
    FIELD tOrderNum AS INTEGER
    FIELD tShipType AS CHARACTER
    FIELD tStocked AS CHARACTER
    FIELD tOpenTotal AS DECIMAL
    FIELD tRcvdTotal AS DECIMAL
    FIELD tTaxCode AS CHARACTER
    FIELD tWeight AS DECIMAL
    FIELD tTermsCode AS CHARACTER
INDEX idx1 IS PRIMARY UNIQUE tDbRowid tPoDate DESCENDING tWhsNum tPoNum
INDEX idx2 tDbRowid tPoStat tPoDate.

DEFINE TEMP-TABLE tData1 NO-UNDO
    FIELD tDbRowid AS ROWID
    FIELD tPoNum AS CHARACTER
    FIELD tWhsNum AS CHARACTER
    FIELD tPoLineNum AS INTEGER
    FIELD tSku AS CHARACTER
    FIELD tSkuDesc AS CHARACTER
    FIELD tQtyOrd AS DECIMAL
    FIELD tQtyRet AS DECIMAL
    FIELD tBuyUm AS CHARACTER
    FIELD tEntCost AS DECIMAL
    FIELD tCostUm AS CHARACTER
    FIELD tCompNum AS INTEGER
INDEX idx1 IS PRIMARY tPoLineNum tCompNum.

DEFINE DATASET dsData FOR tData, tData1
    DATA-RELATION Relationship FOR tData,tData1
    RELATION-FIELDS (tDbRowid, tDbRowid, tPoNum, tPoNum, tWhsNum, tWhsNum).

All Replies

Posted by jquerijero on 29-Mar-2012 16:04

Since this is a refresh functionality, can I assume that you are deleting temp-table in the process? When you delete a temp-table record, the corresponding bindingsource entry is not removed. So when the UltraGrid triggers a redraw you will get the error.

You can try something like this;

temp = grid:DataSource.

grid:DataSource = ?.

/* refresh temp-table */

grid:DataSource = temp.

Also,

If your INPUT-OUTPUT parameter will eventually cross the AppServer boundary, you also get the same error.

Posted by Admin on 29-Mar-2012 16:16

I'd rather reopen the query to fix the queries result list or DELETE-RESULT-LIST-ENTRY to remove the specific malicious entry.

It's more likely an issue of the BindingSource than the Grid.

Posted by jquerijero on 29-Mar-2012 16:26

Re-opening a query won't help, since the problem is on the currently bound records. DELETE-RESULT-LIST-ENTRY is not always feasible when dealing with n-tier architecture. It's also not elegant when deleting multiple records at once. 

Posted by Admin on 29-Mar-2012 16:31

You cannot delete multiple records at once. You always delete one after the other - and can DELETE-RESULT-LIST-ENTRY one after the other. No matter in which architecture.

Posted by jquerijero on 29-Mar-2012 17:20

DELETE-RESULT-LIST-ENTRY requires passing the query handle around. Most n-tier architectures use temp-table and dataset as data carrier. I understand that you only delete one record at a time that's why I said "not elegant when you have to delete multiple records" and not impossible. And it's not always feasible when you are delegating work across appserver or webservice API boundaries.

Posted by Admin on 29-Mar-2012 17:31

Absoltely agree with you.

But no matter what you do, the BindingSource works with a query; on a temp-table or on ProDataset temp-tables using an explicit query or an implicit query such as the TOP-NAV-QUERY or the Query of a ProDataset Relation.

Posted by jquerijero on 29-Mar-2012 17:49

The post is why the user is getting "no record avail". The most probably answer is that the temp-table that is bound to the grid is being manipulated, and the bindingsource has no way of knowing what happened.

Posted by Admin on 30-Mar-2012 02:01

The post is why the user is getting "no record avail"

... during a call to the BindingSource's RefreshAll() method.

When the record is deleted, it's still contained in the result list of the query (whatever Query the BindingSource uses, see my previous post). The only way to get a record out of the query's result-list is the DELETE-RESULT-LIST-ENTRY method or re-opening the query. Period.

Please try it out or read the binding source sample in the GUI for .NET Developers guide.

Posted by doug.macmillan on 30-Mar-2012 09:10

I have not had a chance to revisit the issue outlined in this post.  I have gotten around the issue temporariily by building up all of the child data on the front end versus building it up in the BeforeRowExpanded event.  I will review the your comments and see if I can figure out the problem.

A couple comments

1. This appears to be data dependent - that is depending on what parent records are selected, the error may not occur

2. The error occurs regardless if running the data gathering routine and filling the dataset over thge appserver or on the client and passing back the dataset handle so I don't think the appserver boundary has anything to do with it

3. No tData records are being deleted - the only action is that tData1 (child records) are being added

Posted by jquerijero on 30-Mar-2012 10:23

We've dealing with this issue for quite sometimes now. I would like to know what you find out to add to my growing list of when this errors can show up. The problem seems to be related to the UltraGrid repaint in between what you are doing. It's a little touchy because sometimes the code seems to proceed nicely until you add a messagebox, or you call one of UltraGrid's methods.

So far, I noticed this problem in the following cases;

- You might get this when you input-output along the appserver boundary (I pass a copy).

- You will get this when you directly delete a record (I normally close the query then delete to handle this)

- You called a method on the client where the query is currently scope with an INPUT and if the Ultragrid repaint gets trigger before you can reopen the query. (if the first thing you do in the method is to reopen the query, it seems to work fine)

- When cancelling out of UltraGrid update mode and you have an embedded editor that is in edit mode, the CancelCreateRow can trigger this error (related to delete, unsubscribe then resubscribe to fix)

- The temp-table is built in window A, window A passes the temp-table to window B then window A is closed. (this has something to do with the widget pool)

Except for the record deletion and CancelCreateRow, most of the above cases are related to creation of new temp-table instance that is different from what is currently bound. It's not set in stone, but I think this happens when the UltraGrid repaints in between the process.

Posted by Admin on 30-Mar-2012 12:51

When you Input-output the temp-table across the AppServer boundary, the rowids of the temp-table records may change, which invalidates the query result list. Thus, you will have to reopen the query to avoid trouble with the binding source.

Posted by doug.macmillan on 30-Mar-2012 13:10


Executing the following code before calling the RefreshAll method solves the problem...

hQry = DATASET dsData:HANDLE:TOP-NAV-QUERY(1).
hQry:QUERY-PREPARE(pWhereClause).
hQry:QUERY-OPEN().
       
IF NOT(VALID-HANDLE(bindingSource1:HANDLE)) THEN
    bindingSource1:HANDLE = DATASET dsData:HANDLE.


bindingSource1:REFRESH().

Posted by jquerijero on 07-May-2012 15:00

I think the QUERY-OPEN triggers a refresh automatically.

This thread is closed