3

Is the function System.String:Format is limited to 3 input?

When I do:

DISPLAY System.String:Format("~{0~} ~{1~} ~{2~}", 0, 1, 2).

Everything is fine.

But when I do:

DISPLAY System.String:Format("~{0~} ~{1~} ~{2~} ~{3~}", 0, 1, 2, 3).

I get a compile error:

Impossible to find a method 'Format' with a compatible signature  from class 'System.String'. (14457)

I found a workaround that looks like:

System.String:Format("~{0~} ~{1~} ~{2~}", 0, 1, System.String:Format("~{0~} ~{1~} ~{2~}", 2, 3, System.String:Format("~{0~} ~{1~} ~{2~}", 4, 5, 6))).

But I do not found it elegant.

Thank you! Sebastien

UPDATE:

Here an example where format is used to format the datetime, leading zero and round decimal.

/* constants */
DEFINE VARIABLE MSG_WELCOME AS CHARACTER NO-UNDO INITIAL "Hello user  ~{0~:d6}, your balance account is ~{1~:n2} in date of ~{2~:yyyy-MM-dd}.".

/* declaration */
DEFINE VARIABLE iUserId AS INTEGER NO-UNDO.
DEFINE VARIABLE dtTransaction AS DATETIME NO-UNDO.
DEFINE VARIABLE dBalance AS DECIMAL NO-UNDO.
DEFINE VARIABLE strMessage AS CHARACTER NO-UNDO.

/* initialization */
iUserId = 106.
dtTransaction = DATETIME(10, 31, 2014, 11, 22, 33).
dBalance = 1234.56789.
strMessage = System.String:Format(MSG_WELCOME, iUserId, dBalance, dtTransaction).

/* output */
MESSAGE strMessage VIEW-AS ALERT-BOX INFO BUTTONS OK.

OUTPUT: Hello user 000106, your balance account is 1234,57 in date of 2014-10-31.

Tom Sawyer
  • 835
  • 2
  • 10
  • 32
  • What is it that you want to accomplish? If I'm not mistaken System.String:Format is a .net method. There might be a way to do what you want by simply using ABL? – Jensd Mar 17 '14 at 14:22
  • I added an example in the post. In ONE of our case, we use String:Format to generate output for EDI file. So we need 8 or 9 parameters to have a complete transaction in a specific format. – Tom Sawyer Mar 17 '14 at 16:36
  • Take a look at the SUBSTITUTE function! – Jensd Mar 17 '14 at 16:41

2 Answers2

3

By looking at the available overloads of System.String.Format this becomes less mysterious:

public static string Format(string format, object arg0);
public static string Format(string format, params object[] args);
public static string Format(IFormatProvider provider, string format, params object[] args);
public static string Format(string format, object arg0, object arg1);
public static string Format(string format, object arg0, object arg1, object arg2);

By adding the fact that OpenEdge does not support .Net vararg parameters (defined with the params keyword), it becomes clear. Your first example is using the last listed version with 3 object parameters, your second example does not work because there is no overload with 5 parameters.

But it's not impossible to use vararg parameters from OpenEdge. If we look at autocompletion from PDSOE, we see that all 5 signatures are there and that the params keyword is simply ignored. That means you could use the highlighted version with unlimited parameters, but you need to pass an array of type System.Object to it.

enter image description here

This is an example of how it could be done:

DEF VAR v-list AS System.Collections.ArrayList NO-UNDO.

v-list = new System.Collections.ArrayList().

v-list:Add(106).
v-list:Add(DATETIME(10, 31, 2014, 11, 22, 33)).
v-list:Add(1234.56789).
v-list:Add("moo").

MESSAGE System.String:Format("~{0~} ~{1~} ~{2~} ~{3~}", v-list:ToArray())
VIEW-AS ALERT-BOX.
Fabian Frank
  • 495
  • 4
  • 9
1

SUBSTITUTE() can be used to replace up to 9 variables with values. The function is somewhat similar to that of sprintf in C. The (perhaps bad) side effect is that the formatting isn't in the string itself but in the function call.

Example:

DEFINE VARIABLE MSG_WELCOME AS CHARACTER NO-UNDO INITIAL "Hello user  &1, your balance account is &2 in date of &3.".

DEFINE VARIABLE iUserId AS INTEGER NO-UNDO.
DEFINE VARIABLE dtTransaction AS DATETIME NO-UNDO.
DEFINE VARIABLE dBalance AS DECIMAL NO-UNDO.
DEFINE VARIABLE strMessage AS CHARACTER NO-UNDO.

iUserId = 106.
dtTransaction = DATETIME(10, 31, 2014, 11, 22, 33).
dBalance = 1234.56789.

strMessage = SUBSTITUTE( MSG_WELCOME, STRING(iUserId, "999999"), STRING(dBalance,">>>,>>>.99"), STRING(dtTransaction,"9999-99-99")).

MESSAGE strMessage VIEW-AS ALERT-BOX.
Jensd
  • 7,886
  • 2
  • 28
  • 37
  • Thank you Jensd! Curiosity, how is it possible to manage the date format when 99 is for the day and also for the month? Example of a transaction: yyyyMMddXXXXXX9999999999 where the result would be 201410310001600000123457 (date + userid + balance), is it possible to control the disposition of the datepart and also the separator (dash, slash or none)? Thank you! – Tom Sawyer Mar 17 '14 at 17:39
  • That's controlled by your sessions date format. If you set SESSION:DATE-FORMAT = "ymd" that will force the specific order you mentioned. Could also be controlled by the -d startup parameter. – Jensd Mar 17 '14 at 18:01
  • As for dashes and slashes in the date you can do that by using different format strings, "9999/99/99", "9999-99-99", "99999999". – Jensd Mar 18 '14 at 07:10