Thank you for your reply!
@Tom wrote:
Adding the format to the PUT statement will allow the data step to make a better guess about how to define MEMNAME. But that will not solve the issue that MEMNAME has not yet gotten a value at that point in the data step.
The problem is that the PUT statement that uses MEMNAME is BEFORE the SET statement. So the data step compiler guesses that you wanted MEMNAME as numeric, and then when the first SET statement runs there is a conflict.
For that particular data step the solution would be to make sure the SET statement is before the PUT statement. Not only will that fix the type conflict it will also mean that MEMNAME actually has a value that can be written by the PUT statement.
You could add another SET statement at the top of the step before the first PUT. But then the data step would iterate once for each observation in the dataset, writing multiple copies of the data step to the output file. To fix that you could add a STOP statement to the end of the data step so that it stops after the first iteration. Or you could add an OBS=1 dataset option to the SET statement. In that case the data step would stop at the top of the second iteration when it tries to read a second observation from an input that only had one observation. That is how normal data step stop.
Yes, one of the key measures I took to tackle the problem was adding a SET statement after the "data _null_" statement. This informs SAS of where the variable MEMNAME comes from as well as its characteristics like its length and type. I forgot to say that in yesterday's response but that modification is present in the code. In addition, in an attempt to simplify the code conducted today, I found that the format for MEMNAME can actually be removed once the SET statement is added.
@Tom wrote:
Programming hint: Note you could also use a FILEREF in the generated code. In that case the logic to generate the code would not need to change for a different input file. Instead just make sure to define the fileref before running the generated code.
...
* Write data statement and INFILE statement ;
set metadata (obs=1);
put 'data ' memname '(label=' memlabel :$quote. ');'
' infile csv dsd truncover firstobs=2;'
;
...
/*Replace the address of the CSV with a real one */
filename csv 'myfile.csv';
%include code / source2;
Thank you for pointing out a way to further simplify the code! Adding yet another FILENAME statement renders a more handy code that can be more easily compiled into a macro. This is very useful.
... View more