mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-01-04 13:50:06 +00:00
Binary file not shown.
Binary file not shown.
@@ -1,29 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/* >>> dsSQL library: <<<
|
||||
*
|
||||
* The dsSQL library stores temporary views
|
||||
* generated during the %SQL() macro execution.
|
||||
* If possible a subdirectory of WORK is created as:
|
||||
|
||||
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))/dsSQLtmp";
|
||||
|
||||
* if not possible then redirects to WORK as:
|
||||
|
||||
LIBNAME dsSQL BASE "%sysfunc(pathname(WORK))";
|
||||
|
||||
**/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
data _null_;
|
||||
length rc0 $ 32767 rc1 rc2 8;
|
||||
rc0 = DCREATE("dsSQLtmp", "%sysfunc(pathname(work))/" );
|
||||
rc1 = LIBNAME("dsSQL", "%sysfunc(pathname(work))/dsSQLtmp", "BASE");
|
||||
rc2 = LIBREF ("dsSQL" );
|
||||
if rc2 NE 0 then
|
||||
rc1 = LIBNAME("dsSQL", "%sysfunc(pathname(work))", "BASE");
|
||||
run;
|
||||
|
||||
/* list details about the library in the log */
|
||||
libname dsSQL LIST;
|
||||
@@ -1,65 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/* >>> %dsSQL_Inner() macro: <<<
|
||||
*
|
||||
* Internal macro called by dsSQL() function.
|
||||
* The macro generates a uniqualy named sql view on the fly
|
||||
* which is stored in DSSQL library.
|
||||
*
|
||||
* Recommended for SAS 9.3 and higher.
|
||||
* Based on paper:
|
||||
* "Use the Full Power of SAS in Your Function-Style Macros"
|
||||
* by Mike Rhoads, Westat, Rockville, MD
|
||||
* https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
|
||||
*
|
||||
**/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
/* inner macro */
|
||||
%MACRO dsSQL_Inner() / secure;
|
||||
%local query tempfile1 tempfile2 ps_tmp;
|
||||
%let query = %superq(query_arg);
|
||||
%let query = %sysfunc(dequote(&query));
|
||||
|
||||
%let viewname = dsSQL.dsSQLtmpview&UNIQUE_INDEX_2.;
|
||||
|
||||
%let tempfile1 = A%sysfunc(datetime(), hex7.);
|
||||
%let tempfile2 = B%sysfunc(datetime(), hex7.);
|
||||
|
||||
filename &tempfile1. temp;
|
||||
filename &tempfile2. temp;
|
||||
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
options ps = MAX;
|
||||
proc printto log = &tempfile1.;
|
||||
run;
|
||||
/* get the query shape i.e. the executed one */
|
||||
proc sql feedback noexec;
|
||||
&query
|
||||
;
|
||||
quit;
|
||||
proc printto;
|
||||
run;
|
||||
options ps = &ps_tmp.;
|
||||
|
||||
%put *** executed as ***;
|
||||
data _null_;
|
||||
infile &tempfile1. FIRSTOBS = 2; /* <- 2 to ignore header */
|
||||
file &tempfile2.;
|
||||
/* create the view name */
|
||||
if _N_ = 1 then
|
||||
put " create view &viewname. as ";
|
||||
input;
|
||||
put _infile_;
|
||||
putlog ">" _infile_;
|
||||
run;
|
||||
%put *****************;
|
||||
|
||||
proc sql;
|
||||
%include &tempfile2.; /* &query */
|
||||
;
|
||||
quit;
|
||||
filename &tempfile1. clear;
|
||||
filename &tempfile2. clear;
|
||||
%MEND dsSQL_Inner;
|
||||
@@ -1,56 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/* >>> %SQL() macro: <<<
|
||||
*
|
||||
* Main macro which allows to use
|
||||
* SQL's queries in the data step.
|
||||
* Recommended for SAS 9.3 and higher.
|
||||
* Based on paper:
|
||||
* "Use the Full Power of SAS in Your Function-Style Macros"
|
||||
* by Mike Rhoads, Westat, Rockville, MD
|
||||
* https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
|
||||
*
|
||||
* SYNTAX:
|
||||
|
||||
%sql(<nonempty sql querry code>)
|
||||
|
||||
* The sql querry code is limited to 32000 bytes.
|
||||
*
|
||||
* EXAMPLE 1: simple sql query
|
||||
|
||||
data class_subset;
|
||||
set %SQL(select name, sex, height from sashelp.class where age > 12);
|
||||
run;
|
||||
|
||||
* EXAMPLE 2: query with dataset options
|
||||
|
||||
data renamed;
|
||||
set %SQL(select * from sashelp.class where sex = "F")(rename = (age=age2));
|
||||
run;
|
||||
|
||||
* EXAMPLE 3: dictionaries in datastep
|
||||
|
||||
data dictionary;
|
||||
set %SQL(select * from dictionary.macros);
|
||||
run;
|
||||
|
||||
**/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
|
||||
/* Main User macro */
|
||||
%MACRO SQL() / PARMBUFF SECURE;
|
||||
%let SYSPBUFF = %superq(SYSPBUFF); /* macroquoting */
|
||||
%let SYSPBUFF = %substr(&SYSPBUFF, 2, %LENGTH(&SYSPBUFF) - 2); /* remove brackets */
|
||||
%let SYSPBUFF = %superq(SYSPBUFF); /* macroquoting */
|
||||
%let SYSPBUFF = %sysfunc(quote(&SYSPBUFF)); /* quotes */
|
||||
%put NOTE:*** the query ***; /* print out the query in the log */
|
||||
%put NOTE-&SYSPBUFF.;
|
||||
%put NOTE-*****************;
|
||||
|
||||
%local UNIQUE_INDEX; /* internal variable, a unique index for views */
|
||||
%let UNIQUE_INDEX = &SYSINDEX;
|
||||
%sysfunc(dsSQL(&UNIQUE_INDEX, &SYSPBUFF)) /* <-- call dsSQL() function,
|
||||
see the WORK.SQLinDSfcmp dataset */
|
||||
%MEND SQL;
|
||||
@@ -1,42 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/* >>> dsSQL() function: <<<
|
||||
*
|
||||
* Internal function called by %SQL() macro.
|
||||
* The function pass query code from the %SQL()
|
||||
* macro to the %dsSQL_Inner() innternal macreo.
|
||||
*
|
||||
* Recommended for SAS 9.3 and higher.
|
||||
* Based on paper:
|
||||
* "Use the Full Power of SAS in Your Function-Style Macros"
|
||||
* by Mike Rhoads, Westat, Rockville, MD
|
||||
* https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
|
||||
*
|
||||
**/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
proc fcmp
|
||||
/*inlib = work.&packageName.fcmp*/
|
||||
outlib = work.&packageName.fcmp.package
|
||||
;
|
||||
function dsSQL(unique_index_2, query $) $ 41;
|
||||
length
|
||||
query query_arg $ 32000 /* max query length */
|
||||
viewname $ 41
|
||||
;
|
||||
query_arg = dequote(query);
|
||||
rc = run_macro('dsSQL_Inner' /* <-- inner macro */
|
||||
,unique_index_2
|
||||
,query_arg
|
||||
,viewname
|
||||
);
|
||||
if rc = 0 then return(trim(viewname));
|
||||
else
|
||||
do;
|
||||
put 'ERROR:[function dsSQL] A problem with the dsSQL() function';
|
||||
return(" ");
|
||||
end;
|
||||
endsub;
|
||||
run;
|
||||
quit;
|
||||
@@ -1,10 +0,0 @@
|
||||
proc sort data=sashelp.class out=test1;
|
||||
by age name;
|
||||
run;
|
||||
|
||||
data class;
|
||||
set %SQL(select * from sashelp.class order by age, name);
|
||||
run;
|
||||
|
||||
proc compare base = test1 compare = class;
|
||||
run;
|
||||
@@ -1,29 +0,0 @@
|
||||
data class_work;
|
||||
set sashelp.class;
|
||||
run;
|
||||
|
||||
data test_work;
|
||||
set %sql(select * from class_work);
|
||||
run;
|
||||
|
||||
options dlcreatedir;
|
||||
libname user "%sysfunc(pathname(work))/user";
|
||||
%put *%sysfunc(pathname(user))*;
|
||||
|
||||
data cars_user cars_user2;
|
||||
set sashelp.cars;
|
||||
run;
|
||||
|
||||
data test_user;
|
||||
set %sql(select * from cars_user);
|
||||
run;
|
||||
|
||||
data test_user2;
|
||||
set %sql(select * from user.cars_user2);
|
||||
run;
|
||||
|
||||
libname user clear;
|
||||
%put *%sysfunc(pathname(user))*;
|
||||
|
||||
proc datasets lib = work;
|
||||
run;
|
||||
@@ -1,45 +0,0 @@
|
||||
/* This is the description file for the package. */
|
||||
/* The colon (:) is a field separator and is restricted */
|
||||
/* in lines of the header part. */
|
||||
|
||||
/* **HEADER** */
|
||||
Type: Package :/*required, not null, constant value*/
|
||||
Package: SQLinDS :/*required, not null, up to 24 characters, naming restrictions like for a dataset name! */
|
||||
Title: SQL queries in Data Step :/*required, not null*/
|
||||
Version: 2.1 :/*required, not null*/
|
||||
Author: Mike Rhoads (RhoadsM1@Westat.com) :/*required, not null*/
|
||||
Maintainer: Bartosz Jablonski (yabwon@gmail.com) :/*required, not null*/
|
||||
License: MIT :/*required, not null, values: MIT, GPL2, BSD, etc.*/
|
||||
Encoding: UTF8 :/*required, not null, values: UTF8, WLATIN1, LATIN2, etc. */
|
||||
|
||||
Required: "Base SAS Software" :/*optional, COMMA separated, QUOTED list, names of required SAS products, values must be like from proc setinit;run; output */
|
||||
|
||||
/* **DESCRIPTION** */
|
||||
/* All the text below will be used in help */
|
||||
DESCRIPTION START:
|
||||
|
||||
The SQLinDS package is an implementation of
|
||||
the macro-function-sandwich concept introduced in:
|
||||
"Use the Full Power of SAS in Your Function-Style Macros"
|
||||
the article by Mike Rhoads, Westat, Rockville, MD
|
||||
|
||||
Copy of the article is available at:
|
||||
https://support.sas.com/resources/papers/proceedings12/004-2012.pdf
|
||||
|
||||
Package provides ability to "execute" SQL queries inside a datastep, e.g.
|
||||
|
||||
data class;
|
||||
set %SQL(select * from sashelp.class);
|
||||
run;
|
||||
|
||||
SQLinDS package contains the following components:
|
||||
|
||||
1) %SQL() macro - the main package macro available for the User
|
||||
|
||||
2) dsSQL() function (internal)
|
||||
3) %dsSQL_inner() macro (internal)
|
||||
4) Library DSSQL (created in a subdirectory of the WORK library)
|
||||
|
||||
See help for the %SQL() macro to find more examples.
|
||||
|
||||
DESCRIPTION END:
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
|
||||
filename packages "C:\SAS_PACKAGES";
|
||||
%include packages(generatePackage.sas);
|
||||
|
||||
ods html;
|
||||
%generatePackage(filesLocation=C:\SAS_PACKAGES_DEV\SQLinDS)
|
||||
|
||||
|
||||
/*
|
||||
* filename reference "packages" and "package" are keywords;
|
||||
* the first one should be used to point folder with packages;
|
||||
* the second is used internally by macros;
|
||||
|
||||
filename packages "C:\SAS_PACKAGES";
|
||||
%include packages(loadpackage.sas);
|
||||
|
||||
dm 'log;clear';
|
||||
%loadpackage(SQLinDS)
|
||||
|
||||
%helpPackage(SQLinDS)
|
||||
%helpPackage(SQLinDS,*)
|
||||
|
||||
%unloadPackage(SQLinDS)
|
||||
*/
|
||||
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2012 Mike Rhoads
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,82 +0,0 @@
|
||||
|
||||
options dlCreateDir;
|
||||
libname dsSQL "%sysfunc(pathname(work))/dsSQLtmp";
|
||||
|
||||
/* makro zewnetrzne */
|
||||
%MACRO SQL() / PARMBUFF SECURE;
|
||||
%let SYSPBUFF = %superq(SYSPBUFF); /* maskujemy znaki specjalne */
|
||||
%let SYSPBUFF = %substr(&SYSPBUFF,2,%LENGTH(&SYSPBUFF) - 2); /* kasujemy otwierający i zamykający nawias */
|
||||
%let SYSPBUFF = %superq(SYSPBUFF); /* maskujemy jeszcze raz */
|
||||
%let SYSPBUFF = %sysfunc(quote(&SYSPBUFF)); /* dodajemy cudzyslowy */
|
||||
%put ***the querry***;
|
||||
%put &SYSPBUFF.;
|
||||
%put ****************;
|
||||
|
||||
%local UNIQUE_INDEX; /* dodatkowa zmienna indeksujaca, zeby tworzony widok byl unikalny */
|
||||
%let UNIQUE_INDEX = &SYSINDEX; /* przypisujemy jej wartosc */
|
||||
%sysfunc(dsSQL(&UNIQUE_INDEX, &SYSPBUFF)) /* <-- wywolulemy funkcje dsSQL */
|
||||
%MEND SQL;
|
||||
|
||||
/* funkcja */
|
||||
%macro MacroFunctionSandwich_functions();
|
||||
|
||||
%local _cmplib_;
|
||||
options APPEND=(cmplib = WORK.DATASTEPSQLFUNCTIONS) ;
|
||||
%let _cmplib_ = %sysfunc(getoption(cmplib));
|
||||
%put NOTE:[&sysmacroname.] *&=_cmplib_*;
|
||||
|
||||
options cmplib = _null_;
|
||||
|
||||
proc fcmp outlib=work.datastepSQLfunctions.package;
|
||||
function dsSQL(unique_index_2, query $) $ 41;
|
||||
|
||||
length query query_arg $ 32000 viewname $ 41; /* query_arg mozna zmienic na dluzszy, np. 32000 :-) */
|
||||
query_arg = dequote(query);
|
||||
rc = run_macro('dsSQL_Inner', unique_index_2, query_arg, viewname); /* <-- wywolulemy makro wewnetrzne dsSQL_Inner */
|
||||
if rc = 0 then return(trim(viewname));
|
||||
else do;
|
||||
return(" ");
|
||||
put 'ERROR:[function dsSQL] A problem with the function';
|
||||
end;
|
||||
endsub;
|
||||
run;
|
||||
|
||||
options cmplib = &_cmplib_.;
|
||||
%let _cmplib_ = %sysfunc(getoption(cmplib));
|
||||
%put NOTE:[&sysmacroname.] *&=_cmplib_*;
|
||||
|
||||
%mend MacroFunctionSandwich_functions;
|
||||
%MacroFunctionSandwich_functions()
|
||||
|
||||
/* delete macro MacroFunctionSandwich_functions since it is not needed */
|
||||
proc sql;
|
||||
create table _%sysfunc(datetime(), hex16.)_ as
|
||||
select memname, objname
|
||||
from dictionary.catalogs
|
||||
where
|
||||
objname = upcase('MACROFUNCTIONSANDWICH_FUNCTIONS')
|
||||
and objtype = 'MACRO'
|
||||
and libname = 'WORK'
|
||||
order by memname, objname
|
||||
;
|
||||
quit;
|
||||
data _null_;
|
||||
set _last_;
|
||||
call execute('proc catalog cat = work.' !! strip(memname) !! ' et = macro force;');
|
||||
call execute('delete ' !! strip(objname) !! '; run;');
|
||||
call execute('quit;');
|
||||
run;
|
||||
proc delete data = _last_;
|
||||
run;
|
||||
|
||||
/* makro wewnetrzne */
|
||||
%MACRO dsSQL_Inner() / SECURE;
|
||||
%local query;
|
||||
%let query = %superq(query_arg);
|
||||
%let query = %sysfunc(dequote(&query));
|
||||
|
||||
%let viewname = dsSQL.dsSQLtmpview&UNIQUE_INDEX_2;
|
||||
proc sql;
|
||||
create view &viewname as &query;
|
||||
quit;
|
||||
%MEND dsSQL_Inner;
|
||||
Binary file not shown.
Binary file not shown.
1604
generatePackage.sas
1604
generatePackage.sas
File diff suppressed because it is too large
Load Diff
@@ -1,164 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/**############################################################################**/
|
||||
/* */
|
||||
/* Copyright Bartosz Jablonski, July 2019. */
|
||||
/* */
|
||||
/* Code is free and open source. If you want - you can use it. */
|
||||
/* I tested it the best I could */
|
||||
/* but it comes with absolutely no warranty whatsoever. */
|
||||
/* If you cause any damage or something - it will be your own fault. */
|
||||
/* You have been warned! You are using it on your own risk. */
|
||||
/* However, if you decide to use it do not forget to mention author: */
|
||||
/* Bartosz Jablonski (yabwon@gmail.com) */
|
||||
/* */
|
||||
/* Here is the official version: */
|
||||
/*
|
||||
Copyright (c) 2019 Bartosz Jablonski (yabwon@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
/**#############################################################################**/
|
||||
|
||||
/* Macros to install SAS packages, version 20200603 */
|
||||
/* A SAS package is a zip file containing a group of files
|
||||
with SAS code (macros, functions, datasteps generating
|
||||
data, etc.) wrapped up together and %INCLUDEed by
|
||||
a single load.sas file (also embedded inside the zip).
|
||||
*/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
/*** HELP START ***/
|
||||
%macro installPackage(
|
||||
packageName /* package name, without the zip extension */
|
||||
, sourcePath = /* location of the package, e.g. "www.some.page/", mind the "/" at the end */
|
||||
, replace = 1 /* 1 = replace if the package already exist, 0 = otherwise */
|
||||
)
|
||||
/*** HELP END ***/
|
||||
/
|
||||
secure;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp fullstimer_tmp stimer_tmp msglevel_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
%let source_tmp = %sysfunc(getoption(source));
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
|
||||
%local in out;
|
||||
%let in = i%sysfunc(md5(&packageName.),hex7.);
|
||||
%let out = o%sysfunc(md5(&packageName.),hex7.);
|
||||
|
||||
/*options MSGLEVEL=i;*/
|
||||
|
||||
/*
|
||||
Reference:
|
||||
https://blogs.sas.com/content/sasdummy/2011/06/17/how-to-use-sas-data-step-to-copy-a-file-from-anywhere/
|
||||
*/
|
||||
|
||||
%if %superq(sourcePath)= %then
|
||||
%do;
|
||||
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/;
|
||||
%end;
|
||||
filename &in URL "&sourcePath.%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
filename &out "%sysfunc(pathname(packages))/%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
/*
|
||||
filename in list;
|
||||
filename out list;
|
||||
*/
|
||||
/* copy the file byte-by-byte */
|
||||
data _null_;
|
||||
length filein 8 out_path in_path $ 4096;
|
||||
out_path = pathname ("&out");
|
||||
in_path = pathname ("&in" );
|
||||
|
||||
|
||||
filein = fopen( "&in", 'S', 1, 'B');
|
||||
if filein = 0 then
|
||||
put "ERROR: Source file:" /
|
||||
"ERROR- " in_path /
|
||||
"ERROR- is unavaliable!";
|
||||
if filein > 0;
|
||||
|
||||
put @2 "Source information:";
|
||||
infonum = FOPTNUM(filein);
|
||||
length infoname $ 32 infoval $ 128;
|
||||
do i=1 to coalesce(infonum, -1);
|
||||
infoname = FOPTNAME(filein, i);
|
||||
infoval = FINFO(filein, infoname);
|
||||
put @4 infoname ":"
|
||||
/ @6 infoval
|
||||
;
|
||||
end;
|
||||
rc = FCLOSE(filein);
|
||||
put;
|
||||
|
||||
|
||||
|
||||
if FEXIST("&out") = 0 then
|
||||
do;
|
||||
put @2 "Installing the &packageName. package.";
|
||||
rc = FCOPY("&in", "&out");
|
||||
end;
|
||||
else if FEXIST("&out") = 1 then
|
||||
do;
|
||||
if symget("replace")="1" then
|
||||
do;
|
||||
put @2 "The following file will be replaced during "
|
||||
/ @2 "instalation of the &packageName. package: "
|
||||
/ @5 out_path;
|
||||
rc = FDELETE("&out");
|
||||
rc = FCOPY("&in", "&out");
|
||||
end;
|
||||
else
|
||||
do;
|
||||
put @2 "The following file will NOT be replaced: "
|
||||
/ @5 out_path;
|
||||
rc = 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
put @2 "Done with return code " rc=;
|
||||
run;
|
||||
|
||||
filename &in clear;
|
||||
filename &out clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
%mend installPackage;
|
||||
|
||||
/*** HELP START ***/
|
||||
/* Example 1:
|
||||
|
||||
filename packages "C:/Users/&sysuserid/Desktop/download_test/";
|
||||
|
||||
%installPackage(SQLinDS);
|
||||
%installPackage(SQLinDS);
|
||||
%installPackage(SQLinDS,replace=0);
|
||||
|
||||
|
||||
%installPackage(NotExistingPackage);
|
||||
|
||||
*/
|
||||
/*** HELP END ***/
|
||||
19
license.sas
19
license.sas
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2019 Bartosz Jablonski
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
131
listpackages.sas
131
listpackages.sas
@@ -1,131 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/**############################################################################**/
|
||||
/* */
|
||||
/* Copyright Bartosz Jablonski, July 2019. */
|
||||
/* */
|
||||
/* Code is free and open source. If you want - you can use it. */
|
||||
/* I tested it the best I could */
|
||||
/* but it comes with absolutely no warranty whatsoever. */
|
||||
/* If you cause any damage or something - it will be your own fault. */
|
||||
/* You've been warned! You are using it on your own risk. */
|
||||
/* However, if you decide to use it don't forget to mention author: */
|
||||
/* Bartosz Jablonski (yabwon@gmail.com) */
|
||||
/* */
|
||||
/* Here is the official version: */
|
||||
/*
|
||||
Copyright (c) 2019 Bartosz Jablonski (yabwon@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
/**#############################################################################**/
|
||||
|
||||
/* Macros to list SAS packages in packages' folder, version 20020725 */
|
||||
/* A SAS package is a zip file containing a group
|
||||
of SAS codes (macros, functions, datasteps generating
|
||||
data, etc.) wrapped up together and %INCLUDEed by
|
||||
a single load.sas file (also embedded inside the zip).
|
||||
*/
|
||||
/*
|
||||
* Example 1:
|
||||
|
||||
filename packages "C:\SAS_PACKAGES";
|
||||
%include packages(listpackages.sas);
|
||||
%listPackages()
|
||||
|
||||
*/
|
||||
/*** HELP END ***/
|
||||
|
||||
|
||||
%macro listPackages()/
|
||||
des = 'Macro to list SAS package from `package` fileref, version 20020725.'
|
||||
;
|
||||
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp;
|
||||
%let filesWithCodes = WORK._%sysfunc(datetime(), hex16.)_;
|
||||
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
%let source_tmp = %sysfunc(getoption(source));
|
||||
options NOnotes NOsource ls=MAX ps=MAX;
|
||||
|
||||
data _null_;
|
||||
base = "%sysfunc(pathname(packages))";
|
||||
|
||||
if base = " " then
|
||||
do;
|
||||
put "NOTE: The filereference PACKAGES is not assigned.";
|
||||
stop;
|
||||
end;
|
||||
|
||||
length folder file $ 256 folderRef fileRef $ 8;
|
||||
|
||||
folderRef = "_%sysfunc(datetime(), hex6.)0";
|
||||
|
||||
rc=filename(folderRef, base);
|
||||
folderid=dopen(folderRef);
|
||||
|
||||
put;
|
||||
put "/*" 100*"+" ;
|
||||
do i=1 to dnum(folderId); drop i;
|
||||
folder = dread(folderId, i);
|
||||
|
||||
fileRef = "_%sysfunc(datetime(), hex6.)1";
|
||||
rc = filename(fileRef, catx("/", base, folder));
|
||||
fileId = dopen(fileRef);
|
||||
|
||||
EOF = 0;
|
||||
if fileId = 0 and lowcase(scan(folder, -1, ".")) = 'zip' then
|
||||
do;
|
||||
file = catx('/',base, folder);
|
||||
length nn $ 96;
|
||||
nn = repeat("*", (96-lengthn(file)));
|
||||
|
||||
putlog " ";
|
||||
put " * " file @; put nn /;
|
||||
|
||||
infile package ZIP FILEVAR=file member="description.sas" end=EOF;
|
||||
|
||||
do until(EOF);
|
||||
input;
|
||||
if lowcase(scan(_INFILE_,1,":")) in ("package" "title" "version" "author" "maintainer" "license") then
|
||||
do;
|
||||
_INFILE_ = scan(_INFILE_,1,":") !! ":" !! scan(_INFILE_,2,":");
|
||||
putlog " * " _INFILE_;
|
||||
end;
|
||||
if strip(_INFILE_) = "DESCRIPTION START:" then leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
rc = dclose(fileId);
|
||||
rc = filename(fileRef);
|
||||
end;
|
||||
|
||||
putlog " ";
|
||||
put 100*"+" "*/";
|
||||
rc = dclose(folderid);
|
||||
rc = filename(folderRef);
|
||||
stop;
|
||||
run;
|
||||
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.;
|
||||
%mend listPackages;
|
||||
|
||||
602
loadpackage.sas
602
loadpackage.sas
@@ -1,602 +0,0 @@
|
||||
/*** HELP START ***/
|
||||
|
||||
/**############################################################################**/
|
||||
/* */
|
||||
/* Copyright Bartosz Jablonski, July 2019. */
|
||||
/* */
|
||||
/* Code is free and open source. If you want - you can use it. */
|
||||
/* I tested it the best I could */
|
||||
/* but it comes with absolutely no warranty whatsoever. */
|
||||
/* If you cause any damage or something - it will be your own fault. */
|
||||
/* You have been warned! You are using it on your own risk. */
|
||||
/* However, if you decide to use it do not forget to mention author: */
|
||||
/* Bartosz Jablonski (yabwon@gmail.com) */
|
||||
/* */
|
||||
/* Here is the official version: */
|
||||
/*
|
||||
Copyright (c) 2019 Bartosz Jablonski (yabwon@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
/**#############################################################################**/
|
||||
|
||||
/* Macros to load, to get help, or to unload SAS packages, version 20020725 */
|
||||
/* A SAS package is a zip file containing a group of files
|
||||
with SAS code (macros, functions, datasteps generating
|
||||
data, etc.) wrapped up together and %INCLUDEed by
|
||||
a single load.sas file (also embedded inside the zip).
|
||||
*/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
/*** HELP START ***/
|
||||
|
||||
%macro loadPackage(
|
||||
packageName /* name of a package,
|
||||
e.g. myPackage,
|
||||
required and not null */
|
||||
, path = %sysfunc(pathname(packages)) /* location of a package,
|
||||
by default it looks for
|
||||
location of "packages" fileref */
|
||||
, options = %str(LOWCASE_MEMNAME) /* posible options for ZIP filename */
|
||||
, source2 = /*source2*/ /* option to print out details,
|
||||
null by default */
|
||||
, requiredVersion = . /* option to test if loaded package
|
||||
is provided in required version */
|
||||
, lazyData = /* a list of names of lazy datasets
|
||||
to be loaded, if not null then
|
||||
datasets from the list are loaded
|
||||
instead of a package, asterisk
|
||||
means "load all datasets" */
|
||||
, zip = zip /* standard package is zip (lowcase),
|
||||
e.g. %loadPackage(PiPackage)
|
||||
if the zip is not avaliable use a folder
|
||||
unpack data to "pipackage.disk" folder
|
||||
and use loadPackage in the form:
|
||||
%loadPackage(PiPackage, zip=disk, options=)
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load SAS package, version 20020725. Run %loadPackage() for help info.'
|
||||
;
|
||||
%if %superq(packageName) = %then
|
||||
%do;
|
||||
%put ;
|
||||
%put ###############################################################################;
|
||||
%put # This is short help information for the loadPackage macro #;
|
||||
%put ###############################################################################;
|
||||
%put # #;
|
||||
%put # Macro to load SAS packages, version 20020725 #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, datasteps generating #;
|
||||
%put # data, etc.) wrapped up together and included by #;
|
||||
%put # a single load.sas file (also embedded inside the zip). #;
|
||||
%put # #;
|
||||
%put # Parameters: #;
|
||||
%put # #;
|
||||
%put # packageName Name of a package, e.g. myPackage, #;
|
||||
%put # Required and not null, default use case: #;
|
||||
%put # %nrstr(%%loadPackage(myPackage)). #;
|
||||
%put # If empty displays this help information. #;
|
||||
%put # #;
|
||||
%put # path= Location of a package. By default it looks for #;
|
||||
%put # location of the "packages" fileref, i.e. #;
|
||||
%put # %nrstr(%%sysfunc(pathname(packages))) #;
|
||||
%put # #;
|
||||
%put # options= Posible options for ZIP filename, #;
|
||||
%put # default value: LOWCASE_MEMNAME #;
|
||||
%put # #;
|
||||
%put # source2= Option to print out details, null by default. #;
|
||||
%put # #;
|
||||
%put # requiredVersion= Option to test if the loaded package #;
|
||||
%put # is provided in required version, #;
|
||||
%put # default value: . #;
|
||||
%put # #;
|
||||
%put # lazyData= A list of names of lazy datasets to be loaded. #;
|
||||
%put # If not null datasets from the list are loaded #;
|
||||
%put # instead of the package. #;
|
||||
%put # Asterisk (*) means "load all datasets". #;
|
||||
%put # #;
|
||||
%put # zip=zip Standard package is zip (lowcase), #;
|
||||
%put # e.g. %nrstr(%%loadPackage(PiPackage)). #;
|
||||
%put # If the zip is not avaliable use a folder. #;
|
||||
%put # Unpack data to "pipackage.disk" folder #;
|
||||
%put # and use loadPackage in the following form: #;
|
||||
%put # %nrstr(%%loadPackage(PiPackage, zip=disk, options=)) #;
|
||||
%put # #;
|
||||
%put ###############################################################################;
|
||||
%put ;
|
||||
%GOTO ENDloadPackage;
|
||||
%end;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp fullstimer_tmp stimer_tmp msglevel_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
%let source_tmp = %sysfunc(getoption(source));
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
%local _PackageFileref_;
|
||||
%let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.);
|
||||
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
/* put location of package myPackageFile.zip here */
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
;
|
||||
%if %sysfunc(fexist(&_PackageFileref_.)) %then
|
||||
%do;
|
||||
%include &_PackageFileref_.(packagemetadata.sas) / &source2.;
|
||||
filename &_PackageFileref_. clear;
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
%if %sysevalf(&requiredVersion. > &packageVersion.) %then
|
||||
%do;
|
||||
%put ERROR: Required version is &requiredVersion.;
|
||||
%put ERROR- Provided version is &packageVersion.;
|
||||
%ABORT;
|
||||
%end;
|
||||
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.;
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
ENCODING =
|
||||
%if %bquote(&packageEncoding.) NE %then &packageEncoding. ;
|
||||
%else utf8 ;
|
||||
;
|
||||
%if %bquote(&lazyData.) = %then
|
||||
%do;
|
||||
%include &_PackageFileref_.(load.sas) / &source2.;
|
||||
%end;
|
||||
%else
|
||||
%do;
|
||||
%include &_PackageFileref_.(lazydata.sas) / &source2.;
|
||||
%end;
|
||||
|
||||
%end;
|
||||
%else %put ERROR:[&sysmacroname] File "&path./&packageName..&zip." does not exist;
|
||||
filename &_PackageFileref_. clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
|
||||
/* jump here after running %loadPackage() - only help is displayed */
|
||||
%ENDloadPackage:
|
||||
%mend loadPackage;
|
||||
|
||||
/*** HELP START ***/
|
||||
|
||||
%macro unloadPackage(
|
||||
packageName /* name of a package,
|
||||
e.g. myPackage,
|
||||
required and not null */
|
||||
, path = %sysfunc(pathname(packages)) /* location of a package,
|
||||
by default it looks for
|
||||
location of "packages" fileref */
|
||||
, options = %str(LOWCASE_MEMNAME) /* possible options for ZIP filename */
|
||||
, source2 = /*source2*/ /* option to print out details,
|
||||
null by default */
|
||||
, zip = zip /* standard package is zip (lowcase),
|
||||
e.g. %unloadPackage(PiPackage)
|
||||
if the zip is not avaliable use a folder
|
||||
unpack data to "pipackage.disk" folder
|
||||
and use unloadPackage in the form:
|
||||
%unloadPackage(PiPackage, zip=disk, options=)
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to unload SAS package, version 20020725. Run %unloadPackage() for help info.'
|
||||
;
|
||||
%if %superq(packageName) = %then
|
||||
%do;
|
||||
%put ;
|
||||
%put ###############################################################################;
|
||||
%put # This is short help information for the unloadPackage macro #;
|
||||
%put ###############################################################################;
|
||||
%put # #;
|
||||
%put # Macro to unload SAS packages, version 20020725 #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, datasteps generating #;
|
||||
%put # data, etc.) wrapped up together and included by #;
|
||||
%put # a single load.sas file (also embedded inside the zip). #;
|
||||
%put # #;
|
||||
%put # Parameters: #;
|
||||
%put # #;
|
||||
%put # packageName Name of a package, e.g. myPackage, #;
|
||||
%put # Required and not null, default use case: #;
|
||||
%put # %nrstr(%%unloadPackage(myPackage)). #;
|
||||
%put # If empty displays this help information. #;
|
||||
%put # #;
|
||||
%put # path= Location of a package. By default it looks for #;
|
||||
%put # location of the "packages" fileref, i.e. #;
|
||||
%put # %nrstr(%%sysfunc(pathname(packages))) #;
|
||||
%put # #;
|
||||
%put # options= Posible options for ZIP filename, #;
|
||||
%put # default value: LOWCASE_MEMNAME #;
|
||||
%put # #;
|
||||
%put # source2= Option to print out details, null by default. #;
|
||||
%put # #;
|
||||
%put # zip=zip Standard package is zip (lowcase), #;
|
||||
%put # e.g. %nrstr(%%unloadPackage(PiPackage)). #;
|
||||
%put # If the zip is not avaliable use a folder. #;
|
||||
%put # Unpack data to "pipackage.disk" folder #;
|
||||
%put # and use loadPackage in the following form: #;
|
||||
%put # %nrstr(%%unloadPackage(PiPackage, zip=disk, options=)) #;
|
||||
%put # #;
|
||||
%put ###############################################################################;
|
||||
%put ;
|
||||
%GOTO ENDunloadPackage;
|
||||
%end;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
%let source_tmp = %sysfunc(getoption(source));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
|
||||
%local _PackageFileref_;
|
||||
%let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.);
|
||||
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
/* put location of package myPackageFile.zip here */
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
;
|
||||
%if %sysfunc(fexist(&_PackageFileref_.)) %then
|
||||
%do;
|
||||
%include &_PackageFileref_.(packagemetadata.sas) / &source2.;
|
||||
filename &_PackageFileref_. clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.;
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
ENCODING =
|
||||
%if %bquote(&packageEncoding.) NE %then &packageEncoding. ;
|
||||
%else utf8 ;
|
||||
;
|
||||
%include &_PackageFileref_.(unload.sas) / &source2.;
|
||||
%end;
|
||||
%else %put ERROR:[&sysmacroname] File "&path./&packageName..&zip." does not exist;
|
||||
filename &_PackageFileref_. clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp. msglevel = &msglevel_tmp.;
|
||||
/* jump here after running %unloadPackage() - only help is displayed */
|
||||
%ENDunloadPackage:
|
||||
%mend unloadPackage;
|
||||
|
||||
/*** HELP START ***/
|
||||
|
||||
%macro helpPackage(
|
||||
packageName /* name of a package,
|
||||
e.g. myPackageFile.zip,
|
||||
required and not null */
|
||||
, helpKeyword /* phrase to search in help,
|
||||
when empty prints description
|
||||
"*" means prints all help
|
||||
"license" prints license */
|
||||
, path = %sysfunc(pathname(packages)) /* location of a package,
|
||||
by default it looks for
|
||||
location of "packages" fileref */
|
||||
, options = %str(LOWCASE_MEMNAME) /* possible options for ZIP filename */
|
||||
, source2 = /*source2*/ /* option to print out details,
|
||||
null by default */
|
||||
, zip = zip /* standard package is zip (lowcase),
|
||||
e.g. %helpPackage(PiPackage,*)
|
||||
if the zip is not avaliable use a folder
|
||||
unpack data to "pipackage.disk" folder
|
||||
and use helpPackage in the form:
|
||||
%helpPackage(PiPackage, *, zip=disk, options=)
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to get help about SAS package, version 20020725. Run %helpPackage() for help info.'
|
||||
;
|
||||
%if %superq(packageName) = %then
|
||||
%do;
|
||||
%put ;
|
||||
%put ###############################################################################;
|
||||
%put # This is short help information for the helpPackage macro #;
|
||||
%put ###############################################################################;
|
||||
%put # #;
|
||||
%put # Macro to get help about SAS packages, version 20020725 #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, datasteps generating #;
|
||||
%put # data, etc.) wrapped up together and included by #;
|
||||
%put # a single load.sas file (also embedded inside the zip). #;
|
||||
%put # #;
|
||||
%put # Parameters: #;
|
||||
%put # #;
|
||||
%put # packageName Name of a package, e.g. myPackage, #;
|
||||
%put # Required and not null, default use case: #;
|
||||
%put # %nrstr(%%helpPackage(myPackage)). #;
|
||||
%put # If empty displays this help information. #;
|
||||
%put # #;
|
||||
%put # helpKeyword Phrase to search in help, #;
|
||||
%put # - when empty prints description, #;
|
||||
%put # - "*" means prints all help, #;
|
||||
%put # - "license" prints license. #;
|
||||
%put # #;
|
||||
%put # path= Location of a package. By default it looks for #;
|
||||
%put # location of the "packages" fileref, i.e. #;
|
||||
%put # %nrstr(%%sysfunc(pathname(packages))) #;
|
||||
%put # #;
|
||||
%put # options= Posible options for ZIP filename, #;
|
||||
%put # default value: LOWCASE_MEMNAME #;
|
||||
%put # #;
|
||||
%put # source2= Option to print out details, null by default. #;
|
||||
%put # #;
|
||||
%put # zip=zip Standard package is zip (lowcase), #;
|
||||
%put # e.g. %nrstr(%%helpPackage(PiPackage)). #;
|
||||
%put # If the zip is not avaliable use a folder. #;
|
||||
%put # Unpack data to "pipackage.disk" folder #;
|
||||
%put # and use loadPackage in the following form: #;
|
||||
%put # %nrstr(%%helpPackage(PiPackage, zip=disk, options=)) #;
|
||||
%put # #;
|
||||
%put ###############################################################################;
|
||||
%put ;
|
||||
%GOTO ENDhelpPackage;
|
||||
%end;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
%let source_tmp = %sysfunc(getoption(source));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
|
||||
%local _PackageFileref_;
|
||||
%let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.);
|
||||
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
/* put location of package myPackageFile.zip here */
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
;
|
||||
%if %sysfunc(fexist(&_PackageFileref_.)) %then
|
||||
%do;
|
||||
%include &_PackageFileref_.(packagemetadata.sas) / &source2.;
|
||||
filename &_PackageFileref_. clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.;
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
ENCODING =
|
||||
%if %bquote(&packageEncoding.) NE %then &packageEncoding. ;
|
||||
%else utf8 ;
|
||||
;
|
||||
%include &_PackageFileref_.(help.sas) / &source2.;
|
||||
%end;
|
||||
%else %put ERROR:[&sysmacroname] File "&path./&packageName..&zip." does not exist;
|
||||
filename &_PackageFileref_. clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp. msglevel = &msglevel_tmp.;
|
||||
/* jump here after running %helpPackage() - only help is displayed */
|
||||
%ENDhelpPackage:
|
||||
%mend helpPackage;
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- macro for testing available packages in the packages folder [DONE] checkout: %listPackages()
|
||||
- add MD5(&packageName.) value hash instead "package" word in filenames [DONE]
|
||||
*/
|
||||
|
||||
/*** HELP START ***/
|
||||
|
||||
/*
|
||||
* Filenames references "packages" and "package" are keywords;
|
||||
* the first one should be used to point folder with packages;
|
||||
* the second is used internally by macros;
|
||||
|
||||
* Example 1:
|
||||
* assuming that _THIS_FILE_ and the SQLinDS package (sqlinds.zip file)
|
||||
* are located in the "C:/SAS_PACKAGES/" folder
|
||||
* copy the following code into autoexec.sas
|
||||
* or run it in your SAS session
|
||||
**/
|
||||
/*
|
||||
|
||||
filename packages "C:/SAS_PACKAGES";
|
||||
%include packages(loadpackage.sas);
|
||||
|
||||
%loadpackage(SQLinDS)
|
||||
%helpPackage(SQLinDS)
|
||||
%unloadPackage(SQLinDS)
|
||||
|
||||
* optional;
|
||||
|
||||
libname packages "C:/SAS_PACKAGES/";
|
||||
%include "%sysfunc(pathname(packages))/loadpackage.sas";
|
||||
|
||||
%loadPackage(SQLinDS)
|
||||
%helpPackage(SQLinDS)
|
||||
%unloadPackage(SQLinDS)
|
||||
|
||||
* in case when user SAS session does not support ZIP fileref ;
|
||||
* the following solution could be used, ;
|
||||
* unzip packagename.zip content into packagename.disk folder ;
|
||||
* and run macros with following options: ;
|
||||
|
||||
%loadPackage(packageName,zip=disk,options=)
|
||||
%helpPackage(packageName,,zip=disk,options=) %* mind double comma! ;
|
||||
%unloadPackage(packageName,zip=disk,options=)
|
||||
|
||||
*/
|
||||
/*** HELP END ***/
|
||||
|
||||
|
||||
/*** HELP START ***/
|
||||
/* Macros to install SAS packages, version 20200603 */
|
||||
/* A SAS package is a zip file containing a group of files
|
||||
with SAS code (macros, functions, datasteps generating
|
||||
data, etc.) wrapped up together and %INCLUDEed by
|
||||
a single load.sas file (also embedded inside the zip).
|
||||
*/
|
||||
|
||||
/*** HELP END ***/
|
||||
|
||||
/*** HELP START ***/
|
||||
%macro installPackage(
|
||||
packageName /* package name, without the zip extension */
|
||||
, sourcePath = /* location of the package, e.g. "www.some.page/", mind the "/" at the end */
|
||||
, replace = 1 /* 1 = replace if the package already exist, 0 = otherwise */
|
||||
)
|
||||
/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to install SAS package, version 20020725. Run %%installPackage() for help info.'
|
||||
;
|
||||
%if %superq(packageName) = %then
|
||||
%do;
|
||||
%put ;
|
||||
%put ###############################################################################;
|
||||
%put # This is short help information for the installPackage macro #;
|
||||
%put ###############################################################################;
|
||||
%put # #;
|
||||
%put # Macro to install SAS packages, version 20020725 #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, datasteps generating #;
|
||||
%put # data, etc.) wrapped up together and included by #;
|
||||
%put # a single load.sas file (also embedded inside the zip). #;
|
||||
%put # #;
|
||||
%put # Parameters: #;
|
||||
%put # #;
|
||||
%put # packageName Name of a package, e.g. myPackage, #;
|
||||
%put # Required and not null, default use case: #;
|
||||
%put # %nrstr(%%installPackage(myPackage)). #;
|
||||
%put # If empty displays this help information. #;
|
||||
%put # #;
|
||||
%put # sourcePath= Location of the package, e.g. "www.some.web.page/" #;
|
||||
%put # Mind the "/" at the end of the path! #;
|
||||
%put # Current default location: #;
|
||||
%put # https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/ #;
|
||||
%put # #;
|
||||
%put # replace= With default value of 1 it causes existing package file #;
|
||||
%put # to be replaceed by new downloaded file. #;
|
||||
%put # #;
|
||||
%put ###############################################################################;
|
||||
%put ;
|
||||
%GOTO ENDinstallPackage;
|
||||
%end;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp fullstimer_tmp stimer_tmp msglevel_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
%let source_tmp = %sysfunc(getoption(source));
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
|
||||
%local in out;
|
||||
%let in = i%sysfunc(md5(&packageName.),hex7.);
|
||||
%let out = o%sysfunc(md5(&packageName.),hex7.);
|
||||
|
||||
/*options MSGLEVEL=i;*/
|
||||
|
||||
/*
|
||||
Reference:
|
||||
https://blogs.sas.com/content/sasdummy/2011/06/17/how-to-use-sas-data-step-to-copy-a-file-from-anywhere/
|
||||
*/
|
||||
|
||||
%if %superq(sourcePath)= %then
|
||||
%do;
|
||||
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/;
|
||||
%end;
|
||||
filename &in URL "&sourcePath.%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
filename &out "%sysfunc(pathname(packages))/%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
/*
|
||||
filename in list;
|
||||
filename out list;
|
||||
*/
|
||||
/* copy the file byte-by-byte */
|
||||
data _null_;
|
||||
length filein 8 out_path in_path $ 4096;
|
||||
out_path = pathname ("&out");
|
||||
in_path = pathname ("&in" );
|
||||
|
||||
|
||||
filein = fopen( "&in", 'S', 1, 'B');
|
||||
if filein = 0 then
|
||||
put "ERROR: Source file:" /
|
||||
"ERROR- " in_path /
|
||||
"ERROR- is unavaliable!";
|
||||
if filein > 0;
|
||||
|
||||
put @2 "Source information:";
|
||||
infonum = FOPTNUM(filein);
|
||||
length infoname $ 32 infoval $ 128;
|
||||
do i=1 to coalesce(infonum, -1);
|
||||
infoname = FOPTNAME(filein, i);
|
||||
infoval = FINFO(filein, infoname);
|
||||
put @4 infoname ":"
|
||||
/ @6 infoval
|
||||
;
|
||||
end;
|
||||
rc = FCLOSE(filein);
|
||||
put;
|
||||
|
||||
|
||||
|
||||
if FEXIST("&out") = 0 then
|
||||
do;
|
||||
put @2 "Installing the &packageName. package.";
|
||||
rc = FCOPY("&in", "&out");
|
||||
end;
|
||||
else if FEXIST("&out") = 1 then
|
||||
do;
|
||||
if symget("replace")="1" then
|
||||
do;
|
||||
put @2 "The following file will be replaced during "
|
||||
/ @2 "instalation of the &packageName. package: "
|
||||
/ @5 out_path;
|
||||
rc = FDELETE("&out");
|
||||
rc = FCOPY("&in", "&out");
|
||||
end;
|
||||
else
|
||||
do;
|
||||
put @2 "The following file will NOT be replaced: "
|
||||
/ @5 out_path;
|
||||
rc = 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
put @2 "Done with return code " rc=;
|
||||
run;
|
||||
|
||||
filename &in clear;
|
||||
filename &out clear;
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
/* jump here after running %installPackage() - only help is displayed */
|
||||
%ENDinstallPackage:
|
||||
%mend installPackage;
|
||||
|
||||
/*** HELP START ***/
|
||||
/* Example 1:
|
||||
|
||||
filename packages "C:/Users/&sysuserid/Desktop/download_test/";
|
||||
|
||||
%installPackage(SQLinDS);
|
||||
%installPackage(SQLinDS);
|
||||
%installPackage(SQLinDS,replace=0);
|
||||
|
||||
|
||||
%installPackage(NotExistingPackage);
|
||||
|
||||
*/
|
||||
/*** HELP END ***/
|
||||
BIN
macroarray.zip
BIN
macroarray.zip
Binary file not shown.
BIN
sqlinds.zip
BIN
sqlinds.zip
Binary file not shown.
Reference in New Issue
Block a user