As of December 1, 2020, Focal Point is retired and repurposed as a reference repository. We value the wealth of knowledge that's been shared here over the years. You'll continue to have access to this treasure trove of knowledge, for search purposes only.
Join the TIBCO Community TIBCO Community is a collaborative space for users to share knowledge and support one another in making the best use of TIBCO products and services. There are several TIBCO WebFOCUS resources in the community.
From the Home page, select Predict: WebFOCUS to view articles, questions, and trending articles.
Select Products from the top navigation bar, scroll, and then select the TIBCO WebFOCUS product page to view product overview, articles, and discussions.
Request access to the private WebFOCUS User Group (login required) to network with fellow members.
Former myibi community members should have received an email on 8/3/22 to activate their user accounts to join the community. Check your Spam folder for the email. Please get in touch with us at community@tibco.com for further assistance. Reference the community FAQ to learn more about the community.
I have a manufacturing scenario where I have an alpha serial number and a part count. The serial number indicates the starting serial number, and the part count indicates the number of parts produced starting from that known serial. The intention is to create a single record for each serial number so that they can be flagged when defective for future clustering and yield analysis. I can use the MacGyver technique to generate a line per unique part produced, however, what I really need is an easy way to increment the serial numbers for each part.
There are 2 types of serial numbers:
AANANAN - e.g. MN7A9B6 an increment would be then MN7A9B7, and an increment for MN7A9B9 would be MN7A9C0 ANNNNNNNN - e.g. A00012340 an increment would be A00012341
Any thoughts on an easy way to do this?This message has been edited. Last edited by: dhagen,
"There is no limit to what you can achieve ... if you don’t care who gets the credit." Roger Abbott
Don't bother. I couldn't imagine doing a define function that didn't contain a mountain of code ... hence the posting. I just finished testing the FUSE routine on my local system. I'm happy with the results, and it took < 1 hour to do, so that was a lot less time than I initially expected. All I need to do now is compile and deploy on the customer site.
Thanks anyway.
"There is no limit to what you can achieve ... if you don’t care who gets the credit." Roger Abbott
Yes. Stands for Focus User Written Subroutine. Write it in C, then compile it to a .dll, then copy it to the server /user directory and then you can use it like any subroutine.
Can you post the source code, just in case someone needs to do something similar ?
I'm also interested in how you did it.
Here you go:
/*
* GETNEXTSNBR.C - Fuse routine to increment Polycon serial numbers by 1. Serial numbers can be of
* multiple formats, and are always a combination of letters and numbers.
*
* Known formats are: AA9A9A9 - e.g. MN1A8C9
* A99999999 - e.g. A00213456
*
* Created on: 2011-11-08
* Author: d hagen
*/
#include <string.h>
static const char CURR_CHAR[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const char NEXT_CHAR[] = "1234567890BCDEFGHIJKLMNOPQRSTUVWXYZA";
static const int CHAR_COUNT = 36;
/**
* Check if character to be processed is actually a valid character.
* 1 = Valid, 0 = Invalid
*/
int isValid ( char _in )
{
int i, irtn = 0;
for ( i = 0; i < CHAR_COUNT; i++ ) {
if (_in == CURR_CHAR[i]) {
irtn = 1;
break;
}
}
return irtn;
}
/**
* Change the passed character.
* The new value will be the same index position in the NEXT_CHAR array.
*/
char changeValue ( char _in )
{
int i;
char rtn = _in;
for ( i = 0; i < CHAR_COUNT; i++ ) {
if (_in == CURR_CHAR[i]) {
rtn = NEXT_CHAR[i];
break;
}
}
return rtn;
}
/**
* Function to increment the serial number one digit at a time.
*/
void getnextsnbr ( char *, char * );
void getnextsnbr ( char *inChar, char *outChar )
{
int i, rollover = 1;
unsigned char p[ strlen(inChar) ];
/* copy the inbound */
for( i = 0; i < strlen(inChar); i++ ){
p[i] = inChar[i];
}
/* Loop in reverse to increment a value. If the resulting value is either 0 or A, then
* tag the loop as a roll over and allowing the digit to the left to be incremented as well */
for ( i = strlen(inChar)-1; i >= 0; i-- ) {
if ( isValid( p[i] ) && rollover ) {
p[i] = changeValue( p[i] );
if ( p[i] == 'A' || p[i] == '0' )
rollover = 1;
else
rollover = 0;
}
}
/* Write the value to the output for WF or iDM to use */
for( i = 0; i < strlen(p); i++ ){
outChar[i] = p[i];
}
}
"There is no limit to what you can achieve ... if you don’t care who gets the credit." Roger Abbott
I couldn't imagine doing a define function that didn't contain a mountain of code
You were sooo right about that. I had to use some Dialogue Manager to help with the dirty and repetitive work and came up with a function that attempts to do that serial # increment you needed.
I'm sure your C-based solution is much more efficient than the WebFOCUS-based one below but the challenge was too tempting to resist
-*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* Set &CHARSYS to 'ASCII' or 'EBCDIC' as needed
-* EBCDIC support has not been tested !!!
-SET &CHARSYS = 'ASCII';
-SET &CHR_0 = IF &CHARSYS EQ 'ASCII' THEN 48 ELSE 240;
-SET &CHR_9 = IF &CHARSYS EQ 'ASCII' THEN 57 ELSE 249;
-SET &CHR_A = IF &CHARSYS EQ 'ASCII' THEN 65 ELSE 193;
-SET &CHR_Z = IF &CHARSYS EQ 'ASCII' THEN 90 ELSE 233;
-*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DEFINE FUNCTION SERINCR (SERIALNO/A20)
SERLEN/I4 = ARGLEN(20, SERIALNO, SERLEN);
RESULT/A20 = REVERSE(SERLEN, SERIALNO, RESULT);
INCRNX/A1 = 'Y';
-REPEAT :INCRSER FOR &I FROM 1 TO 20;
SERCHR/A1 = SUBSTR(20, RESULT, &I, &I, 1, SERCHR);
SERDEC/I3 = BYTVAL(SERCHR, SERDEC);
SERNXDEC/I3 = IF INCRNX NE 'Y' THEN SERDEC ELSE
IF NOT (SERDEC FROM &CHR_0 TO &CHR_9 OR SERDEC FROM &CHR_A TO &CHR_Z) THEN SERDEC ELSE
IF SERDEC EQ &CHR_9 THEN &CHR_0 ELSE
IF SERDEC EQ &CHR_Z THEN &CHR_A ELSE (SERDEC + 1);
SERNXCHR/A1 = CTRAN(1, SERCHR, SERDEC, SERNXDEC, SERNXCHR);
RESULT/A20 = OVRLAY(RESULT, 20, SERNXCHR, 1, &I, RESULT);
INCRNX/A1 = IF INCRNX EQ 'Y' AND (SERDEC EQ &CHR_9 OR &CHR_Z) THEN 'Y' ELSE 'N';
-:INCRSER
SERINCR/A20 = REVERSE(SERLEN, RESULT, SERINCR);
END
-*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TABLE FILE CAR
PRINT CAR
COMPUTE SERIAL/A20 = IF EDIT(CAR, '9') EQ 'J' THEN 'MN1A8C9' ELSE
IF EDIT(CAR, '9') EQ 'A' THEN 'A00213456' ELSE
IF EDIT(CAR, '9') EQ 'P' THEN 'MZZZZZZ' ELSE
IF EDIT(CAR, '9') EQ 'T' THEN 'MN7A9B6' ELSE
IF EDIT(CAR, '9') EQ 'D' THEN 'A00012340' ELSE 'A99999999';
COMPUTE NEXTSERIAL/A20 = SERINCR (SERIAL);
END
I cheated a bit as your C routine gave me a few ideas and this post from Francis gave me the expression I needed to make character conversions.
This was not fully tested (particularly EBCDIC support) but as I said, was just an interesting exercise.This message has been edited. Last edited by: njsden,