Answered Need Reasoning For Below Output (code Attached)

Ashwani Mishra

New Member
Hello There,

Below code show 2 different output for input date. If I pass blank date to function and concatenate the output of funstion to another string, it returns ?. Where as if I simply concatenate 1 string with character "?" it shows the output. Can someone please explain the reason? thanks!

OS - Window 7, Above code checked in OE10.2B, 11.4

Code:
DEF VAR cal AS CHAR FORMAT "x(3)" EXTENT 12
INITIAL ["JAN", "FEB", "MAR", "APR", "MAY",
"JUN", "JUL", "AUG", "SEP", "OCT",
"NOV", "DEC"].
DEF VAR d-monddyyyy AS CHAR FORMAT "x(15)" NO-UNDO.
DEF VAR dtblank AS DATE INIT ?.
DEF VAR dt-date AS DATE INIT 08/21/2017.

FUNCTION NiceDate RETURNS CHARACTER
(ipDate AS DATE ) FORWARD.

d-monddyyyy = NiceDate(dtblank) .
MESSAGE "Date blnk: " + d-monddyyyy
    VIEW-AS ALERT-BOX.
MESSAGE "Date : " + "?"
    VIEW-AS ALERT-BOX.
d-monddyyyy = NiceDate(dt-date) .
MESSAGE "Date : " + d-monddyyyy
VIEW-AS ALERT-BOX.


FUNCTION NiceDate RETURNS CHARACTER
(ipDate AS DATE ):
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/

DEFINE VARIABLE chBetterDate AS CHARACTER NO-UNDO.

chBetterDate = cal[MONTH(ipdate)] + " "
             + string(DAY (ipDate), "99") + ","
             + string(YEAR(ipDate), " 9999").

RETURN chBetterDate.


END FUNCTION.
 

Osborne

Active Member
When you add the null value - ? not "?" - to a string it clears the whole string and you just get ?:
Code:
DEFINE VARIABLE vLogical AS LOGICAL INITIAL ? NO-UNDO.
DEFINE VARIABLE vText AS CHARACTER INITIAL "Some Text" NO-UNDO.

vText = vText + " " + STRING(vLogical).

MESSAGE "Text =" vText VIEW-AS ALERT-BOX.
I am not sure of the exact reason, but remember reading it is something to do with Progress using null to terminate a character string.
 

Ashwani Mishra

New Member
When you add the null value - ? not "?" - to a string it clears the whole string and you just get ?:
Code:
DEFINE VARIABLE vLogical AS LOGICAL INITIAL ? NO-UNDO.
DEFINE VARIABLE vText AS CHARACTER INITIAL "Some Text" NO-UNDO.

vText = vText + " " + STRING(vLogical).

MESSAGE "Text =" vText VIEW-AS ALERT-BOX.
I am not sure of the exact reason, but remember reading it is something to do with Progress using null to terminate a character string.

Thanks for your response. After your reply, I did search how progress deals with null value and found few KB articles. My problem was, I was getting few null values in temp table and while sending this values to HTML file after adding null to character strings, It was making whole HTML file blank i.e. ?. So now I have to put a check for all those fields and handle it before sending it HTML. Thanks again.
 

TomBascom

Curmudgeon
? <> "?"

The first is "the unknown value" -- aka null. The second is the question mark character. They are NOT the same.

Just like 0 <> "0".

When you say "I pass blank date" you probably mean that the value of the date that you are passing is null. (When you display an unknown date it shows as blank.)

When you concatenate strings if any part of the string is unknown the entire string becomes unknown. Because if you add something unknown to something that is known the result is unknown. It's infectious - or "viral" ;)

One simple way to avoid this is to use the SUBSTITUTE() function rather than concatenation. SUBSTITUTE() converts unknown values to the "?" character -- which is much friendlier than making the whole string ?. This you might code:

Code:
define variable monthList as character no-undo initial "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".
define variable d as date no-undo.

d = today.

display substitute( "&1 &2, &3", entry( month( d ), monthList ), string( day( d ), "99" ), string( year( d ), "9999" )) format "x(12)".

This will display the string "?, ? ?" rather than the unknown value if you have a null date. That avoids the problem of a viral unknown string.

Note: SUBSTITUTE() does do automatic type conversions but it converts its arguments to strings using EXPORT format -- so if you want formatting like "9999" for the year you need to wrap a STRING() call with a format spec around the argument.
 
Last edited:

Ashwani Mishra

New Member
? <> "?"

The first is "the unknown value" -- aka null. The second is the question mark character. They are NOT the same.

Just like 0 <> "0".

When you say "I pass blank date" you probably mean that the value of the date that you are passing is null. (When you display an unknown date it shows as blank.)

When you concatenate strings if any part of the string is unknown the entire string becomes unknown. Because if you add something unknown to something that is known the result is unknown. It's infectious - or "viral" ;)

One simple way to avoid this is to use the SUBSTITUTE() function rather than concatenation. SUBSTITUTE() converts unknown values to the "?" character -- which is much friendlier than making the whole string ?. This you might code:

Code:
define variable monthList as character no-undo initial "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".
define variable d as date no-undo.

d = today.

display substitute( "&1 &2, &3", entry( month( d ), monthList ), string( day( d ), "99" ), string( year( d ), "9999" )) format "x(12)".

This will display the string "?, ? ?" rather than the unknown value if you have a null date. That avoids the problem of a viral unknown string.

Note: SUBSTITUTE() does do automatic type conversions but it converts its arguments to strings using EXPORT format -- so if you want formatting like "9999" for the year you need to wrap a STRING() call with a format spec around the argument.

Thanks a ton Tom, This is such a great explanation. I was seeking a reason for it and you gave me proper solution :)
 
Top