Unable to generate a save predicate...

dayv2005

Member
I am messing around with the Architecture made Simple work series. I have almost managed to mimic it in my screen.

I get these errors when it tries to update the values and process them.

---------------------------
Error
---------------------------
Unable to generate a save predicate for UserSettings if field SettingsID is not mapped in ttUserSettingsBefore. (11896)
---------------------------
OK
---------------------------
---------------------------
Error
---------------------------
Unable to generate SAVE-WHERE-STRING for SAVE-ROW-CHANGES for buffer UserSettings. (11911)
---------------------------
OK
---------------------------

Code:
/****TEMP-TABLE******/
DEFINE TEMP-TABLE ttUserSettings BEFORE-TABLE ttUserSettingsBefore 
    
    FIELD SettingsID AS CHARACTER   FORMAT "->,>>>,>>9"
    FIELD UserName   AS CHARACTER   FORMAT "X(25)"
    FIELD ScreenName AS CHARACTER   FORMAT "X(25)"
    FIELD FieldName  AS CHARACTER   FORMAT "X(25)"
    FIELD FieldValue AS CHARACTER   FORMAT "X(25)"
    
    .

/****DATASET******/
DEFINE DATASET dsUserSettings FOR ttUserSettings.


/******UI*********/
/*Change Data*/
TEMP-TABLE ttUserSettings:TRACKING-CHANGES = TRUE.
FOR EACH ttUserSettings:
    ASSIGN ttUserSettings.ScreenName = "Changed".
END.
TEMP-TABLE ttUserSettings:TRACKING-CHANGES = FALSE.

/* Gets a copy of only the records that were changed */
DEFINE VARIABLE hDSChanges AS HANDLE     NO-UNDO.
CREATE DATASET hDSChanges.
hDSChanges:CREATE-LIKE (DATASET dsUserSettings:HANDLE).
hDSChanges:GET-CHANGES (DATASET dsUserSettings:HANDLE).

RUN changeUserSettingsData IN hSaUserSettings
    (INPUT-OUTPUT DATASET-HANDLE hDSChanges).

hDSChanges:MERGE-CHANGES (DATASET dsUserSettings:HANDLE).


/******daUserSettings.cls******/
CLASS daUserSettings:

	{ttUserSettings.i}
	{dsUserSettings.i}
    
    CONSTRUCTOR PUBLIC daUserSettings():
        /* Init */
    END CONSTRUCTOR.
    
	METHOD PUBLIC VOID fetchUserSettingsData(
        INPUT fFilterValue AS CHAR,
        OUTPUT DATASET FOR dsUserSettings):

        DEFINE VAR qString AS CHAR NO-UNDO.
	
        DEFINE QUERY qUserSettings FOR UserSettings.
	    DEFINE DATA-SOURCE scUserSettings FOR QUERY qUserSettings.

	    BUFFER ttUserSettings:ATTACH-DATA-SOURCE(DATA-SOURCE scUserSettings:HANDLE,"").

        QUERY qUserSettings:QUERY-PREPARE("For each UserSettings no-lock " + fFilterValue).

	    DATASET dsUserSettings:FILL().
	    
	END METHOD.

    METHOD PUBLIC VOID changeUserSettingsData (
	    INPUT-OUTPUT DATASET FOR dsUserSettings):
	
        DEFINE DATA-SOURCE scUserSettings FOR UserSettings.

/****Here is where the problem occurs ****/
	    BUFFER ttUserSettings:ATTACH-DATA-SOURCE(DATA-SOURCE scUserSettings:HANDLE).

        FOR EACH ttUserSettingsBefore:
            BUFFER ttUserSettingsBefore:SAVE-ROW-CHANGES().
	    END.     
/***********************************/

	END METHOD .    
	    
END CLASS.

I can not figure this out. I don't know if it's something involving the db or the includes or what. Also i left out other code sections that weren't the problem. If you need more info please let me know.

BTW i am on 10.1c
 

dayv2005

Member
I don't know if this was the practical way of doing this, but i solved it.

I added a rowid to the temp table. Populated it in my fetch and used it in my change as well.

Code:
DEFINE TEMP-TABLE ttUserSettings BEFORE-TABLE ttUserSettingsBefore 
    
    FIELD ttRowID    AS ROWID /* <---------- ADDED THIS FIELD */
    FIELD SettingsID AS CHARACTER   FORMAT "->,>>>,>>9"
    FIELD UserName   AS CHARACTER   FORMAT "X(25)"
    FIELD ScreenName AS CHARACTER   FORMAT "X(25)"
    FIELD FieldName  AS CHARACTER   FORMAT "X(25)"
    FIELD FieldValue AS CHARACTER   FORMAT "X(25)"
    
    .

CLASS daUserSettings:

	{ttUserSettings.i}
	{dsUserSettings.i}
    
    CONSTRUCTOR PUBLIC daUserSettings():
        /* Init */
    END CONSTRUCTOR.
    
	METHOD PUBLIC VOID fetchUserSettingsData(
        INPUT fFilterValue AS CHAR,
        OUTPUT DATASET FOR dsUserSettings):

/************CHANGED THIS *********/
        DEFINE QUERY qUserSettings FOR UserSettings.
	    DEFINE DATA-SOURCE scUserSettings FOR QUERY qUserSettings
            UserSettings KEYS(ROWID).

	    BUFFER ttUserSettings:ATTACH-DATA-SOURCE(DATA-SOURCE scUserSettings:HANDLE,"ttUserSettings.ttRowID,rowid(UserSettings)").
/**********************************/

        QUERY qUserSettings:QUERY-PREPARE("For each UserSettings no-lock " + fFilterValue).

	    DATASET dsUserSettings:FILL().
	    
	END METHOD.

    METHOD PUBLIC VOID changeUserSettingsData (
	    INPUT-OUTPUT DATASET FOR dsUserSettings):
	
/************CHANGED THIS *********/
        DEFINE QUERY qUserSettings FOR UserSettings.
	    DEFINE DATA-SOURCE scUserSettings FOR QUERY qUserSettings
            UserSettings KEYS(ROWID).

        BUFFER ttUserSettings:ATTACH-DATA-SOURCE(DATA-SOURCE scUserSettings:HANDLE,"ttUserSettings.ttRowID,rowid(UserSettings)").
/**********************************/
        FOR EACH ttUserSettingsBefore:
            BUFFER ttUserSettingsBefore:SAVE-ROW-CHANGES().
	    END.     

	END METHOD .    
	    
END CLASS.

This worked great, but not sure if this is the way i should have done this or not? Any feedback on this approach?
 

RealHeavyDude

Well-Known Member
I don't see any indexes in you temp-table definitions and I think that's the reason why you're getting the error message. AFAIK, the SAVE-ROW-CHANGES uses the key field in the temp-table to locate the corresponding database record ...

When I use temp-tables in ProDataSets which are derived from database tables I always index them similar like the database tables. Maybe I skip unnecessary indexes - BUT - I always have the same primary unique index on the temp-table as on the database table. This way I never had any problems.

Maybe others can give you a more accurate explanation of this behavior.

HTH, RealHeavyDude.
 
Top