Jedi SAS Tricks: The DATA to DATA Step Macro

41

I was answering questions about SAS in a forum the other day, and it struck me how much easier it is to help folks if they can provide a snippet of data to go along with their program when asking others to help troubleshoot. This makes it easy to run their code on your own SAS session so you can help pinpoint the problem more quickly. It's easy to share your code on a forum with a quick copy and paste, but it's not so easy to share data. Encodings, O/S platforms, etc. all make a difference, so often you can't just attach a dataset, even if the forum accepts attachments - it wouldn't be usable. So how can I turn a SAS DATA set into a DATA step? Why, write an DATA set to DATA step macro, of course!

I solved this problem for myself a long time ago by writing a macro that takes a SAS data set and creates a DATA step which uses DATALINES to reproduce the data using code. I can then share the the code that produces the input data set as part of the program when I ask for help. I put this macro program in my SAS AUTOCALL path so it's always available when I need it. The macro name is data2datastep, and like most of the macros I write for my own use, it is self-documenting. Calling the macro with !help as the value of the first parameter - like this: %data2datastep(!help) - will get you syntax help in the SAS log.

A little about how the macro works: after all of the parameter checking is complete, the macro uses some SQL to gather information about the data set and put that information into macro variables for later use. Here is the SQL query that gets a space delimited list of the variable names which we will use to produce values for the DATALINES portion of our DATA step:

select Name
      into :varlist separated by ' '
   from dictionary.columns
   where libname="&lib"
     and memname="&dsn"
;

And here is the second query that gets a space delimited list of the variable names concatenated with a ':' and required informat, which we will use on the DATA step INPUT statement to read the values in from the DATALINES:

select case type
          when 'num' then 
             case 
                when missing(format) then cats(Name,':32.')
                else cats(Name,':',format)
             end 
          else cats(Name,':$',length,'.')
       end
      into :inputlist separated by ' '
   from dictionary.columns
   where libname="&lib"
     and memname="&dsn"
;

Finally I used a DATA _NULL_ step to write a DATA step. Sounds a little nefarious, doesn't it? :-) But it works nicely and the resulting DATA step program will produce a dataset which can be used for testing:

data _null_;
   file "&file" dsd;
   if _n_ =1 then do;
      put "data &lib..&dsn;";
      put @3 "infile datalines dsd truncover;";
      put @3 "input %superq(inputlist);";
      put "datalines4;";
   end;
   set &lib..&dsn(obs=&obs) end=last; 
   put &varlist @;
   if last then do;
      put;
      put ';;;;';
   end;
   else put;
run;

After the macro is compiled, %data2datastep(!help) produces this information in the SAS log:

NOTE: DATA2DATASTEP macro help document:
      Purpose: Converts a data set to a SAS DATA step.
      Syntax: %DATA2DATASTEP(dsn<,lib,file,obs>)
      dsn:  Name of the dataset to be converted. Required.
      lib:  LIBREF where the dataset resides. Optional.
      file: Filename for the DATA step produced. Optional.
            Default is create_&lib._&dsn._data.sas in the SAS default directory.
      obs:  Max observations to include the created dataset. Optional.
            Default is MAX (all observations)

NOTE:   DATA2DATASTEP cannot be used in-line - it generates code.
        Use !HELP to print these notes.

Now let's test that baby on some real data! I want to produce a DATA step that will create 5 rows of data from the SASHELP.CARS dataset. The macro call would be:

%data2datastep(cars,sashelp,,5)

The DATA step program is written to the file create_sashelp_CARS_data.sas. Here's what the code looks like:

data SASHELP.CARS;
  infile datalines dsd truncover;
  input Make:$13. Model:$40. Type:$8. Origin:$6. DriveTrain:$5. 
        MSRP:DOLLAR8. Invoice:DOLLAR8. EngineSize:32. Cylinders:32. 
        Horsepower:32. MPG_City:32. MPG_Highway:32. Weight:32.
        Wheelbase:32. Length:32.;
datalines4;
Acura,MDX,SUV,Asia,All,"$36,945","$33,337",3.5,6,265,17,23,4451,106,189
Acura,RSX Type S 2dr,Sedan,Asia,Front,"$23,820","$21,761",2,4,200,24,31,2778,101,172
Acura,TSX 4dr,Sedan,Asia,Front,"$26,990","$24,647",2.4,4,200,22,29,3230,105,183
Acura,TL 4dr,Sedan,Asia,Front,"$33,195","$30,299",3.2,6,270,20,28,3575,108,186
Acura,3.5 RL 4dr,Sedan,Asia,Front,"$43,755","$39,014",3.5,6,225,18,24,3880,115,197
;;;;

I can edit the code to change the LIBREF of the dataset to be produced to WORK. If there is sensitive information included, at this point I can easily anonymize it by editing the clear text values in the DATALINES portion of the DATA step. When I'm done editing, can test my code:

data WORK.CARS;
  infile datalines dsd truncover;
  input Make:$13. Model:$40. Type:$8. Origin:$6. DriveTrain:$5. 
        MSRP:DOLLAR8. Invoice:DOLLAR8. EngineSize:32. Cylinders:32. 
        Horsepower:32. MPG_City:32. MPG_Highway:32. Weight:32.
        Wheelbase:32. Length:32.;
datalines4;
Acura,MDX,SUV,Asia,All,"$36,945","$33,337",3.5,6,265,17,23,4451,106,189
Acura,RSX Type S 2dr,Sedan,Asia,Front,"$23,820","$21,761",2,4,200,24,31,2778,101,172
Acura,TSX 4dr,Sedan,Asia,Front,"$26,990","$24,647",2.4,4,200,22,29,3230,105,183
Acura,TL 4dr,Sedan,Asia,Front,"$33,195","$30,299",3.2,6,270,20,28,3575,108,186
Acura,3.5 RL 4dr,Sedan,Asia,Front,"$43,755","$39,014",3.5,6,225,18,24,3880,115,197
;;;;
title "&syslast";
proc print;
run;

The result looks good!
Dataset produced from code generated by the data2datastep macro

With the data2datasetp macro in my toolbox, I can easily post a little snip of data to go with my code whenever I'm asking for help in a forum.

As usual, you can download a zip file containing the complete SAS program and a copy of this article from the link below. Until next time, may the SAS be with you!
Mark

Link to the original macro program ZIP file: Jedi_SAS_Tricks_Data2DataStep.zip
Link to the latest update: Jedi_SAS_Tricks_Data2DataStepV2.zip

Share

About Author

SAS Jedi

Principal Technical Training Consultant

Mark Jordan (a.k.a. SAS Jedi) grew up in northeast Brazil as the son of Baptist missionaries. After 20 years as a US Navy submariner pursuing his passion for programming as a hobby, in 1994 he retired, turned his hobby into a dream job, and has been a SAS programmer ever since. Mark writes and teaches a broad spectrum of SAS programming classes, and his book, "Mastering the SAS® DS2 Procedure: Advanced Data Wrangling Techniques" is in its second edition. When he isn’t writing, teaching, or posting “Jedi SAS Tricks”, Mark enjoys playing with his grand and great-grandchildren, hanging out at the beach, and reading science fiction novels. His secret obsession is flying toys – kites, rockets, drones – and though he usually tries to convince Lori that they are for the grandkids, she isn't buying it. Mark lives in historic Williamsburg, VA with his wife, Lori, and Stella, their cat. To connect with Mark, check out his SAS Press Author page, follow him on Twitter @SASJedi or connect on Facebook or LinkedIn.

Related Posts

41 Comments

  1. Thanks for this. It would really help me out, if I can figure it out!

    I am trying to follow your comment to Taqeer from 2017. I am also new to SAS...I'm using SAS University Edition

    Done

    Done

    Done

    I don’t see instructions. Here’s the log:

    ——————————————————————————————————————————————
    1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
    68
    69 %data2datastep(!help)

    NOTE: DATA statement used (Total process time):
    real time 0.00 seconds
    user cpu time 0.00 seconds
    system cpu time 0.00 seconds
    memory 491.93k
    OS Memory 23712.00k
    Timestamp 01/13/2022 06:11:25 PM
    Step Count 34 Switch Count 0
    Page Faults 0
    Page Reclaims 75
    Page Swaps 0
    Voluntary Context Switches 0
    Involuntary Context Switches 0
    Block Input Operations 0
    Block Output Operations 0

    NOTE: DATA2DATASTEP macro help document:
    Purpose: Converts a data set to a SAS DATA step.
    Syntax: %DATA2DATASTEP(dsn)
    dsn: Name of the dataset to be converted. Required.
    lib: LIBREF of the original dataset. (Optional - if DSN is not fully qualified)
    outlib: LIBREF for the output dataset. (Optional - default is WORK)
    file: Fully qualified filename for the DATA step code produced. (Optional)
    Default is create_&outlib._&dsn._data.sas in the SAS default directory.
    obs: Max observations to include the created dataset.
    (Optional) Default is MAX (all observations)
    fmt: Format the numeric variables in the output dataset like the original data set?
    (YES|NO - Optional) Default is YES
    lbl: Reproduce column labels in the output dataset?
    (YES|NO - Optional) Default is YES

    NOTE: DATA2DATASTEP cannot be used in-line - it generates code.
    Every FORMAT in the original data must have a corresponding INFORMAT of the same name.
    Data set label is automatically re-created.
    Only numeric column formats can be re-created, character column formats are ingnored.
    Use !HELP to print these notes.
    70
    71 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
    81

    ——————————————————————————————————————————————
    Also, I’m using SAS University Edition, so what would be the correct path for the cars.sas data set?

    When I select Properties on the SASHELP folder, I see multiple paths.

    /pbr/sfw/sas/940/SASFoundation/9.4/nls/u8/sascfg
    /pbr/sfw/sas/940/SASFoundation/9.4/nls/u8/sashelp
    /pbr/sfw/sas/940/SASFoundation/9.4/nls/en/sascfg
    /pbr/sfw/sas/940/SASFoundation/9.4/sashelp

    Which one would I use instead of this: C:\temp\make_cars.sas

    Also, is "make_cars.sas" the name of the data set we are trying to create?

    Thank you very much!

    • Some of my statements were not included because I enclosed them in
      Here they are in quotes.

      "Download and unzip that macro program"
      Done

      "Open the program file (data2datastep.sas) in your SAS session and submit it just the way it is"
      Done

      "In a new Editor window, submit this code: %data2datastep(!help)"
      Done

      This will produce instructions in the SAS log on how to use the macro program to recreate a data set of your choice.

      I don’t see instructions. Here’s the log:

      • SAS Jedi

        It's been a LONG time since I made this post and this macro! The macro has been refined a bit over the years, and I'm made it a part of my published GitHub macro collection. Getting and using the macro from there is easier. So here are newer directions that, hopefully, will get you started more quickly and easily.
        1. Copy and submit this program in your SAS session:
        /* Get the macro soruce code */
        filename source "data2datastep.sas";
        proc http url="https://raw.githubusercontent.com/SASJedi/sas-macros/master/data2datastep.sas"
        out=source;
        quit;
        /* The data2datastep.sas file is now saved your SAS session default file location - you can view it if you want */
        /* Compile the macro */
        %include source;

        /* We no longer need the fileref for the source code */
        filename source clear;

        /* Get syntax help - run this code and look at the log */
        %data2datastep(?)

        2. Look in your SAS log. You should see output like this:
        NOTE: * DATA2DATASTEP help ************************************

        Purpose: Converts a data set to a SAS DATA step.
        Syntax: %DATA2DATASTEP(dsn)
        dsn: Name of the dataset to be converted. Required.
        lib: LIBREF of the original dataset. (Optional)
        outlib: LIBREF for the output dataset. (Optional)
        file: Fully qualified filename for DATA step code. (Optional)
        Default is create_&outlib._&dsn._data.sas
        in the SAS default directory.
        obs: Max observations to include the created dataset.
        (Optional) Default is MAX (all observations)
        fmt: Copy numeric variable formats?
        (YES|NO - Optional) Default is YES
        lbl: Copy column labels?
        (YES|NO - Optional) Default is YES

        NOTE: DATA2DATASTEP cannot be used in-line - it generates code.
        CAVEAT: Numeric FORMATS in the original data must have a
        corresponding INFORMAT of the same name.
        Character formats are ingnored.
        Data set label is automatically re-created.

        Use ? to print these notes.

        • Thanks for the response.

          When I run this:

          /* Get the macro soruce code */
          filename source "data2datastep.sas";
          proc http url="https://raw.githubusercontent.com/SASJedi/sas-macros/master/data2datastep.sas"
          out=source;
          quit;

          I get this:

          1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
          68
          69 /* Get the macro soruce code */
          70 filename source "data2datastep.sas";
          71 proc http url="https://raw.githubusercontent.com/SASJedi/sas-macros/master/data2datastep.sas"
          72 out=source;
          73 quit;

          ERROR: Insufficient authorization to access /pbr/biconfig/940/Lev1/SASApp/data2datastep.sas.
          ERROR: Insufficient authorization to access /pbr/biconfig/940/Lev1/SASApp/data2datastep.sas.
          NOTE: PROCEDURE HTTP used (Total process time):
          real time 0.26 seconds
          user cpu time 0.03 seconds
          system cpu time 0.00 seconds
          memory 1667.71k
          OS Memory 27296.00k
          Timestamp 01/14/2022 10:00:33 PM
          Step Count 36 Switch Count 3
          Page Faults 0
          Page Reclaims 374
          Page Swaps 0
          Voluntary Context Switches 16
          Involuntary Context Switches 0
          Block Input Operations 0
          Block Output Operations 0

          74
          75 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
          85

          • "ERROR: Insufficient authorization to access /pbr/biconfig/940/Lev1/SASApp/data2datastep.sas" means your SAS session "default path" points to a location where you don't have write access. Change the FILENAME statement to include path information pointing to somewhere you DO have write access. I no longer have a functional SAS University Edition image, as I moved to SAS On Demand for Academics when the University Edition was discontinued. (You can get it too at https://www.sas.com/en_us/software/on-demand-for-academics.html)

            In SAS On Demand for Academics, I also don't have write access to the default file location, so this FILENAME statement writes the file to my Linux home directory:
            FILENAME SOURCE "~/data2datastep.sas";

            You will need to adjust the path for your own SAS.

  2. Please do not post the last comment that I submitted. After further testing, it looks like I was mistaken about my first comment.

    Thank you!

    Todd

  3. HI,

    Sorry i had this error:

    ERROR: Physical file does not exist, C:\Temp\output.sas.
    NOTE: The SAS System stopped processing this step because of errors.
    NOTE: There were 1 observations read from the data set SASHELP.CARS.
    NOTE: DATA statement used (Total process time):
    real time 0.01 seconds
    cpu time 0.01 seconds

    Why did not create the file?

    Thanks

    • SAS Jedi

      1. Ensure you have called the macro correctly and have provided parameters with the information necessary to produce your DATA step program file in the expected location. I suspect you have either failed to fully qualify your output file name, or have specified a storage location (C:\temp) that does not exist on the computer where your SAS is executing. For example, SAS University Edition runs on Linux where there are no drive letters, and all file paths start with '/myfolders'.

      If you are uncertain, get syntax help with:
      %data2datastep(!help)
      You should get a response like this in the log:

      Purpose: Converts a data set to a SAS DATA step.
      Syntax: %DATA2DATASTEP(dsn,lib,outlib,file,obs,fmt,lbl)
      dsn: Name of the dataset to be converted. Required.
      lib: LIBREF of the original dataset. (Optional - if DSN is not fully qualified)
      outlib: LIBREF for the output dataset. (Optional - default is WORK)
      file: Fully qualified filename for the DATA step code produced. (Optional)
      Default is create_&outlib._&dsn._data.sas in the SAS default directory.
      obs: Max observations to include the created dataset.
      (Optional) Default is MAX (all observations)
      fmt: Format the numeric variables in the output dataset like the original data set?
      (YES|NO - Optional) Default is YES
      lbl: Reproduce column labels in the output dataset?
      (YES|NO - Optional) Default is YES

      2. If that doesn't give you enough information to resolve your problem, re-run the macro after setting SAS option MPRINT:
      options mprint;
      %data2datastep()

      The log will reveal the DATA step code used by the macro to produce the results. If you want help with that, copy your macro call and the resulting DATA step code to the comments here and we can continue to troubleshoot.

      May the SAS be with you!
      Mark

  4. This is a great macro. Thanks much. If you're accepting feature requests, please consider adding support for numeric special missing values (.A .B etc). Currently the macro runs fine, but since the values are written to the data portion of the .sas file as A B etc, and program does not use MISSING statement, the data step errors. I would think could either add a MISSING statement (which is a hassle, because it sets it globally, so ideally should be restored to the user's initial setting), or get the macro to write values as .A .B. Thanks again!

    • SAS Jedi

      I like this idea, and will eventually add this feature. I'll post a comment here when I post the new version.
      Thanks for taking the time to make suggestions!
      Mark

    • SAS Jedi

      Hummm... what do you mean by this? Are you thinking the macro should check for a dataset label and re-create it if it exists? Or were you thinking of variable (column) labels instead?

      • SAS Jedi

        How about this newly modified version?
        http://blogs.sas.com/content/sastraining/files/2017/07/Jedi_SAS_Tricks_Data2DataStepV2-2.zip

        From the macro's self-documentation:
        Purpose: Converts a data set to a SAS DATA step.
        Syntax: %DATA2DATASTEP(dsn,lib,outlib,file,obs,fmt,lbl)
        dsn: Name of the dataset to be converted. Required.
        lib: LIBREF of the original dataset. (Optional - if DSN is not fully qualified)
        outlib: LIBREF for the output dataset. (Optional - default is WORK)
        file: Fully qualified filename for the DATA step code produced. (Optional)
        Default is create_&outlib._&dsn._data.sas in the SAS default directory.
        obs: Max observations to include the created dataset.
        (Optional) Default is MAX (all observations)
        fmt: Format the numeric variables in the output dataset like the original data set?
        (YES|NO - Optional) Default is YES
        lbl: Reproduce column labels in the output dataset?
        (YES|NO - Optional) Default is YES

        • Hi
          I am new to SAS , please advise how to use this program.
          I have downloaded the program called: datatodatastep,sas

          when I open it , it comes as : do I have to fill only the first line in this program down below, (dsn , lib, file , obs) and it will do the rest, I am confused , please advise.

          %macro data2datastep(dsn,lib,file,obs);
          %local varlist msgtype;

          %if %superq(obs)= %then %let obs=MAX;

          %let msgtype=NOTE;
          %if %superq(dsn)= %then %do;
          %let msgtype=ERROR;
          %put &msgtype: You must specify a data set name;
          %put;
          %goto syntax;
          %end;
          %let dsn=%qupcase(%superq(dsn));
          %if %superq(dsn)=!HELP %then %do;
          %syntax:
          %put &msgtype: &SYSMACRONAME macro help document:;
          %put &msgtype- Purpose: Converts a data set to a SAS DATA step.;
          %put &msgtype- Syntax: %nrstr(%%)&SYSMACRONAME(dsn);
          %put &msgtype- dsn: Name of the dataset to be converted. Required.;
          %put &msgtype- lib: LIBREF where the dataset resides. Optional.;
          %put &msgtype- file: Fully qulaified filename for the DATA step produced. Optional.;
          %put &msgtype- Default is %nrstr(create_&lib._&dsn._data.sas) in the SAS default directory.;
          %put &msgtype- obs: Max observations to include the created dataset. Optional.;
          %put &msgtype- Default is MAX (all observations);
          %put;
          %put NOTE: &SYSMACRONAME cannot be used in-line - it generates code.;
          %put NOTE- Use !HELP to print these notes.;
          %return;
          %end;

          %if %superq(lib)= %then %do;
          %let lib=%qscan(%superq(dsn),1,.);
          %if %superq(lib) = %superq(dsn) %then %let lib=WORK;
          %else %let dsn=%qscan(&dsn,2,.);
          %end;
          %let lib=%qupcase(%superq(lib));
          %let dsn=%qupcase(%superq(dsn));

          %if %sysfunc(exist(&lib..&dsn)) ne 1 %then %do;
          %put ERROR: (&SYSMACRONAME) - Dataset &lib..&dsn does not exist.;
          %let msgtype=NOTE;
          %GoTo syntax;
          %end;

          %if %superq(file)= %then %do;
          %let file=create_&lib._&dsn._data.sas;
          %if %symexist(USERDIR) %then %let file=&userdir/&file;
          %end;

          %if %symexist(USERDIR) %then %do;
          %if %qscan(%superq(file),-1,/$$=%superq(file) %then
          %let file=&userdir/&file;
          %end;

          proc sql noprint;
          select Name
          into :varlist separated by ' '
          from dictionary.columns
          where libname="&lib"
          and memname="&dsn"
          ;
          select case type
          when 'num' then
          case
          when missing(format) then cats(Name,':32.')
          else cats(Name,':',format)
          end
          else cats(Name,':$',length,'.')
          end
          into :inputlist separated by ' '
          from dictionary.columns
          where libname="&lib"
          and memname="&dsn"
          ;
          quit;

          data _null_;
          file "&file" dsd;
          if _n_ =1 then do;
          put "data &lib..&dsn;";
          put @3 "infile datalines dsd truncover;";
          put @3 "input %superq(inputlist);";
          put "datalines4;";
          end;
          set &lib..&dsn(obs=&obs) end=last;
          put &varlist @;
          if last then do;
          put;
          put ';;;;';
          end;
          else put;
          run;
          %mend;

          • SAS Jedi

            Taqeer,
            Welcome to the wonderful world of SAS :-) The macro DATA2DATASTEP macro program was designed as a tool you can use without understanding TOO much about how the SAS Macro language and SAS Macro facility work, but I can see that the blog post I wrote to go with it didn't give clear instructions for those not familiar with the arcane world of SAS macro. So here's a very brief explanation of what's going on, and some quick instructions to get it up and running without having to study up on the internals of the program.
            How MACRO programs work:
            1. All of the code you downloaded (everything between the %macro and %mend statements) make up a macro program. Macro programs are designed to write SAS programs for you. Each time you start a new SAS session and want to use a macro program, it will have to be compiled first. After compiling the macro, you can call it as many times as you want to produce SAS programs for you. Many macros, like this one, accept parameters to allow you to control the way the program works. The DATA2DATASTEP macro described in this post is designed to create a SAS DATA step program that can reproduce any SAS data set you choose.

            2. Generic instructions for folks new to SAS who want to use the DATA2DATASTEP macro program described in this post:
            a. Download and unzip that macro program (http://blogs.sas.com/content/sastraining/files/2017/07/Jedi_SAS_Tricks_Data2DataStepV2-2.zip)
            b. Open the program file (data2datastep.sas) in your SAS session and submit it just the way it is - don't change a thing.
            c. In a new Editor window, submit this code: %data2datastep(!help) This will produce instructions in the SAS log on how to use the macro program to recreate a data set of your choice.

            3. A simple example of using the macro to make a program that will re-create the SASHELP.CARS dataset in the WORK library, keeping only 10 observations. We will save the program file to "c:\temp\make_cars.sas". If your computer doesn't have a folder named C:\temp, create it in Windows File Explorer before running this SAS code.
            a. Ensure you have already compiled the macro as described in step 2 above.
            b. In a new Editor window, write and submit this macro call (there is no semicolon included here because macro calls do not require a semicolon):
            %data2datastep(cars, sashelp, work, C:\temp\make_cars.sas,10)
            c. After the program runs, you will find a SAS program file in C:\temp named make_cars.sas.
            d. Open that program in SAS and run it to create a dataset named work.cars with 10 observations.

            If you are new to SAS, you'll want to get familiar with traditional SAS programming before diving into macro. We have tons of free training videos to get you started. When you are ready to tackle macro programming yourself, the SAS Macro documentation is a good place to start. And, of course, SAS offers some excellent training classes on this topic.

            May the SAS be with you!
            Mark

  5. Pingback: Jedi SAS Tricks: DIY Tasks in SAS Studio - SAS Learning Post

  6. Pingback: Jedi SAS Tricks - Make This a Button in Base SAS - SAS Learning Post

  7. When I copy this macro into enterprise guide and feed it parameters %data2datastep(class,sashelp,/SAS Folders/My Folder/output.sas,10);
    It does not work. Am I missing something?

    • SAS Jedi

      Hey, David - please don't copy code from the text in the blog post. Although it looks pretty (and tempting) the HTML usually contains hidden characters that mess up the code when you try to execute it. Instead, download the zip file containing the SAS program from the link provided at the end of the article, unzip it, then open the SAS program in Enterprise Guide and submit that. It should work that way.

      If you still are having trouble, let me know. And it would be helpful to include information about the symptoms of the problem. How did you discover that the code didn't work? What error messages are produced in the SAS log?

      Stay SASy, my friend!
      Mark

  8. Art Carpenter on

    Mark you could also place your code on sasCommunity.org where we can index it.

  9. @Mark Thanks for the follow up. I tested and it works fine now :) I've written a post for the forum, if it gets approved :)

  10. Since I have started to use macros I am becoming a MACROFANATIC, I cannot wait to try tomorrow it and tested...

    THANKS!!!

  11. Edward Ballard on

    Excellent! Now if we could just make a sticky in the SAS Community forums so people could find it easily for posting their data there.

  12. This is awesome Mark!!!
    I couldn't see an out of the box method to use this in SAS UE?
    I used the call as follows:
    %data2datastep(class,sashelp,/folders/myfolders/output.sas,10)

    I can modify the code to work specifically on SAS UE, but wondering if there was a way to make it work out of the box.

    • SAS Jedi

      Fareeza,
      Thanks for this awesome suggestion! I took a look at the problem, and found out that SAS University Edition sets the default path to a location where the user does not have write authority. However, there is an easy way to tell if you are running the macro in SAS University Edition: it automatically creates a GLOBAL scope macro variable named USERDIR when you log in. So I modified the macro to test for the existence of USERDIR and to use the value of USERDIR to set the path for your program file (unless you specified a fully-qualified file name).

      While I was testing, I found another bug in my original code. When testing for the presence of the FILE parameter, I was using &file to resolve the value instead of %superq(file). Having written a blog on this very issue back in 2011 (Jedi SAS Tricks: Macro Q functions), I was a little ashamed of myself...

      In any case, I modified the data2datastep.sas code to fix that bug and to be SAS University Edition-friendly. Just download the ZIP file again to get the updated version (program file modification date is March 13, 2016 at 10:43 am)

      May the SAS be with you!
      Mark

Back to Top