A client asked me about something and I haven't been able to get the problem out of my mind. I have a solution-ish, but I'm hoping it can be better. Here's the issue:
The client uses Cabling to route hoses. For each hose he wants to report its length in a table. So far, so good. Problem is, he wants both the cut length (i.e. the length of raw hose to be cut when manufacturing) and the total length (i.e. the length between the sealing surfaces). You can use internal length to get one of those, but you can't have both.
Simple enough, I thought. Add a parameter to the connectors and make a repeat region relation summing the length with the parameters of the from and to connectors. Problem is, I can't access the parameters of the connector part, just the parameters of the component. I can give a parameter to the components, showing the length to add to get from cut length to total length, and I can retrieve that parameter, but...
User defined cabling parameters seem to always be strings. So trying to add that parameter (harn.run.from.conn.ADDLEN) to the cable length results in a blank column. Can't add a string to a real value.
I got around this using huge sets of if conditions, getting me a number from the string. So:
if firstdigit == "1"
Total = Total + 1*10^(numdigits-1)
if firstdigit == "2"
Total = Total + 2*10^(numdigits-1)
And so on for ages (I can post the entire relation if someone's interested). So now it works, though the ADDLEN parameter can only be three digits and no decimals, but the relation could be bloated even more to compensate, of course.
1. This means that the user still has to add the ADDLEN parameter to each connector every time. It's not saved with the part, since it's designated in Cabling. Does anyone know how to automate this? Can I do something in the part to automatically get this parameter each time it's designated? I know how to do this for entry port information, but I'm not sure if I can do it for parts.
2. Anyone has a more elegant method for converting a string to an integer or real? Since there are no loops in Creo relations, my relation is huge. I wonder if there's a better way?
I don't know about the first question, but you could convert the string to an integer using some of the string search and manipulation functions, like this:
intNumber = 0 numString = "0123456789" index = 1 position = string_length ( txtNumber )
charDigit = EXTRACT ( txtNumber, position, 1 ) intNumber = intNumber + 10^(index - 1) * ( SEARCH ( numString, charDigit ) - 1 ) IF position > 1 index = index + 1 position = position - 1 charDigit = EXTRACT ( txtNumber, position, 1 ) intNumber = intNumber + 10^(index - 1) * ( SEARCH ( numString, charDigit ) - 1 ) ENDIF /* Repeat the IF--THEN block above as many times as you think you'll need, one for each /* digit beyond the first.
Thanks! I stumbled upon that trick in an old thread. (https://community.ptc.com/t5/Part-Modeling/Extract-numbers-from-string-in-creo/td-p/270786/page/2)
It really is a neat trick! Much simpler than my original idea. So now my relation is a lot simpler. Still would like to auto-designate that parameter, though, so the user doesn't have to enter it each time.
Here's my complete relation now:
DIGITS = "0123456789" /* Collect parameters FROM = harn_run_from_conn_ADD TO = harn_run_to_conn_ADD TOTAL = harn_run_len /* Convert "FROM" string to number and add to TOTAL TOTAL = TOTAL+(SEARCH(DIGITS,EXTRACT(FROM,STRING_LENGTH(FROM)-0,1))-1)*1 if STRING_LENGTH(FROM) > 1 TOTAL = TOTAL+(SEARCH(DIGITS,EXTRACT(FROM,STRING_LENGTH(FROM)-1,1))-1)*10 endif if STRING_LENGTH(FROM) > 2 TOTAL = TOTAL+(SEARCH(DIGITS,EXTRACT(FROM,STRING_LENGTH(FROM)-2,1))-1)*100 endif /* Convert "TO" string to number and add to TOTAL TOTAL = TOTAL+(SEARCH(DIGITS,EXTRACT(TO,STRING_LENGTH(TO)-0,1))-1)*1 if STRING_LENGTH(TO) > 1 TOTAL = TOTAL+(SEARCH(DIGITS,EXTRACT(TO,STRING_LENGTH(TO)-1,1))-1)*10 endif if STRING_LENGTH(TO) > 2 TOTAL = TOTAL+(SEARCH(DIGITS,EXTRACT(TO,STRING_LENGTH(TO)-2,1))-1)*100 endif
Could probably use some extra safety code to print an error if the "ADD" parameter has decimals or is longer than three digits.
The relations I put up can be used to get as many digits as you think you'll ever need. You just copy the IF-ENDIF block as many times as you think will suffice. Notice I decrement the "position" for each block so, say, if you have four copies but the number is only 2 digits, it skips the last two IF-ENDIF blocks.
Checking for a decimal would complicate matters quite a bit. You'd have to look for it first, handle the digits after the decimal, then deal with the integer portion of the number. Lots of programming fun. Too bad relations don't have a looping construct. Or, more importantly, too bad relations don't have a proper set of functions to deal with string<==>number conversions.