Try OpenEdge Now
skip to main content
ProDataSet Parameters : Passing a ProDataSet with BY-REFERENCE or BIND : Passing a ProDataSet parameter by reference : ProDataSet instance passed BY-REFERENCE must exist in the caller
ProDataSet instance passed BY-REFERENCE must exist in the caller
Consider this situation where a ProDataSet is passed as an OUTPUT parameter. The calling procedure defines only a handle for the ProDataSet and passes it using the DATASET-HANDLE parameter form, without creating a dynamic ProDataSet first. This is the syntax for passing a ProDataSet as an 0 parameter using BY-REFERENCE:


RUN called-procedure ( OUTPUT DATASET-HANDLE dataset-handle BY-REFERENCE ).
The intention is that the called-procedure's ProDataSet definition and data are passed back as the OUTPUT parameter to populate the dataset-handle in the caller. This cannot work properly when the call is local. When the call is made, the dataset-handle has the Unknown value (?) because it has not been used yet. But the BY-REFERENCE keyword instructs the AVM to use the calling procedure's ProDataSet as the basis for the parameter. Since there is no such ProDataSet at the time of the call, this results in an error. A ProDataSet passed BY-REFERENCE, regardless of the parameter mode, must be initialized by specifying its tables and relations before the call.
In this case the calling procedure must do one of the following:
*It can create a ProDataSet using the handle and use dynamic methods to create a structure of temp-tables and relations for it that are compatible with the ProDataSet in the called-procedure. In this way the calling procedure's dynamic ProDataSet is used for the call, and the data from the called-procedure is effectively appended to it, just as for the static example described earlier.
*It can omit the BY-REFERENCE keyword and pass the ProDataSet by value in all cases, which means that the called-procedure's ProDataSet definition and data are copied back into the calling procedure to instantiate a dynamic ProDataSet there.
*It can assign the handle to some valid existing static or dynamic ProDataSet before the call.
If the OUTPUT parameter is a DATASET-HANDLE, it presumably means that the calling procedure is prepared to accept a variety of ProDataSet definitions returned to it. If this is the case, then once a particular ProDataSet has been passed back and has populated the dynamic ProDataSet, any further calls using the same RUN statement form must receive back a ProDataSet of the same type. Even though the AVM empties the target dynamic ProDataSet so that the data from the called-procedure replaces any data in the calling procedure's ProDataSet, the AVM does not automatically delete the dynamic ProDataSet structure in the calling procedure. If it is not compatible with the OUTPUT parameter, an error results.
If you want to use the same dynamic ProDataSet handle to receive different ProDataSets during the lifetime of the calling procedure, you must delete the dynamic ProDataSet using the DELETE OBJECT statement. Set the handle variable to the Unknown value (?) before you run a called-procedure to get back a different ProDataSet to avoid the error.
Sometimes the calling procedure needs to get back a dynamic ProDataSet (that is, one with a variable definition) on the first call and then wants to be able to make further calls to get back new or additional data in the same ProDataSet type, but without copying the ProDataSet definition locally on subsequent calls. If this is the case, then the first RUN statement must be made by value, in order to get back the ProDataSet definition with the data, and then subsequent calls can be made with a separate RUN statement BY-REFERENCE. This avoids copying the ProDataSet definition locally. (Note that in these descriptions the words "by value" are normally not capitalized in order to emphasize that this is the default behavior, so that the keyword BY-VALUE is not required to get this behavior.)
Naturally you could not pass an uninitialized dynamic ProDataSet as an INPUT or INPUT-OUTPUT parameter, as there would be no definition to pass to the called-procedure. In such a case you could only pass the handle variable and let the called-procedure associate it with a ProDataSet of its own.
To summarize: if the target ProDataSet in the calling procedure is dynamic, then you must either initialize it before making a call to another local procedure BY-REFERENCE, or make the first call by value and subsequent calls BY-REFERENCE, so that you obtain the ProDataSet definition the caller needs.