Alphanumeric key incrementing routine
Creates next string key from the passed one using specified set of characters
$SAMPLECODE$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 * * Creates next string key from the passed one using specified set of characters * * Parameters * 1 - Current Key * 2 - Defines the list of allowed characters * BASEnn - See DO CASE in the body of the program * CUSTOM - the list of character as parameter 3 * 3 - List of characters * * Returns Next key * * Note 1 Routine ignores (doesn't change) positions with the characters not in the specified list * Note 2 When max possible value is reached, the next return value will be the min possible value * FUNCTION NextKey LPARAMETERS tcOldVal, tcOpt, tcCharList LOCAL lcNewVal, i, lcDigits, lcLetters, lnCharListLen, lcOldChar, lcNewChar, lcCharList, lnPos, lcOpt LOCAL lnNextPos lcOpt = IIF(EMPTY(tcOpt), "BASE10", UPPER(tcOpt)) * Get the list of appropriate characters lcCharList = NextKeyFillCharList(lcOpt, tcCharList) lnCharListLen = LEN(lcCharList) lcNewVal = tcOldVal * Scan string from the right to the left FOR i = LEN(lcNewVal) TO 1 STEP -1 lcOldChar = SUBSTR(tcOldVal, i, 1) * Is the current charater in the list? lnPos = AT(lcOldChar, lcCharList) IF lnPos = 0 * Not in the list, keep it LOOP ENDIF * Get the next character position lnNextPos = (lnPos % lnCharListLen) + 1 * Get the next character lcNewChar = SUBSTR(lcCharList,lnNextPos,1) * Stuff it back in the string lcNewVal = STUFF(lcNewVal, i, 1, lcNewChar) * Check if we have to carry over to the next position IF lnNextPos > 1 * We are done EXIT ENDIF ENDFOR RETURN lcNewVal *------------------------------------------------------------ * Fill the list of characters based on character set requested FUNCTION NextKeyFillCharList LPARAMETERS tcCharSet, tcCharList LOCAL lcCharList, lcDigits, lcLetters * Fill string 'lcCharList' with appropriate characters lcDigits = "0123456789" lcLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" DO CASE CASE tcCharSet = "CUSTOM" lcCharList = tcCharList CASE tcCharSet == "BASE10" * Just Digits lcCharList = lcDigits CASE tcCharSet == "BASE16L" * Hexadecimal in lower case lcCharList = lcDigits + "abcdef" CASE tcCharSet == "BASE16" * Hexadecimal in upper case lcCharList = lcDigits + "ABCDEF" CASE tcCharSet == "BASE26L" * Lower case letters lcCharList = LOWER(lcLetters) CASE tcCharSet == "BASE26" * Upper case letters lcCharList = lcLetters CASE tcCharSet == "BASE36L" * Digits + Lower case letters lcCharList = lcDigits + LOWER(lcLetters) CASE tcCharSet == "BASE36" * Digits + Upper case letters lcCharList = lcDigits + lcLetters CASE tcCharSet == "BASE52" * All letters lcCharList = lcLetters + LOWER(lcLetters) CASE tcCharSet == "BASE62" * Digits + All letters lcCharList = lcDigits + lcLetters + LOWER(lcLetters) OTHERWISE * The same as BASE10 lcCharList = lcDigits ENDCASE RETURN lcCharList
1 2 3 4 5 6 7 8 9 10 * Rollover to min value (Base10) ? NextKey("999999") && 000000 * Next value (Base16) ? NextKey("999999", "Base16") && 99999A * Dash ('-') has not been changed ? NextKey("999-FFF", "Base16") && 99A-000
Comments
Thank you for sharing, it´s