web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :

A dynamic strFmt call

PA-22040759-0 Profile Picture PA-22040759-0 6,194
In the communities a users asked about a way to make a dynamic strFmt call, not knowing the number of parameters up front.

With some good critical tests from Levgen Miroshnikov (blog) I think I have managed to write a class method that does that.

Regular StrFmt will round decimal value and change the decimal point to whatever fits your windows locale. This method has a parameter allowing you to keep the formatting of decimal values.

Here is the code for it:
public str dynamicStrFmt(
str _expression,
container _args = conNull(),
boolean _keepRealsDecimals = false)
{
str ret;
Counter counter;
str argStr;
char argChar;

if (_args == conNull())
{
return strFmt(_expression);
}

for (counter = 1; counter <= strLen(_expression); counter++)
{
if (subStr(_expression, counter, 1) != '%')
{
ret += subStr(_expression, counter, 1);
}
else
{
// This is a point in the string where an argument starts
// Find the end of the argument
argStr = '';
argChar = subStr(_expression, counter + 1, 1);
while (argChar && argChar == strKeep(argChar, '0123456789'))
{
argStr += argChar;
argChar = subStr(_expression, counter + strLen(argStr) + 1, 1);
}

// Lookup and insert the value to the result
if (argStr)
{
// Check that the argument is within the bounds of the number of supplied argument values
if (str2Int(argStr) <= conLen(_args))
{
if (typeOf(conPeek(_args, str2Int(argStr))) == Types::Real && _keepRealsDecimals)
{
ret += num2str(conPeek(_args, str2Int(argStr)), -1, numOfDec(conPeek(_args, str2Int(argStr))), 1, 0);
}
else
{
ret += strFmt('%1', conPeek(_args, str2Int(argStr)));
}
}
else
{
// The argument is not within the bounds of the supplied argument values. Keep the argument unchanged.
ret += subStr(_expression, counter, 1) + argStr;
}
// Move the current position in the _expression string to a position after the argument
counter += strLen(argStr);
}
else
{
// Didn't find the argument to be meningfull, so just add the argument character as-is
ret += subStr(_expression, counter, 1);
}
}
}

return ret;
}

And a main method for a quick demo:
public static void main(Args _args)
{
aaaStrFmtBuilder demo = new aaaStrFmtBuilder();

info (demo.dynamicStrFmt("%1 + %1 = %2", [2, 4]));
info(demo.dynamicStrFmt("%1/(%2*%1)", [1000, 0.135], true));
info(demo.dynamicStrFmt("%2 %3 %1", ['AX', 'Microsoft', 'Dynamics']));
}

And here you can download a project with the class and unit tests for it:
 

The two classes are prefixed with 'aaa', making it easier for you to find them in the AOT :-)
Please change the names if you are going to use the code for something real.

Comments

*This post is locked for comments