Reputation: 6020
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.
Upvotes: 2
Views: 5348
Reputation: 7769
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
Upvotes: 4