How to make macros callable without definition - sas

Currently I have a few macros which are very useful but I need to define in each program and then call them. Is there a way I can make a library of macros for myself that I can reference with no need to define them in the same program, maybe needing to be able to call them from a specific library.
Currently:
%macro GenericMacro1(&File);
....
%mend;
%GenericMacro1(File1);
%GenericMacro1(File2);
Want:
libname MyMacros "C://.....";
%MyMacros.GenericMacro1(File1);
%MyMacros.GenericMacro2(File2);

Refer to the SASAUTOS documentation
identifies a location that contains library
members that contain a SAS macro definition. A location can be a SAS
fileref or a host-specific location name enclosed in quotation marks.
Each member contains a SAS macro definition.
Related options are MAUTOSOURCE to enable the autocall facility.
You can also use stored precompiled macros in your SAS session use.
options mstored sasmstore=mylib;
The original source code of a compiled macro is not always extractable during a running SAS session, the documentation warns
CAUTION:
Save your macro source code.

The closest thing to what you are asking for would be to include all the macros at the start of the program. Save the macros into a folder with no other sas programs. Then
%include "C:\path\to\folder\*.sas";
That will include all SAS files in that folder and will compile the macros at the start.
Richard mentions the AUTOCALL feature. Same idea, create a folder with all your macros. Here you need to name the file and the macro the same name. 1 macro per file. Best practice is to use lowercase only.
In your config file (C:\Program Files\SASHome\SASFoundation\9.4\nls\en\sasv9.cfg on my system), you will see a line that starts -SASAUTOS (line 60 in mine). Append your folder location to that list. Restart SAS and you should be able to call the macros in your session.
Alternatively, you can alter the SASAUTOS values during your autoexec.sas.
OPTIONS SASAUTOS=("C:\path\to\folder",
SASAUTOS);

Related

SAS Mfile Capture open code between macro calls

We can capture macro(%test) executed code with the below snippet
filename mprint 'output-file-name.sas';
options MPRINT MFILE;
%test;
options NOMPRINT NOMFILE;
Is there a way to capture the SAS executed code with MFILE option when we have datasteps/proc calls between the macro calls.
Example:
%test;
data ...
set ...
...
run;
%test2;
proc sort data=...
run;
%test3;
Using some sort of wrapper code to put the above code in a macro and then use MFILE ?
Is there any automated standard approach ? I have to implement the solution at enterprise level.
If you have control over the code itself, then you can do it easily using either:
Alternate logging methods for the entire SAS log (proc printto, altlog startup option)
Wrap the entire code in a macro, then use options mfile
That requires you being able to edit the code, though. Given you've thought of the second, and are asking how, I assume you probably don't have control directly.
If you do not have control over the code but have control over the SAS system (for example, you're a SAS Administrator), then you have a few options, all related to capturing the entire log.
You can, again, use altlog option
Better, though, is the more advanced logging options using the SAS logging facility. This can be used to put pretty detailed logs from the workspace server, or even from base SAS itself if you're in an environment where users run base SAS interactively.
If you are using a SAS Workspace Server (Enterprise Guide, SAS Studio), then the latter option is very easy: you just need to change the Workspace Server's logging level to Debug, and modify the name of the file it outputs to such that you can make use of it (add to the name things like the username).
Do note that options mfile can be overridden by the user, unless you add it to the restricted options table.

SAS script works via EG, but fails in linux

I am trying to go over set and get the path of a file. Then, I want to open the file and get another set out of it.
My problem is that my script works without any issues when executed via Enterprise Guide, but fails if executed via command line.
WARNING: Apparent invocation of macro GET_DATA not resolved.
Seems like my path variable is not set and my macro is not executed when I run it via command line.
data _null_;
set files_to_parse;
count + 1;
call execute('%get_data('||path||', '||count||')');
run;
Here I am trying to instantiate an excel as a library
%macro get_data(path, cnt);
/* Get current iteration of excel spreadsheet */
libname xl XLSX "&path.";
%mend get_data;
Make sure you have defined the macro before trying to use it. Perhaps with EG your program worked because you had previously compiled the macro.
The error is that %get_data is not compiled, not that it's not resolving the path.
It's hard to say why with the information you gave us, but since you see a difference running in EG vs in command line, I suspect you either have the macro compiled as part of an autoexec process flow in EG, or you have an autocall macro library that's not properly set up through the command line config file. Talk to your SAS Admin if you don't know what these things mean.

Change temporary file directory in SAS

I need to use PROC.SQL statements for my analysis. The problem is, SAS uses C disk in order to create temporary files when I use SQL statements. My datasets are very large and I do not have enough space for that. Could you please explain me how to allocate this temporary file in other place rather than C disk?
You want to change the WORK system option. You can do:
c:\sas\sas.exe -work d:\temp
to use the d:\temp directory.
You can also use the OPTIONS statement within the config file used when starting SAS (thanks Tom):
options work='d:\temp'
See also:
Indiana University answer for SAS on UNIX systems.
SAS 9.2 documentation on system options.
Create a 'user' library instead. When a USER library is in effect, all one level datasets are written to this directory and it's used as the default instead of WORK library.
libname user 'path to other location';
If you want to permanently change sas work location, you can set it in sasv9.cfg. (Default location: C:\Program Files\SASHome\SASFoundation\9.4\nls\en\sasv9.cfg). Along with -WORK, you may also want to change the value for -UTILLOC option.
You can even spread a Load across Multiple Volumes of Different Disks. Please read Example 1 mentioned in this link - https://support.sas.com/documentation/cdl/en/hostwin/69955/HTML/default/viewer.htm#n1qr5dmzagn9krn1lt1c276963za.htm

Remove standard SAS libraries from GUI

I'd like to remove/delete/unassign the standard SAS libraries from my SAS 9.3 GUI.
I've tried two solutions to remove a library which haven't worked:
%sysfunc(libname(maps)) results in:
ERROR 180-322: Statement is not valid or it is used out of proper order.
Comment out the offending start up code in the file sasv9.cfg
I don't have permission to modify (C:\Program Files...) files in that directory
Thanks!
The libraries are:
- Maps
Mapsgfk
Mapssas
Sashelp
Sasuser
You can remove the map related libnames, at the cost of not having the map files available to you and possibly losing some functionality.
If you copy your basic config file to some other location, either to one of the predefined locations mentioned in Files Used By SAS for your operating system (I link to the Windows version here, but Unix has a similar page); or to a location specified on the -CONFIG option in your shortcut, like for example:
"C:\Program Files\SAS94\SASFoundation\9.4\sas.exe" -CONFIG "C:\temp\sasv9_nolibs.cfg"
You can do this without having write access to the Program Files directories where the config files are usually stored. If you do that, you can then customize it by removing the -MAPS and related lines. Then those libraries will not be created; in that case, only SASHELP, SASUSER, and WORK are created, as follows:
Removing SASUSER does not seem to be possible, as while you can remove the -SASUSER option in the config file, it will still create the SASUSER folder.
Removing the -SASHELP option will unfortunately cause SAS to crash on initialization; SASHELP contains many core files for SAS functionality and SAS cannot work without it. See the following screenshot.
As such, you can get down to 3 libraries, but not further.
You got the 180-322 because the libname function returns a value and you call it in open code and the code it generated is not valid.
29 %put NOTE: %sysfunc(libname(maps));
NOTE: -630193
Do as above an you will see the value. However it looks like you cannot clear LIBREF MAPS.
Not sure if you can remove them without changing your system wide config.sas file. But you could point the MAPS options to null devices so that they don't find any datasets. Here is output from PROC OPTIONS.
MAPS=!SASROOT/maps
Specifies the location of SAS/GRAPH map data sets.
MAPSGFK=!SASROOT/mapsgfk
Specifies the location of GfK maps.
MAPSSAS=!SASROOT/maps
Specifies the location of SAS map data sets.
You can point these two different locations with command line options.
sas -maps /dev/nul -mapsgfk /dev/nul -mapssas /dev/nul
The libref will still be created but there won't be any members found.
You might do something similar for SASUSER, but then you would probably also want to add -rsasuser option so that SAS would know to create a WORK.PROFILE to use in place of the normal SASUSER.PROFILE catalog.
I don't think you would want to remove SASHELP libref as I think there are a number of things in SAS that would not work without being able to find things that are made available via that libref.

front end in Stata

My client has a couple of Stata programs (.do files) that they have been running for a while.
Is it possible to have a front end page or a form for Stata so that we can choose different options/criteria and based on the selections certain programs on Stata are run?
Basically is there a way of creating a form for Stata programs?
One rough way of making a "form" for a program is to use macros. This is not an explicit dialog form, with textboxes, but it allows you to control a program from a single .do file.
Basically, use a bunch of global macros in a separate do file, then have the macros peppered throughout the .do files. My example below does this
Macros File (Form do-file)
global projectname stackoverflow
global exportfmt putdocx
global analysisfolder "/file/path"
global dofilesfolder "/file/path"
The macro projectname allows you to name the project, and thus I put it in all the file save commands, or I save a cleaned dataset using that name. You can even put it inside a file path.
The macro exportfmt you typically use when generating reports using the putdocx or putpdf command. Having a global variable allows me to switch between exporting a pdf or docx.
The macros analysisfolder and dofilesfolder you then use to create file paths that you can call for different projects, just by filling out the "form".
Do-files Usage
$exportfmt clear
$analysisfolder
use $project, clear
$exportfmt begin
$exportfmt paragraph
Thus, create a separate do-file (form do-file) with all your macros, and then you can change them all in one place as you see fit.
It's not a true form, but it can simplify changing of many things throughout a Stata program.
Stata can be launched in batch mode as
stata /b do whatever.do
So you can form that whatever.do file using the tools that are convenient for you, and then run it as needed. Of course you need to make sure that whatever output is being produced by the client's do-files is being saved in a computer readable format (rather than just left there in the screen for the analyst to copy and paste into Word).
This is implemented by ADePT team of the World Bank, see http://www.worldbank.org/adept. It has a C# GUI, but it runs Stata deep inside.
You can make a form that you can use from Stata's drop-down menu. See the help dialog_programming page.