project QadFinancials > class BGLMask > method ApiGetGLMasks

Description

ApiGetGLMasks; this method will return a temp-table that contains all the existing and all the possible GLMasks based on the input parameters.
In the temp-table is a field that indicates wether it is an existing or a possible GLMask.


Parameters


icGLinputcharacterGL; code used for the filtering; use following values:
"":U : no condition on the GL
"XXXnoneXXX":U : only the G/L-masks without G/L-code will be returned
<any-other-value> : the value will be used to company with the G/L-code using the matches operator.
icDivisioninputcharacterDivision; code used for the filtering; use following values:
"":U : no condition on the Division
"XXXnoneXXX":U : only the G/L-masks without Division-code will be returned
<any-other-value> : the value will be used to company with the Division-code using the matches operator.
icProjectinputcharacterProject; ; code used for the filtering; use following values:
"":U : no condition on the Project
"XXXnoneXXX":U : only the G/L-masks without Project-code will be returned
<any-other-value> : the value will be used to company with the Project-code using the matches operator.
icCostCentreinputcharacterCostCentre; code used for the filtering; use following values:
"":U : no condition on the CostCentre
"XXXnoneXXX":U : only the G/L-masks without CostCentre-code will be returned
<any-other-value> : the value will be used to company with the CostCentre-code using the matches operator.
tGetGLMaskCombinationsoutputtemp-tableGetGLMaskCombinations; temp-table that is used by Api-methods to hold the selected/existing masks and the possible masks
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


unused


program code (program9/bglmask.p)

/* ============================= */
    /* Validate the input parameters */ 
    /* ============================= */
    assign vcMessage = "":U.
    if vlCompanyCheckGL = false and icGL <> "XXXnoneXXX":U
    then assign vcMessage = trim(#T-8'The GL mask cannot have a GL specification because the entity property for GL specifications is deactivated.':255(2237)T-8#) + " (1)":U + chr(10) + trim(substitute(#T-9'The value of this parameter should be: &1.':255(2238)T-9#,"XXXnoneXXX":U)).
    if vlCompanyCheckDiv = false and icDivision <> "XXXnoneXXX":U
    then assign vcMessage = trim(#T-10'The GL mask cannot have a sub-account specification because the entity property for sub-account specifications is deactivated.':255(2239)T-10#) + " (2)":U + chr(10) + trim(substitute(#T-11'The value of this parameter should be: &1.':255(2238)T-11#,"XXXnoneXXX":U)).
    if vlCompanyCheckProject = false and icProject <> "XXXnoneXXX":U
    then assign vcMessage = trim(#T-12'The GL mask cannot have a project specification because the entity property for project specifications is deactivated.':255(2240)T-12#) + " (3)":U + chr(10) + trim(substitute(#T-13'The value of this parameter should be: &1.':255(2238)T-13#,"XXXnoneXXX":U)).
    if vlCompanyCheckCC = false and icCostCentre <> "XXXnoneXXX":U
    then assign vcMessage = trim(#T-14'The GL mask cannot have a cost center specification because the entity property for cost center specifications is deactivated.':255(2241)T-14#) + " (4)":U + chr(10) + trim(substitute(#T-15'The value of this parameter should be: &1.':255(2238)T-15#,"XXXnoneXXX":U)).
    if vcMessage <> "":U
    then do :
        assign oiReturnStatus = -3.
        <M-1 run SetMessage (input  vcMessage (icMessage),
                     input  '':U (icArguments),
                     input  '':U (icFieldName),
                     input  '':U (icFieldValue),
                     input  'E':U (icType),
                     input  3 (iiSeverity),
                     input  '':U (icRowid),
                     input  'QADFIN-149':U (icFcMsgNumber),
                     input  '' (icFcExplanation),
                     input  '' (icFcIdentification),
                     input  '' (icFcContext),
                     output viFcReturnSuper (oiReturnStatus)) in BGLMask>
        Return.
    end. /* if vcMessage <> "":U */
    
    /* ======================================================================================== */
    /* In case ".*":U was passed as parameter then we convery it into "*.*":U because otherwise */
    /* the generated query-prepare-code will convert this to a condition using a "Begins".      */
    /* If multiple spaces preceed " *":U then remove these preceding spaces                     */
    /* ======================================================================================== */
    if icGL = ".*":U then assign icGL = "*.*":U.
    if icDivision = ".*":U then assign icDivision = "*.*":U.
    if icProject = ".*":U then assign icProject = "*.*":U.
    if icCostCentre = ".*":U then assign icCostCentre = "*.*":U.
    if trim(icGL) = "*":U and icGL begins " ":U then assign icGL = " *":U.
    if trim(icDivision) = "*":U and icDivision begins " ":U then assign icDivision = " *":U.
    if trim(icProject) = "*":U and icProject begins " ":U then assign icProject = " *":U.
    if trim(icCostCentre) = "*":U AND icCostCentre begins " ":U then assign icCostCentre = " *":U.
    
    /* =================================================================================== */
    /* Initialisations + reading the external tables; we also create an empty query-record */
    /* ourself to simplify the composition of output temp-table tGLMaskCombinations.       */
    /* =================================================================================== */
    empty temp-table tGetGLMaskCombinations.
    empty temp-table tqGLByMatchingGLCode.
    empty temp-table tqDivisionByMatchingDivisionCode.
    empty temp-table tqProjectByMatchingProjectCode.
    empty temp-table tqCostCentreByMatchingCCCode.
    assign viGLID         = 0
           viDivisionID   = 0
           viCostCentreID = 0
           viProjectID    = 0.

    /* ================================== */
    /* GL                                 */
    /* ================================== */
    if vlCompanyCheckGL = true
    then do :
        <Q-2 run GLByMatchingGLCode (all) (Read) (NoCache)
          (input viCompanyId, (CompanyId)
           input icGL, (GLCode)
           output dataset tqGLByMatchingGLCode) in BGL >
        /* In case there is only one found, we can take the ID field */
        find tqGLByMatchingGLCode no-error.
        if available tqGLByMatchingGLCode and
           tqGLByMatchingGLCode.tcGLCode = icGL
        then assign viGLID = tqGLByMatchingGLCode.tiGL_ID.
    end. /* if vlCompanyCheckGL = true */
    else do :
        create tqGLByMatchingGLCode.
        assign tqGLByMatchingGLCode.tlGLIsDivisionAccount   = true
               tqGLByMatchingGLCode.tlGLIsProjectAccount    = true
               tqGLByMatchingGLCode.tlGLIsCostCentreAccount = true.
    end. /* if icGL = "XXXnoneXXX":U */
    
    /* ================================== */
    /* Division                           */
    /* ================================== */    
    if vlCompanyCheckDiv = true
    then do :
        <Q-3 run DivisionByMatchingDivisionCode (all) (Read) (NoCache)
          (input viCompanyId, (CompanyId)
           input icDivision, (DivisionCode)
           output dataset tqDivisionByMatchingDivisionCode) in BDivision >
        /* In case there is only one found, we can take the ID field */
        find tqDivisionByMatchingDivisionCode no-error.
        if available tqDivisionByMatchingDivisionCode and
           tqDivisionByMatchingDivisionCode.tcDivisionCode = icDivision
        then assign viDivisionID = tqDivisionByMatchingDivisionCode.tiDivision_ID.
    end. /* if vlCompanyCheckDiv = true */
    if icDivision = "":U   or
       icDivision = "*":U  or
       icDivision = " *":U or
       icDivision = "XXXnoneXXX":U
    then create tqDivisionByMatchingDivisionCode.
    
    /* ================================== */
    /* Project                            */
    /* ================================== */        
    if vlCompanyCheckProject = true
    then do :
        <Q-4 run ProjectByMatchingProjectCode (all) (Read) (NoCache)
          (input viCompanyId, (CompanyId)
           input icProject, (ProjectCode)
           output dataset tqProjectByMatchingProjectCode) in BProject >
        /* In case there is only one found, we can take the ID field */
        find tqProjectByMatchingProjectCode no-error.
        if available tqProjectByMatchingProjectCode and
           tqProjectByMatchingProjectCode.tcProjectCode = icProject
        then assign viProjectID = tqProjectByMatchingProjectCode.tiProject_ID.
    end. /* if vlCompanyCheckProject = true */
    if icProject = "":U   or
       icProject = "*":U  or
       icProject = " *":U or
       icProject = "XXXnoneXXX":U
    then create tqProjectByMatchingProjectCode.

    /* ================================== */
    /* CostCentre                         */
    /* ================================== */            
    if vlCompanyCheckCC = true
    then do :
        <Q-5 run CostCentreByMatchingCCCode (all) (Read) (NoCache)
          (input viCompanyId, (CompanyId)
           input icCostCentre, (CostCentreCode)
           output dataset tqCostCentreByMatchingCCCode) in BCostCentre >
        /* In case there is only one found, we can take the ID field */
        find tqCostCentreByMatchingCCCode no-error.
        if available tqCostCentreByMatchingCCCode and
           tqCostCentreByMatchingCCCode.tcCostCentreCode = icCostCentre
        then assign viCostCentreID = tqCostCentreByMatchingCCCode.tiCostCentre_ID.
    end. /* if vlCompanyCheckCC = true */
    if icCostCentre = "":U   or
       icCostCentre = "*":U  or
       icCostCentre = " *":U or
       icCostCentre = "XXXnoneXXX":U
    then create tqCostCentreByMatchingCCCode.
    
    
    /* ========================================== */
    /* Compose the records of tGLMaskCombinations */
    /* ========================================== */
    for each tqGLByMatchingGLCode no-lock, 
        each tqDivisionByMatchingDivisionCode no-lock,
        each tqProjectByMatchingProjectCode no-lock,
        each tqCostCentreByMatchingCCCode no-lock :
        if ((tqGLByMatchingGLCode.tlGLIsDivisionAccount   = FALSE OR vlCompanyCheckDiv     = FALSE) AND tqDivisionByMatchingDivisionCode.tcDivisionCode <> "":U) or
           ((tqGLByMatchingGLCode.tlGLIsProjectAccount    = FALSE OR vlCompanyCheckProject = FALSE) AND tqProjectByMatchingProjectCode.tcProjectCode    <> "":U) or
           ((tqGLByMatchingGLCode.tlGLIsCostCentreAccount = FALSE OR vlCompanyCheckCC      = FALSE) AND tqCostCentreByMatchingCCCode.tcCostCentreCode   <> "":U) or
           (tqGLByMatchingGLCode.tlGLIsDivisionAccount   = true and vlCompanyCheckDiv     = true and tqDivisionByMatchingDivisionCode.tcDivisionCode = "":U)     or
           (tqGLByMatchingGLCode.tlGLIsProjectAccount    = true and (tqGLByMatchingGLCode.tcGLAnalysisLimitation = {&GLANALYSISLIMITATION-BOTHREQUIRED} or 
                                                                      tqGLByMatchingGLCode.tcGLAnalysisLimitation = {&GLANALYSISLIMITATION-NONE}) and
            vlCompanyCheckProject = true and tqProjectByMatchingProjectCode.tcProjectCode    = "":U) or
           (tqGLByMatchingGLCode.tlGLIsCostCentreAccount = true and (tqGLByMatchingGLCode.tcGLAnalysisLimitation = {&GLANALYSISLIMITATION-BOTHREQUIRED} or 
                                                                      tqGLByMatchingGLCode.tcGLAnalysisLimitation = {&GLANALYSISLIMITATION-NONE}) and
            vlCompanyCheckCC      = true and tqCostCentreByMatchingCCCode.tcCostCentreCode   = "":U) or
/*
           (tqGLByMatchingGLCode.tlGLIsProjectAccount = true and tqGLByMatchingGLCode.tlGLIsCostCentreAccount = true and
            vlCompanyCheckProject = true and vlCompanyCheckCC = true and 
            tqGLByMatchingGLCode.tcGLAnalysisLimitation = {&GLANALYSISLIMITATION-EXCLEACHOTHER} and
            ((tqCostCentreByMatchingCCCode.tcCostCentreCode = "":U  and tqProjectByMatchingProjectCode.tcProjectCode = "":U) or
             (tqCostCentreByMatchingCCCode.tcCostCentreCode <> "":U  and tqProjectByMatchingProjectCode.tcProjectCode <> "":U))) or
           (tqGLByMatchingGLCode.tlGLIsProjectAccount = true and tqGLByMatchingGLCode.tlGLIsCostCentreAccount = true and
            vlCompanyCheckProject = true and vlCompanyCheckCC = true and 
            tqGLByMatchingGLCode.tcGLAnalysisLimitation = {&GLANALYSISLIMITATION-ATLEASTONE} and
            tqCostCentreByMatchingCCCode.tcCostCentreCode = '':U  and tqProjectByMatchingProjectCode.tcProjectCode = "":U)             
*/
           (tqGLByMatchingGLCode.tlGLIsProjectAccount = true and tqGLByMatchingGLCode.tlGLIsCostCentreAccount = true and
            vlCompanyCheckProject = true and vlCompanyCheckCC = true and             
            (tqCostCentreByMatchingCCCode.tcCostCentreCode = '':U  or tqProjectByMatchingProjectCode.tcProjectCode = "":U))
        then next.    
        else do:
            create tGetGLMaskCombinations.
            assign tGetGLMaskCombinations.tiDomainId       = viDomainId
                   tGetGLMaskCombinations.tiGLMaskID       = 0
                   tGetGLMaskCombinations.tiGLID           = tqGLByMatchingGLCode.tiGL_ID
                   tGetGLMaskCombinations.tiDivisionID     = tqDivisionByMatchingDivisionCode.tiDivision_ID
                   tGetGLMaskCombinations.tiProjectID      = tqProjectByMatchingProjectCode.tiProject_ID
                   tGetGLMaskCombinations.tiCostCentreID   = tqCostCentreByMatchingCCCode.tiCostCentre_ID
                   tGetGLMaskCombinations.tcGLCode         = tqGLByMatchingGLCode.tcGLCode
                   tGetGLMaskCombinations.tcDivisionCode   = tqDivisionByMatchingDivisionCode.tcDivisionCode
                   tGetGLMaskCombinations.tcProjectCode    = tqProjectByMatchingProjectCode.tcProjectCode
                   tGetGLMaskCombinations.tcCostCentreCode = tqCostCentreByMatchingCCCode.tcCostCentreCode
                   tGetGLMaskCombinations.tcStatus         = "":U
                   tGetGLMaskCombinations.tlSelected       = false. 
        end. /* not if */               
    end. /* for each */
    
    /* ====================================================================== */
    /* Find-out the existing GLMask records that match the selection criteria */
    /* Set then as selected and set the GLMaskID for it                       */
    /* ====================================================================== */
    /* In this case a condition on = 0 should be kept */
    if viGLID = 0 and (icGL = "XXXnoneXXX":U or icGL = " *":U)
    then assign viGLID = -999999. 
    if viCostCentreID = 0 and (icCostCentre = "XXXnoneXXX":U or icCostCentre = " *":U)
    then assign viCostCentreID = -999999.
    if viDivisionID = 0 and (icDivision = "XXXnoneXXX":U or icDivision = " *":U)
    then assign viDivisionID = -999999.
    if viProjectID = 0 and (icProject =  "XXXnoneXXX":U or icProject = " *":U)
    then assign viProjectID = -999999.
    <Q-6 run GLMaskByIDsCodes (all) (Read) (NoCache)
       (input viCompanyId, (CompanyId)
        input (if icCostCentre = 'XXXnoneXXX':U or trim(icCostCentre) = '*':U then '':U else icCostCentre), (CostCentreCode)
        input (if icProject = 'XXXnoneXXX':U or trim(icProject) = '*':U then '':U else icProject), (ProjectCode)
        input (if icGL = 'XXXnoneXXX':U or trim(icGL) = '*':U then '':U else icGL), (GLCode)
        input (if icDivision = 'XXXnoneXXX':U or trim(icDivision) = '*':U then '':U else icDivision), (DvisionCode)
        input viCostCentreID, (CostCentreID)
        input viProjectID, (ProjectID)
        input viGLID, (GLID)
        input viDivisionID, (DivisionID)
        input ?, (GLMaskID)
        input viDomainID, (DomainID)
        output dataset tqGLMaskByIDsCodes) in BGLMask >
    for each tqGLMaskByIDsCodes no-lock :
        /* ================================================================================= */
        /* Update the output record (no error when not found allthough this is a corruption) */
        /* ================================================================================= */
        find tGetGLMaskCombinations where    
             tGetGLMaskCombinations.tiDomainID     = tqGLMaskByIDsCodes.tiDomain_ID   and 
             tGetGLMaskCombinations.tiGLID         = tqGLMaskByIDsCodes.tiGL_ID       and
             tGetGLMaskCombinations.tiDivisionID   = tqGLMaskByIDsCodes.tiDivision_ID and 
             tGetGLMaskCombinations.tiProjectID    = tqGLMaskByIDsCodes.tiProject_ID  and 
             tGetGLMaskCombinations.tiCostCentreID = tqGLMaskByIDsCodes.tiCostCentre_ID
             no-lock no-error.
        if not available tGetGLMaskCombinations
        then do :                 
            /* Create records that do not match the current criteria with status = D */
            create tGetGLMaskCombinations.
            assign tGetGLMaskCombinations.tiDomainId       = viDomainId
                   tGetGLMaskCombinations.tiGLMaskID       = tqGLMaskByIDsCodes.tiGLMask_ID
                   tGetGLMaskCombinations.tiGLID           = tqGLMaskByIDsCodes.tiGL_ID
                   tGetGLMaskCombinations.tiDivisionID     = tqGLMaskByIDsCodes.tiDivision_ID
                   tGetGLMaskCombinations.tiProjectID      = tqGLMaskByIDsCodes.tiProject_ID
                   tGetGLMaskCombinations.tiCostCentreID   = tqGLMaskByIDsCodes.tiCostCentre_ID
                   tGetGLMaskCombinations.tcGLCode         = tqGLMaskByIDsCodes.tcGLCode
                   tGetGLMaskCombinations.tcDivisionCode   = tqGLMaskByIDsCodes.tcDivisionCode
                   tGetGLMaskCombinations.tcProjectCode    = tqGLMaskByIDsCodes.tcProjectCode
                   tGetGLMaskCombinations.tcCostCentreCode = tqGLMaskByIDsCodes.tcCostCentreCode
                   tGetGLMaskCombinations.tcStatus         = "D":U
                   tGetGLMaskCombinations.tlSelected       = false. 
        end. /* if not avail */
        else assign tGetGLMaskCombinations.tiGLMaskID = tqGLMaskByIDsCodes.tiGLMask_ID
                    tGetGLMaskCombinations.tlSelected = true.
    end. /* for each tqGLMaskByIDsCodes */
    
    /* ============================================================================== */
    /* For those records that have status = D: delete them as this are db-corruptions */
    /* Remove these records also from the output temp-table                           */
    /* ============================================================================== */
    if can-find (first tGetGLMaskCombinations where 
                       tGetGLMaskCombinations.tcStatus = "D":U)
    then do :
        <M-55 run ClearData (output viFcReturnSuper (oiReturnStatus)) in BGLMask>
        if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0 then Return.
        for each tGetGLMaskCombinations where 
                 tGetGLMaskCombinations.tcStatus = "D":U : 
            assign vcGLMaskIDsToDelete = vcGLMaskIDsToDelete + chr(4) + string(tGetGLMaskCombinations.tiGLMaskID).
            if length(vcGLMaskIDsToDelete,"CHARACTER":U) >= 10000
            then do :
                assign vcGLMaskIDsToDelete = substring(vcGLMaskIDsToDelete,2,-1,"CHARACTER":U).
                <M-47 run DataLoad
          (input  ? (icRowids), 
           input  vcGLMaskIDsToDelete (icPkeys), 
           input  ? (icObjectIds), 
           input  '' (icFreeform), 
           input  true (ilKeepPrevious), 
           output viFcReturnSuper (oiReturnStatus)) in BGLMask>
                assign vcGLMaskIDsToDelete = "":U.
                if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
                if viFcReturnSuper < 0 then Return.
                leave.
            end. /* if length(vcGLMaskIDsToDelete,"CHARACTER":U) >= 10000 */
        end. /* for each tGetGLMaskCombinations where */
        if vcGLMaskIDsToDelete <> "":U and 
           vcGLMaskIDsToDelete <> ?
        then do :
            assign vcGLMaskIDsToDelete = substring(vcGLMaskIDsToDelete,2,-1,"CHARACTER":U).
            <M-48 run DataLoad
          (input  ? (icRowids), 
           input  vcGLMaskIDsToDelete (icPkeys), 
           input  ? (icObjectIds), 
           input  '' (icFreeform), 
           input  true (ilKeepPrevious), 
           output viFcReturnSuper (oiReturnStatus)) in BGLMask>
            if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
            if viFcReturnSuper < 0 then Return.
        end. /* if vcGLMaskIDsToDelete <> "":U and */
        for each tGetGLMaskCombinations where 
                 tGetGLMaskCombinations.tcStatus = "D":U,
            each tGLMask where
                 tGLMask.GLMask_ID = tGetGLMaskCombinations.tiGLMaskID :
            assign tGLMask.tc_Status = "D":U.
            delete tGetGLMaskCombinations.
        end. /* for each */ 
        <M-56 run ValidateBC (output viFcReturnSuper (oiReturnStatus)) in BGLMask>
        if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0 then Return.
        <M-57 run AdditionalUpdates (output viFcReturnSuper (oiReturnStatus)) in BGLMask>
        if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0 then Return.
        <M-58 run DataSave (output viFcReturnSuper (oiReturnStatus)) in BGLMask>
        if viFcReturnSuper <> 0 then assign oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0 then Return.
    end. /* if can-find (first tGetGLMaskCombinations where */


Sample code: how to call this method through RPCRequestService (QXtend Inbound)

define temp-table ttContext no-undo
    field propertyQualifier as character
    field propertyName as character
    field propertyValue as character
    index entityContext is primary unique
        propertyQualifier
        propertyName
    index propertyQualifier
        propertyQualifier.

define dataset dsContext for ttContext.

define variable vhContextDS as handle no-undo.
define variable vhExceptionDS as handle no-undo.
define variable vhServer as handle no-undo.
define variable vhInputDS as handle no-undo.
define variable vhInputOutputDS as handle no-undo.
define variable vhOutputDS as handle no-undo.
define variable vhParameter as handle no-undo.

/* Create context */
create ttContext.
assign ttContext.propertyName = "programName"
       ttContext.propertyValue = "BGLMask".
create ttContext.
assign ttContext.propertyName = "methodName"
       ttContext.propertyValue = "ApiGetGLMasks".
create ttContext.
assign ttContext.propertyName = "applicationId"
       ttContext.propertyValue = "fin".
create ttContext.
assign ttContext.propertyName = "entity"
       ttContext.propertyValue = "1000".
create ttContext.
assign ttContext.propertyName = "userName"
       ttContext.propertyValue = "mfg".
create ttContext.
assign ttContext.propertyName = "password"
       ttContext.propertyValue = "".

/* Create input dataset */
create dataset vhInputDS.
vhInputDS:read-xmlschema("file", "xml/bglmask.apigetglmasks.i.xsd", ?).
vhParameter = vhInputDS:get-buffer-handle("tParameterI").
vhParameter:buffer-create().
assign vhParameter::icGL = <parameter value>
       vhParameter::icDivision = <parameter value>
       vhParameter::icProject = <parameter value>
       vhParameter::icCostCentre = <parameter value>.

/* Connect the AppServer */
create server vhServer.
vhServer:connect("-URL <appserver-url>").

if not vhServer:connected()
then do:
    message "Could not connect AppServer" view-as alert-box error title "Error".
    return.
end.

/* Run */
assign vhContextDS = dataset dsContext:handle.

run program/rpcrequestservice.p on vhServer
    (input-output dataset-handle vhContextDS by-reference,
           output dataset-handle vhExceptionDS,
     input        dataset-handle vhInputDS by-reference,
     input-output dataset-handle vhInputOutputDS by-reference,
           output dataset-handle vhOutputDS).

/* Handle output however you want, in this example, we dump it to xml */
if valid-handle(vhExceptionDS)
then vhExceptionDS:write-xml("file", "Exceptions.xml", true).

if valid-handle(vhOutputDS)
then vhOutputDS:write-xml("file", "Output.xml", true).

/* Cleanup */
vhServer:disconnect().
assign vhServer = ?.

if valid-handle(vhInputDS)
then delete object vhInputDS.

if valid-handle(vhOutputDS)
then delete object vhOutputDS.

if valid-handle(vhExceptionDS)
then delete object vhExceptionDS.