Question

I have an issue with an unresolved macro variable in the following (part of a) macro:

DATA _NULL_;
  SET TempVarFormat END=Last;
  LENGTH FormatValues $10000;
  RETAIN FormatValues;
  IF &OnlyNumeric = 1 THEN
    FormatValues = CATX(" ",FormatValues,STRIP(LookUpValue)||
    " = "||CATQ("A",TRIM(LookupDescription)));
  ELSE
    FormatValues = CATX(" ",FormatValues,CATQ("A"
    ,LookUpValue)||" = "||CATQ("A"
    ,TRIM(LookupDescription)));
  Test = STRIP(FormatValues);
  PUT Test /* To test buildup of variable */;
  IF Last THEN CALL SYMPUT('FormatValuesM',STRIP(FormatValues));
  IF Last THEN CALL SYMPUT('DataCollectionFK',DataCollectionFK);
RUN;
/* Make format with PROC FORMAT*/
%IF &OnlyNumeric = 1 %THEN %DO;
  PROC FORMAT LIB=WORK;
  VALUE DC&DataCollectionFK.A&AttributeFK.Format &FormatValuesM;
  RUN;
%END;
%ELSE %IF &OnlyNumeric = 0 %THEN %DO;
  PROC FORMAT LIB=WORK;
  VALUE $DC&DataCollectionFK.A&AttributeFK.Format &FormatValuesM;
  RUN;
%END;

I get the following warning

Apparent symbolic reference FORMATVALUESM not resolved.

And if I look in the log &DataCollectionFK is resolved but &FormatValues is not.

PROC FORMAT LIB=WORK; VALUE DC170A570Format &FormatValuesM;

Could someone advice? It is driving me nuts.

I tested it also without the STRIP() function and replacing the CALL SYMPUT with PUT to see if the variable is assigned a value. This all works fine.

Log copy (as requested in comment)

4         +
      DATA _NULL_; SET TempVarFormat END=Last; LENGTH

5         + FormatValues $10000; RETAIN FormatValues; IF 1 = 1 THEN FormatValues = CATX(" 
",FormatValues,STRIP(LookUpValue)|| " = "||CATQ("A",TRIM(LookupDescription))); ELSE 
FormatValues = CATX(" ",FormatValues,CATQ("A" ,LookUpValue)||" = "||CATQ("A" ,TRIM
6         +(LookupDescription))); Test = STRIP(FormatValues); PUT Test ; IF Last THEN CALL 
SYMPUT('DataCollectionFK',DataCollectionFK); IF Last THEN CALL SYMPUT('FormatValuesM',Test); 
RUN;

NOTE: Numeric values have been converted to character values at the places given by: 
      (Line):(Column).
      6:107   
1 = "Ja"
1 = "Ja" 0 = "Nee"
NOTE: There were 2 observations read from the data set WORK.TEMPVARFORMAT.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

6         +
        PROC FORMAT LIB=WORK;  VALUE DC170A1483Format &FormatValuesM;  RUN;;

NOTE: Format DC170A1483FORMAT is already on the library.
NOTE: Format DC170A1483FORMAT has been output.
NOTE: PROCEDURE FORMAT used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

MPRINT LOG

MPRINT(CONSTRUCTVARIABLEFORMAT):   DATA TestDataSetFormat;
MPRINT(CONSTRUCTVARIABLEFORMAT):   SET TempVarFormat END=Last;
MPRINT(CONSTRUCTVARIABLEFORMAT):   LENGTH FormatValues $10000;
MPRINT(CONSTRUCTVARIABLEFORMAT):   RETAIN FormatValues;
MPRINT(CONSTRUCTVARIABLEFORMAT):   IF 1 = 1 THEN FormatValues = CATX(" 
",FormatValues,STRIP(LookUpValue)|| " = "||CATQ("A",TRIM(LookupDescription)));
MPRINT(CONSTRUCTVARIABLEFORMAT):   ELSE FormatValues = CATX(" ",FormatValues,CATQ("A" 
,LookUpValue)||" = "||CATQ("A" ,TRIM(LookupDescription)));
MPRINT(CONSTRUCTVARIABLEFORMAT):   Test = STRIP(FormatValues);
MPRINT(CONSTRUCTVARIABLEFORMAT):   PUT Test ;
MPRINT(CONSTRUCTVARIABLEFORMAT):   IF Last THEN CALL 
SYMPUT('DataCollectionFK',DataCollectionFK);
MPRINT(CONSTRUCTVARIABLEFORMAT):   IF Last THEN CALL SYMPUT('FormatValuesM',Test);
MPRINT(CONSTRUCTVARIABLEFORMAT):   RUN;
MPRINT(CONSTRUCTVARIABLEFORMAT):   PROC FORMAT LIB=WORK;
WARNING: Apparent symbolic reference FORMATVALUESM not resolved.
MPRINT(CONSTRUCTVARIABLEFORMAT):   VALUE DC170A1483Format &FormatValuesM;
MPRINT(CONSTRUCTVARIABLEFORMAT):   RUN;

EDIT with some more attemps: The problem lies in that the macro variable is not getting a value during the datastep, for some reason. Loading the macrovariable with an empty value before I run the macro, makes that the script does not give an error. But the variable is resolved as an empty variable.

removing the IF Last THEN parts, also does not alter the outcome.

Was it helpful?

Solution

Surely it'll be easier/simpler to use the cntlin= option of PROC FORMAT to pass in a dataset containing the relevant format name, start, end, label values...

A simple example...

/* Create dummy format data */
data formats ;
  fmtname = 'MYCHARFMT' ;
  type = 'C' ;
  do n1 = 'A','B','C','D','E' ;
    start = n1 ;
    label = repeat(n1,5) ;
    output ;
  end ;
  fmtname = 'MYNUMFMT' ;
  type = 'N' ;
  do n2 = 1 to 5 ;
    start = n2 ;
    label = repeat(strip(n2),5) ;
    output ;
  end ;
  drop n1 n2 ;
run ;

/* dummy data looks like this... */
 fmtname     type    start    label

MYCHARFMT     C        A      AAAAAA
MYCHARFMT     C        B      BBBBBB
MYCHARFMT     C        C      CCCCCC
MYCHARFMT     C        D      DDDDDD
MYCHARFMT     C        E      EEEEEE
MYNUMFMT      N        1      111111
MYNUMFMT      N        2      222222
MYNUMFMT      N        3      333333
MYNUMFMT      N        4      444444
MYNUMFMT      N        5      555555

/* Build formats from dataset */
proc format cntlin=formats library=work ; run ;

There are several other fields which can be defined in your format dataset to cater for low/high/missing values, ranges, etc.

See the SAS documentation > http://support.sas.com/documentation/cdl/en/proc/61895/HTML/default/viewer.htm#a002473464.htm

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top