of 79/79
DATASTAGE ROUTINES ________________________________________ BL: BOT v2.3.0 Returns BLANK if passed value is NOT NULL or BLANK, after trimming spaces DataIn = "":Trim(Arg1) If IsNull(DataIn) or DataIn = "" Then Ans = "" End Else Ans = DataIn End CheckFileRecords: Function CheckFileRecords(Arg1,Arg2) vParamFile = Arg1 : "/" : Arg2 vCountVal = 0 OpenSeq vParamFile To FileVar Else Call DSLogWarn("Cannot open ":vParamFile , "Cannot Open ParamFile") End Loop ReadSeq Dummy From FileVar Else Exit ;* at end-of-file vCountVal = vCountVal + 1 Repeat CloseSeq FileVar Ans=vCountVal Return (vCountVal) CheckFileSizes:

Datastage Routines

  • View
    598

  • Download
    46

Embed Size (px)

Text of Datastage Routines

DATASTAGE ROUTINES ________________________________________ BL: BOT v2.3.0 Returns BLANK if passed value is NOT NULL or BLANK, after trimming spaces DataIn = "":Trim(Arg1) If IsNull(DataIn) or DataIn = "" Then Ans = "" End Else Ans = DataIn End CheckFileRecords: Function CheckFileRecords(Arg1,Arg2) vParamFile = Arg1 : "/" : Arg2 vCountVal = 0 OpenSeq vParamFile To FileVar Else Call DSLogWarn("Cannot open ":vParamFile , "Cannot Open ParamFile") End Loop ReadSeq Dummy From FileVar Else Exit ;* at end-of-file vCountVal = vCountVal + 1 Repeat CloseSeq FileVar Ans=vCountVal Return (vCountVal) CheckFileSizes: DIR = "/interface/dashboard/dashbd_dev_dk_int/Source/" FNAME = "GLEISND_OC_02_20040607_12455700.csv" *CMD = "ll -tr ":DIR:"|grep ":FNAME CMD = "cmp -s ":DIR:"|grep ":FNAME Call DSExecute("UNIX", CMD, Output, SystemReturnCode)

Ans = Output CheckIdocsSent: Checks If Idoc delivery job actually sent any Idocs to SAP. This routine will atempt to read the DataStage Director log for the job name specified as an argument. If the job has a fatal error with "No link file", the routine will copy the IDOC link file(s) into the interface error folder. In case the fatal error above is not found the routine aborts the job. A simple log of which runs produce error link file is maintained in the module's log directory. $INCLUDE DSINCLUDE JOBCONTROL.H vRoutineName = "CheckIdocsSent" Ans = "Ok" If System(91) Then OsType = 'NT' OsDelim = '\' NonOsDelim = '/' Move = 'move ' End Else OsType = 'UNIX' OsDelim = '/' NonOsDelim = '\' Move = 'mv -f ' End vJobHandle = DSAttachJob(JobName, DSJ.ERRFATAL) vLastRunStart = DSGetJobInfo(vJobHandle, DSJ.JOBSTARTTIMESTAMP) vLastRunEnd = DSGetJobInfo(vJobHandle, DSJ.JOBLASTTIMESTAMP) * Get the delivery log for the last run vLogSummary = DSGetLogSummary ( vJobHandle, DSJ.LOGANY, vLastRunStart, vLastRunEnd, 500) vLogSummary = Change(vLogSummary,@FM,'') * Manipulate vLogSummary within routine to return status PosOfStr = Index(Downcase(vLogSummary),"sent",1) vLogMsg = vLogSummary[PosOfStr,20] * Now work out Status If PosOfStr = 0 then Status = 'NOT SENT' vLogMsg = ''

end else Status = 'SENT' vLogMsg = vLogSummary[PosOfStr,20] end Ans = Status vErr = DSDetachJob(vJobHandle) Call DSLogInfo("Job " : JobName : " Detached" , vRoutineName) ***** Make a log entry to keep track of how often the pack doesn't work ******** vMessageToWrite = Fmt(Module_Run_Parm, "12' 'L") : Fmt(Status, "10' 'L") : " - " : vLogMsg vIdocLogFilePath = Interface_Root_Path_Parm: OsDelim : "logs" : OsDelim : "IdocSentLog.log" ******** Open the log file OPENSEQ vIdocLogFilePath TO vIdocLogFile Then Call DSLogInfo("IdocSentLog Open" , vRoutineName) ** Label to return to if file is created FileCreated: *** Write the log entry vIsLastRecord = @Null Loop Until vIsLastRecord Do READSEQ vRecord From vIdocLogFile Then *Call DSLogInfo("Record Read - " : vRecord , vRoutineName) End Else *Call DSLogInfo("End of file reached " , vRoutineName) vIsLastRecord = @True End Repeat WRITESEQ vMessageToWrite To vIdocLogFile Then Call DSLogInfo("Log entry created : " : vMessageToWrite, vRoutineName) End Else Call DSLogFatal("Cannot write to " : vIdocLogFilePath, vRoutineName) End End Else Call DSLogInfo("Could not open file - " : vIdocLogFilePath , vRoutineName) Call DSLogInfo("Creating new file - " : vIdocLogFilePath , vRoutineName) CREATE vIdocLogFile ELSE Call DSLogFatal("Could not create file - " : vIdocLogFilePath , vRoutineName) WEOFSEQ vIdocLogFile WRITESEQ Fmt("Module Run", "12' 'L") : Fmt("Status", "10' 'L") : " " : "Message" To vIdocLogFile Else ABORT Call DSLogInfo("Log file created : " : vIdocLogFilePath , vRoutineName)

GOTO FileCreated End **** Abort the delivery sequence and write error message to the log. ************ If Status = 'NOT SENT' Then Call DSLogInfo("No Idocs were actually sent to SAP - Trying to clean up IDOC Link Files: ", vRoutineName) vIdocSrcLinkPath = Field(Interface_Root_Path_Parm, OsDelim, 1, 4) : OsDelim : "dsproject" : OsDelim : Field(Interface_Root_Path_Parm, OsDelim, 4, 1) vIdocTgtLinkPath = Interface_Root_Path_Parm: OsDelim : "error" OsCmd = Move : " " : vIdocSrcLinkPath : OsDelim : JobName : ".*.lnk " : vIdocTgtLinkPath : OsDelim Call DSExecute(OsType, OsCmd, OsOutput, OsStatus) If OsStatus 0 Then Call DSLogWarn("Error when trying to move link file(s)", vRoutineName) LogMessMoveFail = 'The move command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput Call DSLogWarn(LogMessMoveFail, vRoutineName) Call DSLogFatal("Cleaning up of IDOC Link Files failed", vRoutineName) End Else LogMessMoveOK = "Link files were moved to " : vIdocTgtLinkPath Call DSLogInfo(LogMessMoveOK, vRoutineName) LogMessRetry = "Job " : JobName : " is ready to be relaunched." Call DSLogInfo(LogMessRetry, vRoutineName) End End Else Call DSLogInfo("Delivery job log indicates run OK ", vRoutineName) End ClearMappingTable: SUBROUTINE ClearMappingTable (Clear_Mapping_Table, Errorcode) Error Code = 0 ;* set this to non-zero to stop the stage/job **If Clear_Mapping_Table_Parm = 'Y' Then EXECUTE "CLEARFILE Vendor_Map_HF.GEN" **End Else **End ComaDotRmv: DataIn = "":(Arg1) If IsNull(DataIn) or DataIn = "" Then Ans = "" End Else DataIn = Ereplace(DataIn, ".", "")

DataIn = Ereplace(DataIn, ",", "") Ans = DataIn End CopyFiles: Move files from one directory to another Function CopyofFiles(sourceDir,SourceFileMask,TargetDir,TargetFileMask,Flags) RoutineName = "CopyFiles" If SourceDir = '' Then SourceDir = '.' If TargetDir = '' Then TargetDir = '.' If SourceFileMask = '' Or SourceDir = TargetDir Then Return(0) ! If SourceDir # '.' Then ! OpenPath SourceDir To Fv Else ! Call DSU.DSMkDir(MkStatus,SourceDir,'','777') ! End ! End ! If TargetDir # '.' Then ! OpenPath TargetDir To Fv Else ! Call DSU.DSMkDir(MkStatus,TargetDir,'','777') ! End ! End If System(91) Then OsType = 'NT' OsDelim = '\' NonOsDelim = '/' Copy = 'copy ' Flag = Flags End Else OsType = 'UNIX' OsDelim = '/' NonOsDelim = '\' Copy = 'cp -f ' End If Flags "" then Flag = NonOsDelim:Flags Else Flag = "" SourceWorkFiles = Trims(Convert(',',@FM,SourceFileMask)) SourceFileList = Splice(Reuse(SourceDir),OsDelim,SourceWorkFiles) Convert NonOsDelim To OsDelim In SourceFileList TargetWorkFiles = Trims(Convert(',',@FM,TargetFileMask)) TargetFileList = Splice(Reuse(TargetDir),OsDelim,TargetWorkFiles)

Convert NonOsDelim To OsDelim In TargetFileList OsCmd = Copy:' ' : Flag : " " :SourceFileList:' ':TargetFileList Call DSLogInfo('Copying ': SourceFileList: ' to ':TargetFileList,RoutineName) Call DSExecute(OsType,OsCmd,OsOutput,OsStatus) If OsStatus Then Call DSLogWarn('The Copy command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput, RoutineName) End Else Call DSLogInfo('Files moved...','DSMoveFiles') End Ans = OsStatus CopyofComareROWS: Function copyofcompareRows(Column_Name,Column_Value) $INCLUDE DSINCLUDE JOBCONTROL.H vJobName=DSGetJobInfo(DSJ.ME, DSJ.JOBNAME) vStageName=DSGetStageInfo(DSJ.ME, DSJ.ME, DSJ.STAGENAME) vCommonName=CheckSum(vJobName) : CheckSum(vStageName) : CheckSum(Column_Name) Common /vCommonName/ LastValue vLastValue=LastValue vNewValue=Column_Value If vNewValuevLastValue Then Ans=1 Else Ans=0 LastValue=vNewValue CopyOfZSTPKeyLookup Check if key passed exists in file passed Arg1: Hash file to look in Arg2: Key to look for Arg3: Number of file to use "1" or "2" * Routine to look to see if the key passed exists in the file passed * If so, then the non-key field from the file is returned * If not found, "***Not Found***" is returned * * The routine requires the UniVerse file named to have been created previously *

$INCLUDE DSINCLUDE JOBCONTROL.H EQUATE RoutineName TO 'ZSTPKeyLookup' * Call DSLogInfo("Routine started",RoutineName) Common /ZSTPkeylookup/ Init1, SeqFile1, Init2, SeqFile2, RetVal, msgtext Ans = 0 If NOT(Init1) And Arg3 = "1" Then * Not initialised. Therefore open file Init1 = 1 Open Arg1 TO SeqFile1 Then Clearfile SeqFile1 Else Call DSLogInfo("Open failed 1",RoutineName) msgtext = "Cannot open ZSTP creation control file ":Arg1 Call DSLogFatal(msgtext,RoutineName) Ans = -1 End End If NOT(Init2) And Arg3 = "2" Then * Not initialised. Therefore open file Init2 = 1 Open Arg1 TO SeqFile2 Then Clearfile SeqFile2 Else Call DSLogInfo("Open failed 2",RoutineName) msgtext = "Cannot open ZSTP creation control file ":Arg1 Call DSLogFatal(msgtext,RoutineName) Ans = -1 End End * Read the file to get the data for the key passed, if not found, return "***Not Found***" If Arg3 = "1" Then Read RetVal From SeqFile1, Arg2 Else RetVal = "***Not Found***" End Else Read RetVal From SeqFile2, Arg2 Else RetVal = "***Not Found***" End Ans = RetVal Create12CharTS: Function Create12CharTS(JobName) $INCLUDE DSINCLUDE JOBCONTROL.H

vJobHandle = DSAttachJob(JobName, DSJ.ERRFATAL) vJobStartTime = DSGetJobInfo(vJobHandle, DSJ.JOBSTARTTIMESTAMP) vDate = Trim(vJobStartTime, "-","A") vDate = Trim(vDate, ":","A") vDate = Trim(vDate, " ", "A") vDate = vDate[1,12] Ans=vDate CreateEmptyFile: Function CreateEmptyFile(Arg1,Arg2) *Create Empty File vParamFile = Arg1 : "/" : Arg2 OpenSeq vParamFile To FileVar Else Call DSLogWarn("Cannot open ":vParamFile , "Cannot Open ParamFile") End WeofSeq FileVar CloseSeq FileVar Ans="1" Datetrans: DateVal Function Datetrans(DateVal) Function DeleteFiles(SourceDir,FileMask,Flags) * Function ReverseDate(DateVal) * Date mat be in the form of DD.MM.YY i.e. 01.10.03 * convert to YYYYMMDD SAP format Ans = "20" : DateVal[7,2] : DateVal[4,2] : DateVal[1,2] DeleteFiles: RoutineName = "DeleteFiles"

If SourceDir = '' Then SourceDir = '.' If FileMask = '' SourceDir = '' Then Return(0) If System(91) Then OsType = 'NT' OsDelim = '\' NonOsDelim = '/' Delete = 'del ' End Else OsType = 'UNIX' OsDelim = '/' NonOsDelim = '\' Delete = 'rm ' : Flags : ' ' End WorkFiles = Trims(Convert(',',@FM,FileMask)) FileList = Splice(Reuse(SourceDir),OsDelim,WorkFiles) Convert NonOsDelim To OsDelim In FileList OsCmd = Delete :' ' : FileList Call DSLogInfo('Deleting ':FileList,RoutineName) Call DSExecute(OsType,OsCmd,OsOutput,OsStatus) If OsStatus Then Residx= Index(OsOutput,"non-existent",1) if Index(OsOutput,"non-existent",1) = 0 then Call DSLogInfo('The Delete command (':Residx:OsCmd:') returned status ':OsStatus:':':@FM:OsOutput,RoutineName) End Else Call DSLogInfo('No Files matched Wild Card - Delete was not required...',RoutineName) OsStatus = 0 End End Else Call DSLogInfo('Files deleted...',RoutineName) End Ans = OsStatus DisconnectNetworkDrive: Map a Network Drive on a Windows Server: Function Disconnectnetworkdrive(Drive_Letter) RoutineName = "MapNetworkDrive"

If Drive_Letter = '' Then Return(0) OsType = 'NT' OsDelim = '\' NonOsDelim = '/' Copy = 'copy ' OsCmd = 'net use ' : Drive_Letter : ": /delete" Call DSLogInfo('Disconnecting Network Drive: ' : OsCmd,RoutineName) Call DSExecute(OsType,OsCmd,OsOutput,OsStatus) If OsStatus Then Call DSLogWarn('The Copy command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput, RoutineName) End Else Call DSLogInfo('Drive: ' : Drive_Letter : 'Disconnected ',RoutineName) End Ans = OsStatus DosCmd: Move files from one directory to another: Function DosCmd(Cmd) RoutineName = "DosCmd" If System(91) Then OsType = 'NT' OsDelim = '\' NonOsDelim = '/' End Else OsType = 'UNIX' OsDelim = '/' NonOsDelim = '\' End OsCmd = Cmd Call DSLogInfo("CMD = " : Cmd,RoutineName) Call DSExecute(OsType,OsCmd,OsOutput,OsStatus) If OsStatus Then Call DSLogWarn('The command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput, RoutineName) End Else Call DSLogInfo('The command (':OsCmd:') was successfull ':OsStatus:':':@FM:OsOutput,RoutineName)

End Ans = OsStatus : " - " : OsOutput DSMoveFiles: Move files from one directory to another: f SourceDir = '' Then SourceDir = '.' If TargetDir = '' Then TargetDir = '.' If FileMask = '' Or SourceDir = TargetDir Then Return(0) If System(91) Then OsType = 'NT' OsDelim = '\' NonOsDelim = '/' Move = 'move ' End Else OsType = 'UNIX' OsDelim = '/' NonOsDelim = '\' Move = 'mv -f ' End WorkFiles = Trims(Convert(',',@FM,FileMask)) FileList = Splice(Reuse(SourceDir),OsDelim,WorkFiles) Convert NonOsDelim To OsDelim In FileList OsCmd = Move:' ' : FileList: ' ':TargetDir Call DSLogInfo('Moving ':FileList: ' to ':TargetDir,'DSMoveFiles') Call DSExecute(OsType,OsCmd,OsOutput,OsStatus) If OsStatus Then Call DSLogInfo('The move command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput,'DSMoveFiles') End Else Call DSLogInfo('Files moved...','DSMoveFiles') End Ans = OsStatus Routine Name:ErrorMgmtDummy: Value: The Value to Be Mapped FieldName: The Name of the source field that the Value is contained in Format: The name of the Hash file containing the mapping data Default: The Default value to return if value is not found Msg: ny text you want to store against an error SeverityInd: The Error Severity Indicator: I-Information, W-Warning, E-Error, F-Fatal ErrorLogInd: An Indicator to indicate of errors should be logged (Note this is not yet

implemented) HashFileLocation: A Hashfile could be either local to the Module or Generic. Enter "G" for Generic "L" for Local * FUNCTION Map(Value,FieldName,Format,Default,Msg,ErrorLogInd) * * Executes a lookup against a hashed file using a key * * Input Parameters : Arg1: Value = The Value to be Mapped or checked * Arg2: FieldName = The Name of the field that is either the Target of the Derivation or the sourceField that value is contained in * Arg3: Format = The name of the Hash file containing the mapping data * Arg4: Default = The Default value to return if value is not found * Arg5: Msg = Any text you want stored against an error * Arg6: SeverityInd = An Indicator to the servity Level * Arg7: ErrorLogInd = An Indicator to indicate if errors should be logged * Arg8: HashfileLocation = An Indicator to indicate of errors should be logged (Note this is not yet implemented) * * Return Values: If the Value is not found, return value is: -1. or the Default value if that is supplied * If Format Table not found, return value is: -2 * * * RoutineName = 'Map' Common /HashLookup/ FileHandles(100), FilesOpened Common /TicketCommon/ Ticket_Group, Ticket_Sequence, Set_Key, Mod_Root_Path, Generic_Root_Path, Chk_Hash_File_Name, Mod_Run_Num DEFFUN LogToHashFile(ModRunNum,Ticket_Group,Ticket_Sequence,Set_Key,Table,FieldNam e,Key,Error,Text,SeverityInd) Calling 'DSU.LogToHashFile' If (Ans = "-1" or Ans = "-2" or UpCase(Ans)= "BLOCKED") and ErrorLogInd = "Y" Then Ret_Code=LogToHashFile(Mod_Run_Num,Ticket_Group,Ticket_Sequence,Set_Key,Ta ble,FieldName,Chk_Value,Ans,Msg,SeverityInd) End RETURN(Ans) FileExists: Move files from one directory to another Function File Exits(Filename) Routine Name = "File Exists"

File Found = @TRUE OPENSEQ FileName TO aFile ON ERROR STOP "Cannot open file (":FileName:")" THEN CLOSESEQ aFile END ELSE FileFound = @FALSE ;* file not found END Ans = FileFound FileSize: Returns the size of a file Function FileSize(FileName) RoutineName = "FileSize" FileSize = -99 OPENSEQ FileName TO aFile ON ERROR STOP "Cannot open file (":FileName:")" THEN status FileInfo from aFile else stop FileSize=Field(FileInfo,@FM,4) * FileSize=FileInfo CLOSESEQ aFile END ELSE FileSize = -999 END Ans = FileSize FindExtension: FunctionFindExtesion(Arg1) File_Name=Arg1 * Gets rid of the extension part of the filename LengthofFileName = Len(File_Name) Extension = Index(File_Name, ".", 1) If Extension 0 Then LengthofExtension = LengthofFileName - Extension + 1 File_Extension=File_Name[Extension,LengthofExtension] End Else End Ans = File_Extension FindFileSuffix:

Function FindFileSuffix(Arg1) File_Name=Arg1 * Gets rid of the extension part of the filename Extension = Index(File_Name, ".", 1) If Extension 0 Then MyLenRead=Index(File_Name, ".", 1) - 1 File_Name=File_Name[0,MyLenRead] End Else End * Gets the timestamp. Doesn't handle the case where there are suffix types and timestamp only contains 5 digits without "_" inbetween If Index(File_Name, "_", 6) = 0 Then MyLenRead=Index(File_Name, "_", 4) + 1 MyTimestamp = File_Name[MyLenRead,Len(File_Name)-1] End Else MyTimestamp = Field(File_Name,"_",5):"_":Field(File_Name,"_",6) End TimestampEndPos = Index(File_Name,MyTimestamp,1) + Len(MyTimestamp) MySuffix = File_Name[TimestampEndPos + 1, Len(File_Name)] Ans = MySuffix FindTimeStamp: Function FindTimeStamp(Arg1) File_Name=Arg1 * Gets rid of the extension part of the filename Extension = Index(File_Name, ".", 1) If Extension 0 Then MyLenRead=Index(File_Name, ".", 1) - 1 File_Name=File_Name[0,MyLenRead] End Else End * Gets the timestamp. Doesn't handle the case where there are suffix types and timestamp only contains 5 digits without "_" inbetween If Index(File_Name, "_", 6) = 0 Then MyLenRead=Index(File_Name, "_", 4) + 1 Timestamp = File_Name[MyLenRead,Len(File_Name)-1] End Else Timestamp = Field(File_Name,"_",5):"_":Field(File_Name,"_",6) End Ans = Timestamp

formatCharge: Function FormatCharge(Arg1) vCharge=Trim(Arg1, 0, "L") vCharge=vCharge/100 vCharge=FMT(vCharge,"R2") Ans=vCharge formatGCharge: Ans=1 vLength=Len(Arg1) vMinus=If Arg1[1,1]='-' Then 1 Else 0 If Arg1='0.00' Then Ans=Arg1 End Else If vMinus=1 Then vString=Arg1[2,vLength-1] vString='-':Trim(vString, '0','L') End else vString=Trim(Arg1, '0','L') end Ans=vString End FTPFile: Script_Path: he path to where the Unix Script file lives File_Path: The Value to Be Mapped File_Name: The Name of the source field that the Value is contained in IP_Address: The name of the Hash file containing the mapping data User_ID: The Default value to return if value is not found Password: Any text you want to store against an error Target_Path: The target path where the ifle is to saved on the target server

* FUNCTION FTPFile(Script_Path,File_Path,File_Name,IP_Address, User_ID,Password,Target_Path) * * RoutineName = 'FTPFile' OsCmd = Script_Path : "/ftp_put.sh":" ":File_Path:" ":File_Name:" ":IP_Address:" ":User_ID:" ":Password:" ":Target_Path :" ":Script_Path Call DSLogInfo('Ftp ':File_Name: ' to ' : IP_Address : ' ' :Target_Path,'FTPFile') Call DSLogInfo('Ftp Script = ':Script_Path,'FTPFile') Call DSExecute("UNIX",OsCmd,OsOutput,OsStatus) If OsStatus Then Call DSLogInfo('The FTP command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput,'DSMoveFiles') End Else Call DSLogInfo('Files FTPd...': '(':OsCmd:')','FTPFile') End Ans = OsStatus RETURN(Ans) FTPmget: * FUNCTION FTPFile(Script_Path,Source_Path,File_Wild_Card,IP_Address, User_ID,Password,Target_Path) * * RoutineName = 'FTPmget' OsCmd = Script_Path:"/ftp_Mget.sh":" ":Source_Path:" ":File_Wild_Card:" ":IP_Address:" ":User_ID:" ":Password:" ":Target_Path:" ":Script_Path *OsCmd = Script_Path : "/test.sh" Call DSLogInfo('Ftp ':File_Wild_Card: ' From ' : IP_Address : ' ' :Source_Path : ' to ' :Target_Path,RoutineName) Call DSExecute("UNIX",OsCmd,OsOutput,OsStatus) If OsStatus Then Call DSLogInfo('The FTP command (':OsCmd:') returned status ':OsStatus:':':@FM:OsOutput,'DSMoveFiles')

End Else Call DSLogInfo('Files FTPd...': '(':OsCmd:')',RoutineName) End Ans = OsStatus RETURN(Ans) Concatenate All Input Arguments to Output using TAB character Concatenate All Routine="GBIConcatItem" t = Char(009) If ISNULL(IND) THEN Pattern = "" ELSE Pattern = IND [1,1] If ISNULL(VKORG) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : VKORG [1,4] If ISNULL(VTWEG) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : VTWEG [1,2] If ISNULL(SPART) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : SPART [1,2] If ISNULL(WERKS) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : WERKS [1,4] If ISNULL(AUART) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : AUART [1,4] If ISNULL(FKDAT) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : FKDAT [1,8] If ISNULL(KUNAG) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : KUNAG [1,10] If ISNULL(KUNRE) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : KUNRE [1,10] If ISNULL(MATNR) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : MATNR [1,18] If ISNULL(PSTYV) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : PSTYV [1,4] If ISNULL(KWMENG) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : KWMENG [1,15] If ISNULL(XBLNR) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : XBLNR [1,16] If ISNULL(VGPOS) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : VGPOS [1,6] If ISNULL(FKARA) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : FKARA [1,4] If ISNULL(ZOR_DT_PCODE) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : ZOR_DT_PCODE [1,8] If ISNULL(ZAWB) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : ZAWB [1,16] If ISNULL(LGORT) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : LGORT [1,4] If ISNULL(VKAUS) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : VKAUS [1,3] If ISNULL(VKBUR) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t :

VKBUR [1,4] If ISNULL(VKGRP) VKGRP [1,3] If ISNULL(ZLSCH) ZLSCH [1,1] If ISNULL(ZTERM) ZTERM [1,4] If ISNULL(KURSK) KURSK [1,9] If ISNULL(TAXM1) TAXM1 [1,1] If ISNULL(VRKME) VRKME [1,3] If ISNULL(ARKTX) ARKTX [1,40] If ISNULL(KTGRM) KTGRM [1,2] If ISNULL(ZZTAXCD) ZZTAXCD [1,2] If ISNULL(LAND2) LAND2 [1,3] If ISNULL(NAME1) NAME1 [1,35] If ISNULL(PSTLZ) PSTLZ[1,10] If ISNULL(ORT01) ORT01 [1,35] If ISNULL(KOSTL) KOSTL[1,10] If ISNULL(WAERS) WAERS [1,5] If ISNULL(KUNRG) KUNRG [1,10] If ISNULL(KUNWE) KUNWE [1,10] Ans = Pattern

THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t

ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t :

GBIConcatItem: Concatenate All Input Arguments to Output using TAB character: Routine="GBIConcatItem" t = Char(009) If ISNULL(IND) THEN Pattern = "" ELSE Pattern = IND [1,1] If ISNULL(KNUMV) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : KNUMV [1,16] If ISNULL(KPOSN) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : KPOSN [1,6] If ISNULL(KSCHL) THEN Pattern = Pattern : t ELSE Pattern = Pattern : t : KSCHL [1,4]

If ISNULL(KBETR) [1,11] If ISNULL(KWERT) KWERT [1,13] If ISNULL(WAERS) WAERS [1,5] If ISNULL(KAWRT) KAWRT [1,15] If ISNULL(KHERK) [1,1] Ans = Pattern

THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t THEN Pattern = Pattern : t

ELSE Pattern = Pattern : t : KBETR ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : ELSE Pattern = Pattern : t : KHERK

GCMFConvert: Receive GCMF string and change known strings to required values: DataIn = "":Trim(Arg1) If IsNull(DataIn) or DataIn = "" Then Ans = "" End Else DataIn = Ereplace (DataIn,"$B$","") DataIn = Ereplace (DataIn,"NULL","") DataIn = Ereplace (DataIn,"", ">") DataInFmt = Ereplace (DataInFmt ,"" : Job_Stage_Name * Call DSLogInfo(Message, RoutineName ) *Message = "Map Mod Root Path ==>" : Mod_Root_Path * Call DSLogInfo(Message, RoutineName ) *Message = "Generic Root Path ==>" : Generic_Root_Path * Call DSLogInfo(Message, RoutineName ) *Message = "Map Chk_Hash_File_Name ==>" : Chk_Hash_File_Name * Call DSLogInfo(Message, RoutineName ) *Message = "Map Mod_Run_Num ==>" : Mod_Run_Num * Call DSLogInfo(Message, RoutineName ) DEFFUN

LogToHashFile(ModRunNum,Ticket_Group,Ticket_Sequence,Set_Key,Table,FieldNam e,Key,Error,Text,SeverityInd) Calling 'DSU.LogToHashFile' * If Len(Chk_Hash_File_Name) = 3 And HashFileLocation = "G" Then Format_Extn = Chk_Hash_File_Name Else Format_Extn = Mod_Run_Num [1,5] If System(91) Then OsType = 'NT' OsDelim = '\' NonOsDelim = '/' Move = 'move ' End Else OsType = 'UNIX' OsDelim = '/' NonOsDelim = '\' Move = 'mv -f ' End ColumnPosition = 0 PositionReturn = 0 Table = Format If HashFileLocation = "G" then PathFormat = Generic_Root_Path : OsDelim :"format" : OsDelim: Format : "_HF." : Format_Extn End Else PathFormat = Mod_Root_Path : OsDelim :"format" : OsDelim : Format : "_HF." : Format_Extn End If IsNull(Value) then Chk_Value = "" Else Chk_Value = Value *Message = "Map PathFormat ==>" : PathFormat *Call DSLogInfo(Message, RoutineName ) *Message = "Value ==>" : Value *Call DSLogInfo(Message, RoutineName ) *Message = "Format ==>" : Format *Call DSLogInfo(Message, RoutineName ) *Message = "Default ==>" : Default *Call DSLogInfo(Message, RoutineName ) *Message = "ErrorLogInd ==>" : ErrorLogInd *Call DSLogInfo(Message, RoutineName ) * Set the Default Answer for if a value is not found

Begin Case Case UpCase(Default) = "NODEF" Default_Ans = "-1" Case Default = "PASS" NumFields = Dcount(Chk_Value, "|") If NumFields > 1 Then Default_Ans = Field(Chk_Value,"|",2) *Message = "Num Fields > 1 Default_Ans ==>" : Default_Ans : "#" : Chk_Value *Call DSLogInfo(Message, RoutineName ) End Else Default_Ans = Chk_Value *Message = "Num Fields NG 0 Default_Ans ==>" : Default_Ans : "#" : Chk_Value *Call DSLogInfo(Message, RoutineName ) End Case @TRUE If UpCase(Field(Default,"|",1)) "BL" Then Default_Ans = Default Else Default_Ans = -1 End Case * Determine if we are returning one column or entire row. If Num(ColumnPosition) then ColumnPosition = Int(ColumnPosition) If ColumnPosition > 0 and ColumnPosition < 99999 Then PositionReturn = 1 End End * Attempt to find the table name in our cache. Locate Format in FilesOpened Setting POS Then Read Rec From FileHandles(POS), Chk_Value Then If PositionReturn Then Ans = Rec Else Ans = Rec End Else Ans = Default_Ans End End Else * Table is not in cache of opened tables, so open it. Openpath PathFormat To FileHandles(POS) Then FilesOpened = Format Read Rec From FileHandles(POS), Chk_Value Else Rec = Default_Ans End If PositionReturn And Rec Default_Ans Then Ans = Rec End Else

Ans = Rec End End Else Ans = "-2" End End If UpCase(Field(Default,"|",1)) = "BL" and Ans -2 Then If Chk_Value = "" then Ans = Field(Default,"|",2) End End *Message = "Outside LOGGING" : Mod_Run_Num: "|" : Ticket_Group : "|" : Ticket_Sequence "|" : Set_Key : "|" : Table : "|" : FieldName : "|" : Chk_Value : "|" : Msg *Call DSLogInfo(Message, RoutineName ) *Message = "OUTSIDE PASS Trans Default_Ans ==>" : Default_Ans : " Ans ==> " : Ans *Call DSLogInfo(Message, RoutineName ) LogPass = "N" If (Default = "PASS" and Default_Ans Ans) then LogPass = "Y" If LogPass = "Y" Then *Message = "PASS Trans Default_Ans ==>" : Default_Ans : " Ans ==> " : Ans *Call DSLogInfo(Message, RoutineName ) End If (Ans = "-1" or Ans = "-2" or UpCase(Ans)= "BLOCKED" or LogPass = "Y" or SeverityInd = "I") and ErrorLogInd = "Y" Then *Message = "Write to Log Ans==> " : Ans : " ErrorInd==> " : ErrorLogInd *Message = "LOGGING" : Mod_Run_Num: "|" : Ticket_Group : "|" : Ticket_Sequence : "|" : Table : "|" : FieldName : "|" : Chk_Value : "|" : Ans *Call DSLogInfo(Message, RoutineName ) Ret_Code=LogToHashFile(Mod_Run_Num,Ticket_Group,Ticket_Sequence,Set_Key,Ta ble,FieldName,Chk_Value,Ans,Msg,SeverityInd) End RETURN(Ans) OutputJobStats: Outputs the job link statistics

$INCLUDE DSINCLUDE JOBCONTROL.H hJob = DSAttachJob(JobName, DSJ.ERRFATAL) Start_TS = DSGetJobInfo (hJob, DSJ.JOBSTARTTIMESTAMP) End_TS = DSGetJobInfo (hJob,DSJ.JOBLASTTIMESTAMP) Elapsed_Secs_Cnt = DSGetJobInfo (hJob,DSJ.JOBELAPSED) Job_Term_Status = DSGetJobInfo (hJob,DSJ.JOBINTERIMSTATUS) User_Status = DSGetJobInfo (hJob,DSJ.USERSTATUS) ErrCode = DSDetachJob(hJob) Ans = Start_TS : "|" : End_TS : "|" : Elapsed_Secs_Cnt : "|" : Job_Term_Status : "|" : User_Status Pattern: Routine="Pattern" Var_Len = len(Value) Pattern = Value For i = 1 To Var_Len If Num(Value [i,1]) Then Pattern [i,1] = "n" end Else If Alpha(Value [i,1]) Then Pattern[i,1] = "a" end Else Pattern[i,1] = Value [i,1] end end Next i Ans = Pattern Checks a passed field to see if it matches the pattern which is also passed.: The input field is checked to see if it conforms to the format that is also passed as a second parameter. The result of the routine is True is the pattern matches the required format, and false if it does not. If the second parameter is empty, then true is returned. Equate TransformName To "PatternMatchCheck" Begin Case

Case Arg2 = "" ;* No pattern - so return true Ans = 1 Case Arg3 = "" ;* Only 1 pattern passed Ans = Arg1 Matches Arg2 Case 1 ;* All other cases Ans = Arg1 Matches Arg2 : CHAR(253) : Arg3 End Case PrepareJob: $INCLUDE DSINCLUDE JOBCONTROL.H Job_Handle = DSAttachJob (Job_Name, DSJ.ERRWARN) ErrCode1=DSPrepareJob(Job_Handle) ErrCode2 = DSDetachJob(Job_Handle) Ans= ErrCode2 RangeCheck: * FUNCTION Map(Value,FieldName,Format,Default,Msg,ErrorLogInd) * * Executes a lookup against a hashed file using a key * * Input Parameters : Arg1: Value = The Value to be checked * Arg2: MinValue = The Min Value allowed * Arg3: MaxValue = The Max Value allowed * Arg4: FieldName = The Name of the Source field being checked * Arg5: Msg = Any text you want stored against an error * Arg6: SeverityInd = An Indicator to the servity Level * Arg7: ErrorLogInd = An Indicator to indicate if errors should be logged * * Return Values: If the Value is not found, return value is -1. else the value supplied is returned * * * RoutineName = 'RangeChk' Common /TicketCommon/ Ticket_Group, Ticket_Sequence,Set_Key, Mod_Root_Path, Generic_Root_Path, Chk_Hash_File_Name, Mod_Run_Num DEFFUN LogToHashFile(ModRunNum,Ticket_Group,Ticket_Sequence,Set_Key,Table,FieldNam e,Key,Error,Text,SeverityInd) Calling 'DSU.LogToHashFile' Table = "Min: " : MinValue "to Max: " : MaxValue Msg1 = "" Msg2 = ""

Msg3 = "" Msg4 = "" Ans = "" If Num (Value) = 0 then Msg1 = "-Value is not a number" Ans = -2 End If Num (Value) = 0 then Msg2 = "-MinValue is not a number" Ans = -2 End If Num (Value) = 0 then Msg3 = "-MaxValue is not a number" Ans = -2 End If Ans -2 Then If Value < MinValue Or Value > MaxValue Then Msg4 = "-Value is outside the Range" Ans = -1 End End OutputMsg = Msg : Msg1 : Msg2 : Msg3: Msg4 *Call DSLogInfo(OutputMsg, RoutineName ) If Ans -1 and Ans -2 then Ans = Value If (Ans = "-1" or Ans = "-2") and ErrorLogInd = "Y" Then Ret_Code=LogToHashFile(Mod_Run_Num,Ticket_Group,Ticket_Sequence,Set_Key,Ta ble,FieldName,Value,Ans,OutputMsg,SeverityInd) End RETURN(Ans) ReadParameter: Read parameter value from configuration file * * Function : ReadParameter - Read parameter value from configuration file * Arg : ParameterName (default=JOB_PARAMETER) * DefaultValue (default='') * Config file ([email protected]/config.ini) * Return : Parameter value from config file Function Readparameters(parametersname,Defaultvalue,ConfigFile)

* Function : ReadParameter - Read parameter value from configuration file * Arg : ParameterName (default=JOB_PARAMETER) * DefaultValue (default='') * Config file ([email protected]/config.ini) * Return : Parameter value from config file * If ParameterName = "" Then ParameterName = "JOB_PARAMETER" If ConfigFile = "" Then ConfigFile = @PATH:"/config.ini" ParameterValue = DefaultValue OpenSeq ConfigFile To fCfg Else Call DSLogFatal("Error opening file ":ConfigFile, "ReadParameter") Loop While ReadSeq Line From fCfg If Trim(Field(Line,'=',1)) = ParameterName Then ParameterValue = Trim(Field(Line,'=',2)) Exit End Repeat CloseSeq fCfg Ans = ParameterValue RETURN(Ans) ReturnNumber: String=Arg1 Slen=Len(String) Scheck=0 Rnum="" For Scheck = 1 to Slen Schar=Substrings(String,Scheck,1) If NUM(Schar) then Rnum=Rnum:Schar End Next Outer Ans=Rnum

ReturnNumbers: length=0 length=LEN(Arg1); length1=1; Outer=length; postNum='' counter=1; For Outer = length to 1 Step -1 Arg2=Arg1[Outer,1] If NUM(Arg2) then length2=counter-1 if length2 = 0 then length2=counter postNum=RIGHT(Arg1,length2) END else postNum=RIGHT(Arg1,counter) END END counter=counter+1 Next Outer Ans=postNum ReverseDate: Function ReverseDate(DateVal) * Function ReverseDate(DatelVal) * Date mat be in the form of DDMMYYYY i.e. 01102003 or DMMYYYY 1102003 If Len(DateVal) = 7 then NDateVal = "0" : DateVal End Else NDateVal = DateVal End Ans = NDateVal[5,4] : NDateVal[3,2] : NDateVal[1,2] RunJob: The routine runs a job. Job parameters may be supplied. The result is a dynamic array containing the job status, and row count information for each link. The routine UtilityGetRunJobInfo can be used to interpret this result.

As well as the job name and job parameters, the routine parameters allow the job warning limit and row count limit to be set. Format of returned dynamic array: Status=Jobname=FinishStatus Status=Jobname Status=JobStartTimeStamp Status=JobStopTimeStamp Status=LinkNames (value mark @VM delimited) Status=RowCount (value mark @VM delimited) FunctionRunJob(Arg1,Arg2,Arg3,Arg4) * Demonstrate how to run a job within the GUI development enviroment. Arguments may * be passed in. The result is a dynamic array with the resulting status and run * statistics (row counts for every link on every stage in the job) * $INCLUDE DSINCLUDE JOBCONTROL.H Equate RoutineName To 'RunJob' Equate RunJobName to Arg1 Equate Params To Arg2 Equate RowLimit To Arg3 Equate WarnLimit To Arg4 Dim Param(100,2) ;* Limited to max of 100 parameters Deffun DSRMessage(A1, A2, A3) Calling "*DataStage*DSR_MESSAGE" Deffun DSRTimestamp Calling "DSR_TIMESTAMP" JobHandle = '' Info = '' ParamCount = Dcount(Params,'|') If RowLimit = '' Then RowLimit = 0 If WarnLimit = '' Then WarnLimit = 0 For ParamNum = 1 to ParamCount Param(ParamNum,1) = Field(Field(Params,'|',ParamNum),'=',1) Param(ParamNum,2) = Field(Field(Params,'|',ParamNum),'=',2) Next ParamNum JobStartTime = DSRTimestamp() JobHandle = DSAttachJob(RunJobName, DSJ.ERRFATAL) * Prepare the job

ErrorCode = DSPrepareJob(JobHandle) Message = DSRMessage('DSTAGE_TRX_I_0014', 'Attaching job for processing - %1 Status of Attachment = %2', RunJobName:@FM:JobHandle ) Call DSLogInfo(Message, RoutineName) LimitErr = DSSetJobLimit(JobHandle, DSJ.LIMITROWS, RowLimit) LimitErr = DSSetJobLimit(JobHandle, DSJ.LIMITWARN, WarnLimit) * Need to check if error occurred. ListOfParams = DSGetJobInfo(JobHandle, DSJ.PARAMLIST) ListCount = Dcount(ListOfParams,',') For ParamNum = 1 To ParamCount Message = DSRMessage('DSTAGE_TRX_I_0015', 'Setting Job Param - %1 Setting to %2', Param(ParamNum,1):@FM:Param(ParamNum,2)) Call DSLogInfo(Message, RoutineName) ErrCode = DSSetParam(JobHandle, Param(ParamNum,1),Param(ParamNum,2)) Next ParamNum ErrCode = DSRunJob(JobHandle, DSJ.RUNNORMAL) ErrCode = DSWaitForJob(JobHandle) Status = DSGetJobInfo(JobHandle, DSJ.JOBSTATUS) JobEndTime = DSRTimestamp() If Status = DSJS.RUNFAILED Then Message = DSRMessage( 'DSTAGE_TRX_E_0020', 'Job Failed: %1', RunJobName) Call DSLogWarn(Message, RoutineName) End * Retrieve more information about this job run. Message = DSRMessage('DSTAGE_TRX_I_0016', 'Getting job statistics', '' ) Call DSLogInfo(Message, RoutineName) StageList = DSGetJobInfo(JobHandle,DSJ.STAGELIST) Message = DSRMessage('DSTAGE_TRX_I_0017', 'List of Stages=%1', StageList ) Call DSLogInfo(Message, RoutineName) StageCount = Dcount(StageList, ',') ; * Count number of active stages. Info = RunJobName Info = JobStartTime ;* StartTime (Timestamp format) Info = JobEndTime ;* Now/End (Timestamp format) FOR Stage = 1 To StageCount * Get links on this stage. LinkNames = DSGetStageInfo(JobHandle,Field(StageList,',',Stage),DSJ.LINKLIST) Message = DSRMessage( 'DSTAGE_TRX_I_0018', 'LinkNames for Stage.%1 = %2', Field(StageList,',',Stage):@FM:LinkNames) Call DSLogInfo(Message, RoutineName) LinkCount = Dcount(LinkNames,',') For StageLink = 1 To LinkCount * Get Rowcount For this linkname

RowCount = DSGetLinkInfo(JobHandle,Field(StageList,',',Stage),Field(LinkNames,',',StageLink),DSJ. LINKROWCOUNT) Message = DSRMessage( 'DSTAGE_TRX_I_0019', 'RowCount for %1.%2=%3', Field(StageList,',',Stage):@FM:Field(LinkNames,',',StageLink):@FM:RowCount) Call DSLogInfo(Message, RoutineName) Info = Field(StageList,',',Stage):'.':Field(LinkNames,',',StageLink) Info = RowCount Next StageLink Next Stage Message = DSRMessage( 'DSTAGE_TRX_I_0020', 'RunJob Status=%1', Info ) Call DSLogInfo(Message, RoutineName) Ans = RunJobName:'=':Status:@FM:Info

RunJobAndDetach: The routine runs a job. Job parameters may be supplied. The job is detached from so tht others may be started immediately and the control job finish. As well as the job name and job parameters, the routine parameters allow the job warning limit and row count limit to be set. FunctionRunDetachJob(Arg1,Arg2,Arg3,Arg4) * Run a job, and detach from it so that this job can end * $INCLUDE DSINCLUDE JOBCONTROL.H Equate RoutineName To 'RunJobAndDetach' Equate RunJobName To Arg1 Equate Params To Arg2 Equate RowLimit To Arg3 Equate WarnLimit To Arg4 Dim Param(100,2) ;* Limited to max of 100 parameters Deffun DSRMessage(A1, A2, A3) Calling "*DataStage*DSR_MESSAGE" Deffun DSRTimestamp Calling "DSR_TIMESTAMP" JobHandle = '' Info = '' ParamCount = Dcount(Params,'|') If RowLimit = '' Then RowLimit = 0

If WarnLimit = '' Then WarnLimit = 0 For ParamNum = 1 to ParamCount Param(ParamNum,1) = Field(Field(Params,'|',ParamNum),'=',1) Param(ParamNum,2) = Field(Field(Params,'|',ParamNum),'=',2) Next ParamNum * Attach to the job JobHandle = DSAttachJob(RunJobName, DSJ.ERRWARN) If JobHandle = 0 Then Call DSLogInfo("Job ":RunJobName:" not started - attach failed",RoutineName) Else * Prepare the job ErrorCode = DSPrepareJob(JobHandle) Message = DSRMessage('DSTAGE_TRX_I_0014', 'Attaching job for processing - %1 Status of Attachment = %2', RunJobName:@FM:JobHandle ) Call DSLogInfo(Message, RoutineName) LimitErr = DSSetJobLimit(JobHandle, DSJ.LIMITROWS, RowLimit) LimitErr = DSSetJobLimit(JobHandle, DSJ.LIMITWARN, WarnLimit) * Need to check if error occurred. ListOfParams = DSGetJobInfo(JobHandle, DSJ.PARAMLIST) ListCount = Dcount(ListOfParams,',') For ParamNum = 1 To ParamCount Message = DSRMessage('DSTAGE_TRX_I_0015', 'Setting Job Param - %1 Setting to %2', Param(ParamNum,1):@FM:Param(ParamNum,2)) Call DSLogInfo(Message, RoutineName) ErrCode = DSSetParam(JobHandle, Param(ParamNum,1),Param(ParamNum,2)) Next ParamNum ErrCode = DSRunJob(JobHandle, DSJ.RUNNORMAL) ErrCode = DSDetachJob(JobHandle) End Ans = 0 RunShellCommandReturnStatus: Function RunShellcommandreturnstatus(Command) Call DSLogInfo('Running command:':Command,'RunShellCommandReturnStatus') Call DSExecute('UNIX',Command,Ans,Ret) Call DSLogInfo('Output from command:':Ans,'RunShellCommandReturnStatus') Return(Ret)

SegKey: Segment_Num: An Integer number representing the order number of the Segment in the IDoc Segment_Parm: A Segment Parameter containing a string of Y's and N's in order of Segment_Num denoting of the segment should be written to in this Module Key: The Value to Be Mapped ErrorLogInd: An Indicator to indicate of errors should be logged (Note this is not yet implemented) Function Seqkey(Segment_Num,segmentparam,key,ErrorLogInd) * FUNCTION SegKey(Value,ErrorLogInd) * * Executes a lookup against a hashed file using a key * * Input Parameters : Arg1: Segment_Num * Arg2: Segment_Parm * Arg1: Key = An ordered Pip separated set of Seqment Primary Key Fields * Arg2: ErrorLogInd = An Indicator to indicate of errors should be logged (Note this is not yet implemented) * * Return Values: If the Value is not found, return value is: -1. or the Default value if that is supplied * If Format Table not found, return value is: -2 * * * RoutineName = 'SegKey' BlankFields = "" CRLF = Char(13) : Char(10) Message = "IN Seg Key" : Segment_Num : "|" : Segment_Parm : "|" : Key : "|" : ErrorLogInd : "|" * Call DSLogInfo(Message, RoutineName ) * Determine if this segment should output Write_Ind = Field(Segment_Parm,"|",Segment_Num) If Write_Ind = "Y" then * Count how many keys NumKeys = Dcount(Key,"|") * Make a list of any keys that are missing

Blank_Key_Cnt = 0 ReturnKey = "" For i = 1 to NumKeys Key_Part = Field(Key,"|",i) if Key_Part = "" Then Blank_Key_Cnt = Blank_Key_Cnt + 1 BlankFields = i end ReturnKey = ReturnKey : Key_Part Next i If Blank_Key_Cnt > 0 and ErrorLogInd = "Y" then Message = "Error in Segment Key: ": Segment_Num : " There are " : Blank_Key_Cnt : " Missing Key Parts " : "The Missing Key Parts are" : BlankFields * Call DSLogInfo(Message, RoutineName ) End If Blank_Key_Cnt > 0 then Ans = "Invalid_Key" End Else Ans = ReturnKey End End Else Ans = "Invalid_Key" End SetDSParamsFromFile: A before job subroutine to set Job parameters from an external flat file Input Arg should be of the form: ParamDir,ParamFile If ParamDir is not supplied, the routine assumes the Project directory If ParamFile is not supplied, the routine assumes the Job Name (this could be dangerous) The routine will abort the job if anything doesn't go to plan Note: a lock is placed to stop the same job from running another instance of this routine. The second instance will have to wait for the routine to finish before being allowed to proceed. The lock is released however the routine terminates (normal, abort...) The parameter file should contain non-blank lines of the form ParName = ParValue White space is ignored. The Routine may be invoked via the normal Before Job Subroutine setting, or from

within the 'Job Properties->Job Control' window by entering "Call DSU.SetParams('MyDir,MyFile',ErrorCode)" For Andrew Webb's eyes only The routine could be made to work off a hashed file, or environment variables quite easily. It is not possible to create Job Parameters on-the-fly because they are referenced within a Job via an EQUATE of the form JobParam%%1 = STAGECOM.STATUS JobParam%%2 = STAGECOM.STATUS etc This is then compiled up....So forget it! Subroutinues SetDsparmsformfile(inputArg,Errorcode) $INCLUDE DSINCLUDE DSD_STAGE.H $INCLUDE DSINCLUDE JOBCONTROL.H $INCLUDE DSINCLUDE DSD.H $INCLUDE DSINCLUDE DSD_RTSTATUS.H Equ SetParams To 'SetDSParamsFromFile' ErrorCode = 0 ; * set this to non-zero to stop the stage/job JobName = Field(STAGECOM.NAME,'.',1,2) ParamList = STAGECOM.JOB.CONFIG If ParamList = '' Then Call DSLogWarn('Parameters may not be externally derived if the job has no parameters defined.',SetParams) Return End Call DSLogInfo("SetDSParmsFromFile inputarg >" : InputArg : " Ans) status = SQLBindCol(hStmt, 1, SQL.B.DEFAULT, res) status = SQLFetch(hStmt) If statusSQL.SUCCESS AND statusSQL.SUCCESS.WITH.INFO Then Call DSLogInfo("Result KO", "ExecSQLProc") Ans = -1 Goto Finally End Else Call DSLogInfo("Result OK ", "ExecSQLProc") Call DSLogInfo("The result is " : res, "ExecSQLProc") Ans = 0 End

** Free allocated ressources Finally: status = status = status = status = SQLFreeStmt(hStmt, SQL.DROP) SQLDisconnect(hConn) SQLFreeConnect(hConn) SQLFreeEnv(hEnv)