Search code examples
sassas-macroquoting

SAS: Quoting Problems


I am trying to generate a script from within SAS. Unfortunately, I need to write the line

strMSHTA = "mshta.exe ""about:<input type=file id=FILE>" _
      & "<script>FILE.click();new ActiveXObject('Scripting.FileSystemObject')" _
      & ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>"""

To write the script to file, I am using the following approach:

/* write the script to file */
filename outfile ".\temp.vbs";
data _null_;
  file outfile;
  put 'WScript.Echo "Hello, World!"';
run;

/* run the script */
data _null_;
  call system(".\temp.vbs");
run;

/* housekeeping */
%let rc=%sysfunc(fdelete(outfile));
%symdel rc;
filename outfile clear;

Unfortunately, the put statement doesn't take kindly to &, ', and ". I have tried all of the macro quoting functions, but cannot get anything to work. If necessary, I could use the overloaded concatenation operator + instead of &. Doing this leaves only an error with the middle line due to the single quotes on ActiveXObject('Scripting.FileSystemObject'). Any ideas?


Solution

  • Not sure I understand the problem. Using single quotes instead of double quotes on the outside of your literal strings will eliminate the need to worry about macro triggers like & or %, but you will still need to double up any literal single quote characters you need to generate.

    put 
     'strMSHTA = "mshta.exe ""about:<input type=file id=FILE>" _'
    /'      & "<script>FILE.click();new ActiveXObject(''Scripting.FileSystemObject'')" _'
    /'      & ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>"""'
    ;
    

    You could also break your strings literals into multiple string literals and use different outer quotes for each.

    put 
     'strMSHTA = "mshta.exe ""about:<input type=file id=FILE>" _'
    /'      & "<script>FILE.click();new ActiveXObject('
     "'Scripting.FileSystemObject'" 
     ')" _'
    /'      & ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>"""'
    ;