;========================================================================================================================================== ; Extract substring from string. ; ; Profiling Performance Contest. ; ; - udfStringExtract_1 ; - udfStringExtract_2 ; - udfStringExtract_3 ; ;------------------------------------------------------------------------------------------------------------------------------------------ ; ; Topic: Several StrIndex's ; Conf: WinBatch ; From: MW4 ; Date: Wednesday, January 05, 2011 12:03 PM ; ; No -- there is text after that I need, but I need that "X" line position to grab that. ; ; Better example: ; ; as de 123dek / ab16 fb Xjdheeh BVP 34319 21489 ; kfj jo200 / hb47 fb32 Xjwjw BVP 51123 81000 ; ke kl5 / jh23 fb1 Xokeksmdd BVP 21000 21000 ; 5 5 5 e krk / uy56 fb44 Xssd BVP 21000 21000 ; ; The right part (right of my X) starting with BVP is fixed at BVP, space, 5 digits, space, 5 digits ; ; The left part (left of the X) is completely variable in size and number of spaces to the left of ; the "/", but the "/" and the three spaces to the right are always there. ; ; The "X" part that I need to pull is always variable in size. ; ;------------------------------------------------------------------------------------------------------------------------------------------ ; (c)Detlev Dalitz.20110105. ;========================================================================================================================================== ; How many different test cases? intContestCaseMax = 4 ; How many loops to run? intContestLoopMax = 1000 ; What group of contestants to examine? intContestantMin = 1 intContestantMax = 3 ; Display preview of test case results? blnDisplayPreview = @TRUE ;blnDisplayPreview = @FALSE ; Display contest status in windows title? blnDisplayStatus = @TRUE ;blnDisplayStatus = @FALSE GoSub DEFINE_CONTEST_FUNCTIONS ;========================================================================================================================================== GoSub DEFINE_FUNCTIONS ; Run the contest once and display the results for verifying. ; Then press CANCEL to abort or OK to run complete contest. If blnDisplayPreview For intContestCase = 1 To intContestCaseMax udsPrepareTestCase (intContestCase) udsPrepareCounters () For intContestant = intContestantMin To intContestantMax udsRunContestant (intContestant) Next If @CANCEL == udfArrayDumpToItemList (arrContestResults, intContestantMin, intContestantMax, @LF) Then Goto CANCEL Next EndIf ; Run complete contest. WinShow ("") strContestResult = "" Switch blnDisplayStatus Case @TRUE For intContestCase = 1 To intContestCaseMax udsPrepareTestCase (intContestCase) udsPrepareCounters () For intContestLoop = 1 To intContestLoopMax For intContestant = intContestantMin To intContestantMax WinTitle ("", "Profiling|Case=" : intContestCaseMax : "." : intContestCase : "|Contestant=" : intContestantMax : "." : intContestant : "|Loop=" : intContestLoopMax : "." : intContestLoop) udsRunContestant (intContestant) Next Next strContestResult = strContestResult : @LF : udsResultPerTestCase () Next Break Case @FALSE For intContestCase = 1 To intContestCaseMax udsPrepareTestCase (intContestCase) udsPrepareCounters () For intContestLoop = 1 To intContestLoopMax For intContestant = intContestantMin To intContestantMax udsRunContestant (intContestant) Next Next strContestResult = strContestResult : @LF : udsResultPerTestCase () Next Break EndSwitch strContestResult = strContestResult : @LF : strPre : StrFill ("-", intLenSum) strContestResult = StrSub (strContestResult, 2, -1) Message (strMsgTitle, strContestResult) ClipPut (StrReplace (strContestResult, @LF, @CRLF)) :CANCEL Exit ;========================================================================================================================================== ;========================================================================================================================================== :DEFINE_CONTEST_FUNCTIONS ;========================================================================================================================================== ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineSubRoutine udsPrepareTestCase (intContestCase) Switch intContestCase Case 1 strLine = "as de 123dek / ab16 fb Xjdheeh BVP 34319 21489" Break Case 2 strLine = "kfj jo200 / hb47 fb32 Xjwjw BVP 51123 81000" Break Case 3 strLine = "ke kl5 / jh23 fb1 Xokeksmdd BVP 21000 21000" Break Case 4 strLine = "5 5 5 e krk / uy56 fb44 Xssd BVP 21000 21000" Break EndSwitch #EndSubRoutine ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineSubRoutine udsRunContestant (intContestant) Exclusive (@ON) Switch intContestant Case 1 arrContestants[intContestant] = "udfStringExtract_1" intStart = GetTickCount () arrContestResults[intContestant] = udfStringExtract_1 (strLine) intStop = GetTickCount () arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart Break Case 2 arrContestants[intContestant] = "udfStringExtract_2" intStart = GetTickCount () arrContestResults[intContestant] = udfStringExtract_2 (strLine) intStop = GetTickCount () arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart Break Case 3 arrContestants[intContestant] = "udfStringExtract_3" intStart = GetTickCount () arrContestResults[intContestant] = udfStringExtract_3 (strLine) intStop = GetTickCount () arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart Break EndSwitch Exclusive (@OFF) #EndSubRoutine ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStringExtract_1 (strLine) intItemPos = StrIndex (strLine, " BVP ", 1, @FWDSCAN) intSpacePos = StrIndex (strLine, " ", intItemPos - 1, @BACKSCAN) Return StrSub (strLine, intSpacePos + 1, intItemPos - intSpacePos) #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStringExtract_2 (strLine) Return ItemExtract (-1, ItemRemove (-1, StrReplace (strLine, " BVP ", @TAB), @TAB), " ") #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStringExtract_3 (strLine) Return ItemExtract (-1, StrSub (strLine, 1, StrLen (strLine) - 16), " ") #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;========================================================================================================================================== Return ; from GoSub DEFINE_CONTEST_FUNCTIONS ;========================================================================================================================================== ;========================================================================================================================================== :DEFINE_FUNCTIONS ;========================================================================================================================================== ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfArrayDumpToItemList (arrArray, intFirst, intLast, strDelimiter) If !ArrInfo (arrArray, -1) Then Return "*ARRAY_IS_INVALID*" ; No Array, return invalid itemlist, i. e. empty string "". If ArrInfo (arrArray, 0) != 1 Then Return "*ARRAY_IS_NOT_DIM_1*" ; Array is not a dim-1 array, return invalid itemlist, i. e. empty string "". intElements = ArrInfo (arrArray, 1) If intElements == 0 Then Return "*ARRAY_HAS_NO_ELEMENTS*" ; Array has no element. intFirst = Min (Max (intFirst, 0), intElements - 1) intLast = Min (Max (intLast, 0), intElements - 1) strItemList = "" intFixSize = StrLen (intLast) For intI = intFirst To intLast If !!VarType (arrArray [intI]) If arrArray [intI] == "" strItemList = ItemInsert (StrFixLeft (intI, "0", intFixSize) : "|" : "*ARRAY_ELEMENT_IS_EMPTY_STRING*", -1, strItemList, strDelimiter) Else arrArray [intI] = StrReplace (StrReplace (StrReplace (StrReplace (arrArray [intI], @CRLF, "@CRLF"), @CR, "@CR"), @LF, "@LF"), @TAB, "@TAB") ; Make WB style. arrArray [intI] = StrSub (arrArray [intI], 1, 200) ; Special truncation just for the small buffer of AskItemList. strItemList = ItemInsert (StrFixLeft (intI, "0", intFixSize) : "|" : arrArray [intI], -1, strItemList, strDelimiter) EndIf Else strItemList = ItemInsert (StrFixLeft (intI, "0", intFixSize) : "|" : "*ARRAY_ELEMENT_IS_UNDEFINED*", -1, strItemList, strDelimiter) EndIf Next IntControl (28, 1, 0, 0, 0) IntControl (63, 050, 200, 950, 800) Return AskItemlist ("Profiling|Preview Contestant Result", strItemList, strDelimiter, @UNSORTED, @SINGLE) ; This returns a Unicode string of VarType=128. :CANCEL Return @CANCEL ;.......................................................................................................................................... ; This UDF "udfArrayDumpToItemList" reads a dim-1 array and returns an itemlist of all array cell items within an AskItemList dialog.. ; ; Return values: ; "*ARRAY_IS_INVALID*" ... Invalid array resp. this is no array. ; "*ARRAY_IS_NOT_DIM_1*" ... Array is not a dim-1 array. ; "*ARRAY_HAS_NO_ELEMENTS*" ... Array has no element. ; "*ARRAY_ELEMENT_IS_EMPTY_STRING*" ... Array element has vartype STRING but is empty. ; "*ARRAY_ELEMENT_IS UNDEFINED*" ... Array element has undefined VarType. ; value ... Current value of the array element. ; ; Example: strItemList = udfArrayDumpToItemList (arrArray, 0, 19, @TAB) ; ; Detlev Dalitz.20090515.20100122.20101222. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineSubRoutine udsPrepareCounters () arrContestants = ArrDimension (1 + intContestantMax) ; Array index 0 not used. arrContestResults = ArrDimension (1 + intContestantMax) ; Array index 0 not used. arrContestTicks = ArrDimension (1 + intContestantMax) ; Array index 0 used for the sum. arrContestPct = ArrDimension (1 + intContestantMax) ; Array index 0 not used. ArrInitialize (arrContestants, "") ArrInitialize (arrContestResults, "") ArrInitialize (arrContestTicks, 0) ArrInitialize (arrContestPct, 0.0) #EndSubRoutine ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineSubRoutine udsResultPerTestCase () Decimals (1) For intContestant = intContestantMin To intContestantMax arrContestTicks[0] = arrContestTicks[0] + arrContestTicks[intContestant] Next intContestTicksMin = arrContestTicks[0] For intContestant = intContestantMin To intContestantMax intContestTicksMin = Min (intContestTicksMin, arrContestTicks[intContestant]) Next If arrContestTicks[0] < 1 Then arrContestTicks[0] = 1 ; To prevent dividing by zero. For intContestant = intContestantMin To intContestantMax arrContestPct[intContestant] = 100.0 * arrContestTicks[intContestant] / arrContestTicks[0] Next ; Format output. strMsgTitle = "Performance Contest Result" strTest = "Test" strTicks = "Ticks" strPct = "Pct" strContestant = "Contestant" strCase = "Contest Case = " strIter = "Iterations = " strSep = " " strPre = "; " strWinner = "<== The Winner" strDT = "DateTime = " intLenTest = Max (StrLen (strTest), StrLen (intContestantMax)) intLenTicks = StrLen (strTicks) intLenPct = StrLen (strPct) intLenContestant = StrLen (strContestant) intLenSep = StrLen (strSep) intLenWinner = StrLen (strWinner) For intContestant = intContestantMin To intContestantMax intLenTicks = Max (intLenTicks, StrLen (arrContestTicks[intContestant])) intLenPct = Max (intLenPct, StrLen (arrContestPct[intContestant])) intLenContestant = Max (intLenContestant, StrLen (arrContestants[intContestant])) Next intLenSum = intLenTest + intLenTicks + intLenPct + intLenContestant + intLenWinner + 4 * intLenSep strTest = StrFixLeft (strTest, " ", intLenTest) strTicks = StrFixLeft (strTicks, " ", intLenTicks) strPct = StrFixLeft (strPct, " ", intLenPct) strResult = strPre : StrFill ("-", intLenSum) : @LF : strPre : strMsgTitle strResult = strResult : @LF : strPre : strCase : intContestCase strResult = strResult : @LF : strPre : strIter : intContestLoopMax strResult = strResult : @LF : strPre : strTest : strSep : strTicks : strSep : strPct : strSep : strContestant For intContestant = intContestantMin To intContestantMax strTest = StrFixLeft (intContestant, " ", intLenTest) strTicks = StrFixLeft (arrContestTicks[intContestant], " ", intLenTicks) strPct = StrFixLeft (arrContestPct[intContestant], " ", intLenPct) strContestant = StrFix (arrContestants[intContestant], " ", intLenContestant) If arrContestTicks[intContestant] == intContestTicksMin Then strContestant = strContestant : strSep : strWinner strResult = strResult : @LF : strPre : strTest : strSep : strTicks : strSep : strPct : strSep : strContestant Next Return strResult : @LF : strPre : strDT : TimeYmdHms () #EndSubRoutine ;------------------------------------------------------------------------------------------------------------------------------------------ ;========================================================================================================================================== Return ; from GoSub DEFINE_FUNCTIONS ;========================================================================================================================================== ; ----------------------------------------------------- ; Performance Contest Result ; Contest Case = 1 ; Iterations = 10000 ; Test Ticks Pct Contestant ; 1 7473 44.5 udfStringExtract_1 ; 2 4783 28.5 udfStringExtract_2 ; 3 4523 27.0 udfStringExtract_3 <== The Winner ; DateTime = 2011:01:06:09:06:14 ; ----------------------------------------------------- ; Performance Contest Result ; Contest Case = 2 ; Iterations = 10000 ; Test Ticks Pct Contestant ; 1 10346 42.9 udfStringExtract_1 ; 2 7143 29.6 udfStringExtract_2 ; 3 6629 27.5 udfStringExtract_3 <== The Winner ; DateTime = 2011:01:06:09:07:24 ; ----------------------------------------------------- ; Performance Contest Result ; Contest Case = 3 ; Iterations = 10000 ; Test Ticks Pct Contestant ; 1 16167 44.8 udfStringExtract_1 ; 2 10445 29.0 udfStringExtract_2 ; 3 9452 26.2 udfStringExtract_3 <== The Winner ; DateTime = 2011:01:06:09:09:11 ; ----------------------------------------------------- ; Performance Contest Result ; Contest Case = 4 ; Iterations = 10000 ; Test Ticks Pct Contestant ; 1 17907 42.1 udfStringExtract_1 ; 2 12819 30.1 udfStringExtract_2 ; 3 11805 27.8 udfStringExtract_3 <== The Winner ; DateTime = 2011:01:06:09:11:17 ; -----------------------------------------------------