• Not Answered

Only numeric entry in NamedSet !?

Hello everybody,

I want to create a NamedSet with only numeric entry. The named set e.g. should look like: 123, 456, 789. DeltaV doesn't allow me to do this becaus it expects letters. When I enter 123A, 456A, 789A it works, but this is not possible for my Task, because i Need to write this numbers into a log file.

Any ideas to solve this? Thanks!

I also could read the named set entries character by character, but I don't know how to do this as well.

10 Replies

  • Hello,
    did you try 123"space"?
  • A Named Set entry requires that at least one character be an alpha character.  You should be getting an error dialog that has as part of its statement "and must include at least one alpha character."

    If you have to have the numbers in a log file you'll probably have to create the named set with a letter in each entry and then use an expression to look at the named set parameter value and pass the value to a string parameter that has the letter stripped out.  You could use the SELSTR expression referencing the .CVI field of the named set parameter such as

    '^/PARAM1.CV' := SELSTR('^/PARAMSET.CVI',"123","456","789")

    where PARAM1 is a string parameter and PARAMSET is a named set parameter where 0 is blank, 1 = "123A", 2 = "456A", 3 = "789A"

  • In reply to LostEngineer0:

    Thanks for your answer. Yes i already did but it doesn't work. I'll try the other one.
  • In reply to Scott Thompson:

    @

    First of all thank you for your answer. I did not work with SELSTR before and now I tried some different ways to use ist. But I still don't have a solution for my Problem.

    Now I can select "only number strings" by choosing a named set entry, but because of practical issues I need to have the numbers only in a named set. If I did get that right your answer requires to have this numbers also in the expression. The thing is that we have to change these numbers several times for several parts of our plant. With a named set this would be easy to do. But otherwise I had to change every module.

    Another Problem is that I can only work with 5 entrys in that SELSTR function, right!?
  • In reply to handia:

    The SELSTR function can be nested with the index decreased in each successive nest. However it might be easier to use multiple lines or if statements (or the inline if statement as shown below).

    '^/PARAM1.CV' := ('^/PARAMSET.CVI'<6)?SELSTR('^/PARAMSET.CVI',"111","222","333","444","555"):(('^/PARAMSET.CVI'<11)?SELSTR('^/PARAMSET.CVI'-6,"667","777","888","999","112"):SELSTR('^/PARAMSET.CVI'-11,"123","456","789","321","432")

    Another option to stick with the SELSTR function and make only one additional place to change the strings would be to have the strings that you want to log saved in parameters in a single module, then the SELSTR could reference those parameters. This line of code is only for one set of 5 SELSTR selections and the string parameters are local but they could be in another module.

    '^/OUT1.CV' := SELSTR('^/IN1.CV','^/DEV01.CV','^/DEV02.CV','^/DEV03.CV','^/DEV04.CV','^/DEV05.CV');

    You may also want to leave the string manipulation to a schedule in Operate. Control modules have extremely limited string manipulation capabilities limited to string concatenation only. Pushing the string work up to VBA inside of DeltaV Operate would give you the full suite of string manipulation functions in VBA. However, this does mean that you are dependent on Operate remaining in run mode on the workstation where you set the schedule to execute.
  • In reply to Scott Thompson:

    Handia, You've described your problem as requiring a Named Set to contain integers in the named States. Would you be able to describe your actual problem, the one that requires you to have numbers in the named set? Maybe an alternative solution might present itself if we consider the actual problem you are trying to solve.

    Andre Dicaire

  • In reply to Andre Dicaire:

    Hi Andre Dicaire, thanks for your interest in my problem. I will try to explain.

    Our Operators have to choose several products for their process. When they have choosen a product out of a list (namedset) there shall be an kind of autofill function that writes the corresponding product number (only numbers) in an overview table. So for that reason I tried to create a second namedset which has the product numbers inside. The idea was that if the second entry of the "product names namedset" is selected, the autofill function writes the second entry of the "product number namedset" into the table.

    Why do I want namedsets?? --> In an undefined time span the numbers have to be changed, so I want to change the numbers only in the lowest possible places in the software. The problem is, that the selective list is used by several modules. Thats why a namedset would be propably the easiest solution.


    For know I did a quick and dirty type of solution. But I'm not glad about this. I'll tell you if you don't have any further ideas.
  • In reply to handia:

    How about using a Floating Point Array. Define it to have the same number of rows, 1 column as the operator selection Named Set. Maybe the Named set state for 0 is not user selectable so you the Named Set and FP Array start at index 1. Put the numbers in the FP. For Named State 1, use FPArray[1][1]. You can use the Named state.CVI value to access the corresponding array value ( FPArray[1]['^/NS_PARMATER.CVI']).

    Andre Dicaire

  • Hi,

    System limitations cannot be overcome. You have to do a workaround in either way.

    You can use "Signal characterizer" block, as it gives direct relation between two numbers. The block would have to be kept in a composite & link this composite in all module instances it is used.
    Alternatively, you can replace this composite with a floating point array parameter & an ACT block to select the right array value.
    But both floating point array or SGCR block can end up in rounding errors, resulting in wrong string written.

    If you want the data in pure strings, then you can use SELSTR function in the composite (Since the code will be used in many instances, I guess a composite will be must).

    When you say, the product value is stored in a "Table"? where is exactly this table? in Excel or some other external SW (with "Autofill" Function)?
    In that case, you can even keep the named set to 123A, etc; & use functions in excel / table to remove the last character.

    Best Regards,
    Amod.

  • In reply to amodbobade:

    Is rounding error a concern for integers that are say smaller than 16 Bits? Since we are not doing any math on the numbers, are there any integer values from 0 to 65535 that the Floating point will have Rounding error for?
    I couldn't find a definitive answer on line for conversion error from Float to Integer.

    Anyway, since all the values represent integers, you could ROUND the number before storing it as an integer. a value of 250.9999 would ROUND to 251.

    '^/INT_VALUE' := ROUND('^/ARRAY_VALUE'[1]['^/NAMED_SET_PARAM.CVI']);

    In this example, I've created an array called "ARRAY_VALUE" and is a 1 X 10 array. the column index is always 1. The NAMED_SET_PARAM uses a named set with 11 states, where state 0 is not used. I round the value in the array and store in an integer parameter called INT_VALUE. If for some reason the Float value has a rounding error, the ROUND function will fix it and store the correct Integer.

    Make sure your Named Set does not use the named state for CVI = 0, as reading an array with index of 0 will create an expression error. If you use CVI =0 as a standby state, make sure your CALC expression does not attempt to read or Write to that Array value. Use an IF Then Else to only read the array if the index value is valid. Now you can manage the desired integer values in the array and update them as needed.

    Or, you can add a 1 to the CVI value and offset the integers in the array. So named state of 0 reads index 1 in array, named state 1 reads index 2 etc. Personnally, I would not use the named state of 0.
    '^/INT_VALUE' := ROUND('^/ARRAY_VALUE'[1]['^/NAMED_SET_PARAM.CVI' +1]);

    Andre Dicaire