mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-01-03 21:30:06 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e47ab5e37 | ||
|
|
c4e21e86b6 | ||
|
|
006377b255 | ||
|
|
4b640e8ce1 | ||
|
|
7a7f674acf | ||
|
|
c667bc6b25 | ||
|
|
0a01f39662 | ||
|
|
45127a057e | ||
|
|
3f950e11ce | ||
|
|
96247523ba | ||
|
|
425f7b389c | ||
|
|
56748bc44b |
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 - 2023 Bartosz Jablonski
|
||||
Copyright (c) 2019 - 2024 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
|
||||
|
||||
19
README.md
19
README.md
@@ -16,7 +16,7 @@ Don't forget to **STAR** (:star:) the repository! :-)
|
||||
|
||||
### Current version:
|
||||
|
||||
**The latest version** of SPF is **`20240711`**.
|
||||
**The latest version** of SPF is **`20241207`**.
|
||||
|
||||
To get started with SAS Packages try this [**`Getting Started with SAS Packages`**](https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/Documentation/Getting_Started_with_SAS_Packages.pdf "Getting Started with SAS Packages") presentation (see the `./SPF/Documentation` directory).
|
||||
|
||||
@@ -51,7 +51,8 @@ Letter "D" indicates tutorial dedicated for developers and "U" materials for use
|
||||
|
||||
3) (D) Article and all required materials for ["My first SAS Package"](https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation/Paper_1079-2021) tutorial.
|
||||
|
||||
4) (DU) Materials from Hands-on-Workshop (4+ hours) tutorial: [Share your code with SAS Packages](https://github.com/yabwon/HoW-SASPackages).
|
||||
4) (DU) Materials from Hands-on-Workshop (4+ hours) tutorial: [Share your code with SAS Packages](https://github.com/yabwon/HoW-SASPackages).
|
||||
It is a "zero to hero" tutorial that explains all the "bells and whistles" of using, and all the "nuts and bolts" of developing SAS packages.
|
||||
|
||||
|
||||
---
|
||||
@@ -163,6 +164,10 @@ The SAS Packages Framework [(short) documentation](https://github.com/yabwon/SAS
|
||||
|
||||
### Updates worth mentioning:
|
||||
|
||||
**Update**\[October 27th, 2024\]**:** `%splitCodeForPackage()` **utility macro is available. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20241027 "splitCodeForPackage"))**.
|
||||
|
||||
**Update**\[October 14th, 2024\]**:** `DS2PCK` and `DS2THR` **types for `PROC DS2` *threads* and *packages* added to the framework. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20241014 "PROC DS2"))**.
|
||||
|
||||
**Update**\[December 10th, 2023\]**:** `markdownDoc=` **parameter added to** `%generatePackage()` **macro, which allows to generate markdown file with documentation. Content is taken from the help information notes and the description. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20231210 "markdown documentation"))**.
|
||||
|
||||
**Update**\[November 11th, 2023\]**:** `KMFSNIP` **type for *key macro abbreviations* snippets added to the framework. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20231111 "KMF-abbreviations"))**.
|
||||
@@ -215,32 +220,32 @@ Packages:
|
||||
|
||||
- **SQLinDS**
|
||||
|
||||
[Documentation for SQLinDS](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/sqlinds.md "Documentation for SQLinDS")
|
||||
[Documentation for SQLinDS](https://github.com/SASPAC/blob/main/sqlinds.md "Documentation for SQLinDS")
|
||||
|
||||
[SQLinDS in SASPAC](https://github.com/SASPAC/sqlinds "SQLinDS in SASPAC")
|
||||
|
||||
|
||||
- **DFA** (Dynamic Function Arrays)
|
||||
|
||||
[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA")
|
||||
[Documentation for DFA](https://github.com/SASPAC/blob/main/dfa.md "Documentation for DFA")
|
||||
|
||||
[DFA in SASPAC](https://github.com/SASPAC/dfa "DFA in SASPAC")
|
||||
|
||||
- **macroArray**
|
||||
|
||||
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
|
||||
[Documentation for macroArray](https://github.com/SASPAC/blob/main/macroarray.md "Documentation for macroArray")
|
||||
|
||||
[MacroArray in SASPAC](https://github.com/SASPAC/macroarray "MacroArray in SASPAC")
|
||||
|
||||
- **BasePlus**
|
||||
|
||||
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
|
||||
[Documentation for BasePlus](https://github.com/SASPAC/blob/main/baseplus.md "Documentation for BasePlus")
|
||||
|
||||
[BasePlus in SASPAC](https://github.com/SASPAC/baseplus "BasePlus in SASPAC")
|
||||
|
||||
- **GSM** (Generate Secure Macros)
|
||||
|
||||
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")
|
||||
[Documentation for GSM](https://github.com/SASPAC/blob/main/gsm.md "Documentation for GSM")
|
||||
|
||||
[GSM in SASPAC](https://github.com/SASPAC/gsm "GSM in SASPAC")
|
||||
|
||||
|
||||
BIN
SPF/Documentation/Paper_SM01-PHUSEEU2024.pdf
Normal file
BIN
SPF/Documentation/Paper_SM01-PHUSEEU2024.pdf
Normal file
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
when empty the "packages" value is used */
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to list directories pointed by "packages" fileref, version 20240711. Run %extendPackagesFileref(HELP) for help info.'
|
||||
des = 'Macro to list directories pointed by "packages" fileref, version 20241207. Run %extendPackagesFileref(HELP) for help info.'
|
||||
;
|
||||
|
||||
%if %QUPCASE(&packages.) = HELP %then
|
||||
@@ -22,7 +22,7 @@ des = 'Macro to list directories pointed by "packages" fileref, version 20240711
|
||||
%put ### This is short help information for the `extendPackagesFileref` macro #;
|
||||
%put #-----------------------------------------------------------------------------------------#;;
|
||||
%put # #;
|
||||
%put # Macro to list directories pointed by 'packages' fileref, version `20240711` #;
|
||||
%put # Macro to list directories pointed by 'packages' fileref, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -56,7 +56,7 @@ des = 'Macro to list directories pointed by "packages" fileref, version 20240711
|
||||
%put # Run the following code in your SAS session: #;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas;
|
||||
%put %nrstr( filename packages ("C:/SAS_PK1" "C:/SAS_PK2"); %%* setup a directory for packages; );
|
||||
%put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; );
|
||||
%put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; );
|
||||
%put ;
|
||||
%put %nrstr( filename packages ("D:/NEW_DIR" %%extendPackagesFileref()); %%* add new directory; );
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Macro to generate SAS packages.
|
||||
|
||||
Version 20240711
|
||||
Version 20241207
|
||||
|
||||
A SAS package is a zip file containing a group
|
||||
of SAS codes (macros, functions, data steps generating
|
||||
@@ -43,7 +43,7 @@
|
||||
file name be created */
|
||||
)/ secure minoperator
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to generate SAS packages, version 20240711. Run %generatePackage() for help info.'
|
||||
des = 'Macro to generate SAS packages, version 20241207. Run %generatePackage() for help info.'
|
||||
;
|
||||
%if (%superq(filesLocation) = ) OR (%qupcase(&filesLocation.) = HELP) %then
|
||||
%do;
|
||||
@@ -58,7 +58,7 @@ des = 'Macro to generate SAS packages, version 20240711. Run %generatePackage()
|
||||
%put ### This is short help information for the `generatePackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to generate SAS packages, version `20240711` #;
|
||||
%put # Macro to generate SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -434,7 +434,7 @@ Maintainer: Firstname Lastname (xxxxxx@yyyyy.com)
|
||||
License: MIT
|
||||
Encoding: UTF8
|
||||
|
||||
Required: "Base SAS Software" :%*optional, COMMA separated, QUOTED list, names of required SAS products, values must be like from proc setinit;run; output *;
|
||||
Required: "Base SAS Software" :%*optional, COMMA separated, QUOTED list, names of required SAS products, values must be like from "proc setinit" output *;
|
||||
ReqPackages: "macroArray (0.1)", "DFA (0.1)" :%*optional, COMMA separated, QUOTED list, names of required packages *;
|
||||
|
||||
>> **DESCRIPTION** <<
|
||||
@@ -510,7 +510,7 @@ DESCRIPTION END:
|
||||
| it will be created only if user request it by using:
|
||||
| %loadPackage(packagename, lazyData=klm)
|
||||
| multiple elements separated by space are allowed
|
||||
| an asterisk(*) means "load all data"]
|
||||
| an asterisk("*") means "load all data"]
|
||||
|
|
||||
+-010_imlmodule [one file one IML module,
|
||||
| | only plain code of the module, without "Proc IML" header]
|
||||
@@ -527,6 +527,18 @@ DESCRIPTION END:
|
||||
| |
|
||||
| +-abc.sas [a file with a KMF-abbreviation snippet ABC, _with_ proper tagging, snippets names are in low-case]
|
||||
|
|
||||
+-013_ds2pck [one file one PROC DS2 package]
|
||||
| |
|
||||
| +-abc.sas [a data set with a package ABC stored in WORK.ABC data set]
|
||||
| |
|
||||
| +-library.xyz.sas [a data set with a package LIBRARY.XYZ stored in LIBRARY.XYZ data set]
|
||||
|
|
||||
+-014_ds2thr [one file one PROC DS2 thread]
|
||||
| |
|
||||
| +-abc.sas [a data set with a thread ABC stored in WORK.ABC data set]
|
||||
| |
|
||||
| +-library.xyz.sas [a data set with a thread LIBRARY.XYZ stored in LIBRARY.XYZ data set]
|
||||
|
|
||||
+-<sequential number>_<type [in lower case]>
|
||||
|
|
||||
+-00n_clean [if you need to clean something up after exec file execution,
|
||||
@@ -609,6 +621,7 @@ data &filesWithCodes.;
|
||||
'IMLMODULE' 'PROTO' 'EXEC' 'CLEAN'
|
||||
'LAZYDATA' 'TEST' 'CASLUDF'
|
||||
'ADDCNT' 'KMFSNIP'
|
||||
'DS2PCK' 'DS2THR'
|
||||
))
|
||||
then
|
||||
do;
|
||||
@@ -687,6 +700,9 @@ run;
|
||||
%let notesSourceOptions = %sysfunc(getoption(notes)) %sysfunc(getoption(source));
|
||||
options NOnotes NOsource;
|
||||
|
||||
options mprint;
|
||||
options notes source;
|
||||
|
||||
proc sort data = &filesWithCodes.;
|
||||
by order type file;
|
||||
run;
|
||||
@@ -793,7 +809,7 @@ run;
|
||||
/* code inspired by Kurt Bremser's "Talking to Your Host" article */
|
||||
/* https://communities.sas.com/t5/SAS-User-Groups-Library/WUSS-Presentation-Talking-to-Your-Host/ta-p/838344 */
|
||||
/* WUSS 2022 */
|
||||
|
||||
|
||||
data &filesWithCodes.addCnt;
|
||||
run;
|
||||
|
||||
@@ -855,9 +871,12 @@ title6 "MD5 hashed fileref of package lowcase name: &_PackageFileref_.";
|
||||
title8 "Required SAS packages: %qsysfunc(compress(%superq(packageReqPackages),%str(%'%")))" ; /* " */
|
||||
%end;
|
||||
|
||||
footnote1 "SAS Packages Framework, version 20240711";
|
||||
footnote1 "SAS Packages Framework, version 20241207";
|
||||
|
||||
proc print data = &filesWithCodes.(drop=base folderRef fileRef rc folderid _abort_ fileId additionalContent);
|
||||
proc print
|
||||
data = &filesWithCodes.(drop=base folderRef fileRef rc folderid _abort_ fileId additionalContent)
|
||||
width=full
|
||||
;
|
||||
run;
|
||||
title;
|
||||
|
||||
@@ -876,7 +895,7 @@ title;
|
||||
title2 "Package additional content:";
|
||||
proc print
|
||||
data=&filesWithCodes.addCnt(drop=root dir level)
|
||||
label
|
||||
label width=full
|
||||
;
|
||||
run;
|
||||
%end;
|
||||
@@ -1029,22 +1048,35 @@ data _null_;
|
||||
put ' filename &_PackageFileref_. clear; ';
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
put ' %local rV pV; ';
|
||||
put ' %let pV = %sysfunc(compress(&packageVersion.,.,kd)); ';
|
||||
put ' %let pV = %sysevalf((%scan(&pV.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&pV.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&pV.,3,.,M)+0)*1e0); ';
|
||||
put ' %let rV = %sysfunc(compress(&requiredVersion.,.,kd)); ';
|
||||
put ' %let rV = %sysevalf((%scan(&rV.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&rV.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&rV.,3,.,M)+0)*1e0); ';
|
||||
put ' %if %sysevalf(&requiredVersion. > &packageVersion.) %then ';
|
||||
put ' %do; ';
|
||||
put ' %put ERROR: Required version is &requiredVersion.; ';
|
||||
put ' %put ERROR- Provided version is &packageVersion.; ';
|
||||
put ' %GOTO WrongVersionOFPackage; /*%RETURN;*/ ';
|
||||
put ' %local rV pV rV0 pV0 rVsign; ';
|
||||
put ' %let pV0 = %sysfunc(compress(&packageVersion.,.,kd)); ';
|
||||
put ' %let pV = %sysevalf((%scan(&pV0.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&pV0.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&pV0.,3,.,M)+0)*1e0); ';
|
||||
put ' ';
|
||||
put ' %let rV0 = %sysfunc(compress(&requiredVersion.,.,kd)); ';
|
||||
put ' %let rVsign = %sysfunc(compress(&requiredVersion.,<=>,k)); ';
|
||||
put ' %if %superq(rVsign)= %then %let rVsign=<=; ';
|
||||
put ' %else %if NOT (%superq(rVsign) IN (%str(=) %str(<=) %str(=<) %str(=>) %str(>=) %str(<) %str(>))) %then ';
|
||||
put ' %do; ';
|
||||
put ' %put WARNING: Illegal operatopr "%superq(rVsign)"! Default(<=) will be used.; ';
|
||||
put ' %put WARNING- Supported operators are: %str(= <= =< => >= < >); ';
|
||||
put ' %let rVsign=<=; ';
|
||||
put ' %end; ';
|
||||
put ' %let rV = %sysevalf((%scan(&rV0.,1,.,M)+0)*1e8 ';
|
||||
put ' + (%scan(&rV0.,2,.,M)+0)*1e4 ';
|
||||
put ' + (%scan(&rV0.,3,.,M)+0)*1e0); ';
|
||||
put ' ';
|
||||
put ' %if NOT %sysevalf(&rV. &rVsign. &pV.) %then ';
|
||||
put ' %do; ';
|
||||
put ' %put ERROR: Package &packageName. will not be loaded!; ';
|
||||
put ' %put ERROR- Required version is &rV0.; ';
|
||||
put ' %put ERROR- Provided version is &pV0.; ';
|
||||
put ' %put ERROR- Condition %bquote((&rV0. &rVsign. &pV0.)) evaluates to %sysevalf(&rV. &rVsign. &pV.); ';
|
||||
put ' %put ERROR- Verify installed version of the package.; ';
|
||||
put ' %put ERROR- ; ';
|
||||
put ' %GOTO WrongVersionOFPackage; /*%RETURN;*/ ';
|
||||
put ' %end; ';
|
||||
|
||||
|
||||
put ' filename &_PackageFileref_. &ZIP. ';
|
||||
put ' "&path./%lowcase(&packageName.).&zip." %unquote(&options.) ';
|
||||
@@ -1111,6 +1143,8 @@ data _null_;
|
||||
isProto = 0;
|
||||
isIMLmodule = 0;
|
||||
isCASLudf = 0;
|
||||
isDS2pck = 0;
|
||||
isDS2thr = 0;
|
||||
|
||||
%if (%superq(packageRequired) ne )
|
||||
or (%superq(packageReqPackages) ne )
|
||||
@@ -1350,7 +1384,7 @@ data _null_;
|
||||
('LIBNAME' 'MACRO' /*'MACROS'*/ 'DATA'
|
||||
'FUNCTION' /*'FUNCTIONS'*/ 'FORMAT' /*'FORMATS'*/
|
||||
'IMLMODULE' 'PROTO' 'EXEC' 'CLEAN'
|
||||
'LAZYDATA' 'TEST' 'ADDCNT' 'KMFSNIP'))
|
||||
'LAZYDATA' 'TEST' 'ADDCNT' 'KMFSNIP' 'DS2PCK' 'DS2THR'))
|
||||
then
|
||||
do;
|
||||
putlog 'WARNING: Type ' type 'is not yet supported.';
|
||||
@@ -1361,8 +1395,11 @@ data _null_;
|
||||
isFormat + (upcase(type)=:'FORMAT');
|
||||
isProto + (upcase(type)=:'PROTO');
|
||||
isIMLmodule + (upcase(type)=:'IMLMODULE');
|
||||
isDS2pck + (upcase(type)=:'DS2PCK');
|
||||
isDS2thr + (upcase(type)=:'DS2THR');
|
||||
|
||||
/* HEADERS for IML, FCMP, and PROTO - start */
|
||||
|
||||
/* HEADERS for PROC IML, FCMP, and PROTO - start */
|
||||
if 1 = isFunction and upcase(type)=:'FUNCTION' then
|
||||
do;
|
||||
/* macro variable for test if cherry picking used FCMP */
|
||||
@@ -1420,7 +1457,7 @@ data _null_;
|
||||
/* header, for IML modules */
|
||||
put "proc iml ; ";
|
||||
end;
|
||||
/* HEADERS for IML, FCMP, and PROTO - end */
|
||||
/* HEADERS for PROC IML, FCMP, and PROTO - end */
|
||||
|
||||
put ' ' /
|
||||
'%if (%str(*)=%superq(cherryPick)) or (' fileshort +(-1) ' in %superq(cherryPick)) %then %do; '; /* Cherry Pick test1 start */
|
||||
@@ -1431,6 +1468,8 @@ data _null_;
|
||||
put ' %put %sysfunc(ifc(%SYSMACEXIST(' fileshort +(-1) ')=1, NOTE# Macro ' fileshort
|
||||
"exist. It will be overwritten by the macro from the &packageName. package, ));";
|
||||
|
||||
|
||||
/* separate approach for EXEC */
|
||||
if upcase(type)=:'EXEC' then
|
||||
do;
|
||||
/* User can suppress running the exec files */
|
||||
@@ -1453,9 +1492,84 @@ data _null_;
|
||||
/ ' )));'
|
||||
;
|
||||
end;
|
||||
else
|
||||
/* separate approach for DS2 */
|
||||
else if (upcase(type) in: ('DS2PCK' 'DS2THR')) then
|
||||
do;
|
||||
/* include the file with the code of the element */
|
||||
if 1 = isDS2pck and upcase(type)=:'DS2PCK' then
|
||||
do;
|
||||
/* macro variable for test if cherry picking used DS2 package */
|
||||
put 'data _null_; ';
|
||||
put " call symputX('cherryPick_DS2PCK', 0, 'L'); ";
|
||||
put 'run; ';
|
||||
end;
|
||||
if 1 = isDS2thr and upcase(type)=:'DS2THR' then
|
||||
do;
|
||||
/* macro variable for test if cherry picking used DS2 threads */
|
||||
put 'data _null_; ';
|
||||
put " call symputX('cherryPick_DS2THR', 0, 'L'); ";
|
||||
put 'run; ';
|
||||
end;
|
||||
|
||||
|
||||
/* since DS2 packages and threads are stored in SAS data sets */
|
||||
/* we have to check (before loading) if there is no "regular" */
|
||||
/* data set (or view) with the same name to avoid overwriting */
|
||||
if upcase(type) in: ('DS2PCK' 'DS2THR') then
|
||||
do;
|
||||
length DS2lib $ 8 DS2ds $ 32;
|
||||
DS2lib = coalescec(scan(fileshort,-2,"."), "WORK");
|
||||
DS2ds = scan(fileshort,-1,".");
|
||||
|
||||
put '%put %sysfunc(ifc(%sysfunc(exist(' fileshort +(-1) '))=1,'
|
||||
/ '%sysfunc(dosubl(%str(options ps=min; title; options msglevel=n nodate notes source nomprint;'
|
||||
/ ' data _null_;'
|
||||
/ ' id = OPEN("' fileshort +(-1) '");'
|
||||
/ ' if id then do;'
|
||||
/ ' x = VARNUM(id, "SAS_CHECKSUM_") AND VARNUM(id, "SAS_ROWID_") AND (VARNUM(id, "SAS_TEXTTHREAD_") OR VARNUM(id, "SAS_TEXTPACKAGE_"));'
|
||||
/ ' y = ("DATA"=ATTRC(id, "MTYPE"));'
|
||||
/ ' if symexist("DS2force") then z = symgetn("DS2force"); else z = 0;'
|
||||
/ ' if (x AND y) OR z then do;'
|
||||
/ ' call execute("proc delete data=' fileshort +(-1) '; run;");'
|
||||
/ " put 'NOTE# The " fileshort "will be overwritten by the PROC DS2 package/thread from the &packageName. package.';"
|
||||
|
||||
/* header for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' call execute("proc ds2;");'
|
||||
|
||||
/ ' call execute(''%include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;'');'
|
||||
|
||||
/* footer for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' call execute("run; quit;");'
|
||||
/ ' call execute("options nonotes; proc datasets lib=' DS2lib 'noprint;");'
|
||||
/ " call execute('modify " DS2ds "(label=""Package: &packageName. ; Type: " type "; Name: " fileshort """);');"
|
||||
/ ' call execute("run; quit;");'
|
||||
/ ' end;'
|
||||
/ ' else put "WARNING: Data set ' fileshort 'exist and is not a PROC DS2 package/thread!"'
|
||||
/ ' / "WARNING- PROC DS2 package/thread ' fileshort 'will not be generated..."; '
|
||||
/ ' id = CLOSE(id);'
|
||||
/ ' end;'
|
||||
/ ' run;))),'
|
||||
/ '%sysfunc(dosubl(%str(options ps=min; title; options msglevel=n nodate notes source nomprint;'
|
||||
/* header for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' proc ds2;'
|
||||
|
||||
/ ' %include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;'
|
||||
|
||||
/* footer for each DS2 packages or threads in PROC DS2 run */
|
||||
/ ' run; quit;'
|
||||
/ ' options nonotes; proc datasets lib=' DS2lib 'noprint;'
|
||||
/ " modify " DS2ds "(label=""Package: &packageName. ; Type: " type "; Name: " fileshort """);"
|
||||
/ ' run; quit;'
|
||||
/ '))),'
|
||||
/ '));'
|
||||
/ " "
|
||||
/ ;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
else
|
||||
do;
|
||||
/* include the file with the code of the element, all other cases */
|
||||
put ' %include' " &_PackageFileref_.(_" folder +(-1) "." file +(-1) ') / nosource2;';
|
||||
end;
|
||||
|
||||
@@ -1471,13 +1585,19 @@ data _null_;
|
||||
if upcase(type)=:'FORMAT' then
|
||||
put ' %let cherryPick_FORMAT = %eval(&cherryPick_FORMAT. + 1);';
|
||||
|
||||
if upcase(type)=:'DS2PCK' then
|
||||
put ' %let cherryPick_DS2PCK = %eval(&cherryPick_DS2PCK. + 1);';
|
||||
|
||||
if upcase(type)=:'DS2THR' then
|
||||
put ' %let cherryPick_DS2THR = %eval(&cherryPick_DS2THR. + 1);';
|
||||
|
||||
put '%end; ' /; /* Cherry Pick test1 end */
|
||||
|
||||
|
||||
/* FOOTERS for IML, FCMP, and PROTO - start */
|
||||
/* FOOTERS for PROC IML, FCMP, and PROTO - start */
|
||||
if 1 = LAST.type and upcase(type) in ('FUNCTIONS' 'PROTO' 'FORMATS') then
|
||||
do; /* footer, for multiple functions in one FCMP run, one PROTO run, or one FORMAT run */
|
||||
put "run; " / ;
|
||||
put "quit; " / ;
|
||||
end;
|
||||
if 1 = LAST.type and upcase(type)='IMLMODULE' then /* footer, for IML modules */
|
||||
do;
|
||||
@@ -1488,7 +1608,7 @@ data _null_;
|
||||
'%end; ' /
|
||||
"quit; " / ;
|
||||
end;
|
||||
/* FOOTERS for IML, FCMP, and PROTO - end */
|
||||
/* FOOTERS for PROC IML, FCMP, and PROTO - end */
|
||||
|
||||
/* add the link to the functions dataset, only for the first occurrence */
|
||||
/*if 1 = isFunction and (upcase(type)=:'FUNCTION') then
|
||||
@@ -1576,7 +1696,7 @@ data _null_;
|
||||
%end;
|
||||
put +(-1) '`.;''' /
|
||||
' !! '' %put The macro generated: '' !! put(dtCASLudf, E8601DT19.-L) !! ";"' /
|
||||
' !! '' %put with the SAS Packages Framework version 20240711.;''' /
|
||||
' !! '' %put with the SAS Packages Framework version 20241207.;''' /
|
||||
' !! '' %put ****************************************************************************;''' /
|
||||
' !! '' %GOTO theEndOfTheMacro;''' /
|
||||
' !! '' %end;''' ;
|
||||
@@ -1741,7 +1861,7 @@ data _null_;
|
||||
%end;
|
||||
put +(-1) '`.; '' !!' /
|
||||
''' %put The macro generated: ''' " !! put(dtIML, E8601DT19.-L) !! " '''; '' !!' /
|
||||
''' %put with the SAS Packages Framework version 20240711.; '' !! ' /
|
||||
''' %put with the SAS Packages Framework version 20241207.; '' !! ' /
|
||||
''' %put ****************************************************************************; '' !! ' /
|
||||
''' %GOTO theEndOfTheMacro; '' !! ' /
|
||||
''' %end; '' !! ' /
|
||||
@@ -2256,15 +2376,33 @@ data _null_;
|
||||
/* put 'remove module = ' fileshort ';'; */
|
||||
end;
|
||||
|
||||
/* delete datasets */
|
||||
put "proc sql noprint;";
|
||||
/* delete data sets */
|
||||
put "proc SQL noprint;";
|
||||
EOF = 0;
|
||||
do until(EOF);
|
||||
set &filesWithCodes. end = EOF;
|
||||
if not (upcase(type)=:'DATA') then continue;
|
||||
if not (upcase(type) in: ('DATA')) then continue;
|
||||
put '%put NOTE- Element of type ' type 'generated from the file "' file +(-1) '" will be deleted;';
|
||||
put '%put NOTE- ;';
|
||||
put 'drop table ' fileshort ';' /;
|
||||
put '%sysfunc(ifc(%sysfunc(exist(' fileshort ')),drop table ' fileshort ',));' /;
|
||||
end;
|
||||
put "quit;" /;
|
||||
|
||||
/* delete PROC DS2 packages or threads */
|
||||
put 'data _null_; call symputx("_DS2_2_del_",0,"L"); run;';
|
||||
put "proc SQL noprint;";
|
||||
EOF = 0;
|
||||
do until(EOF);
|
||||
set &filesWithCodes. end = EOF;
|
||||
if not (upcase(type) in: ('DS2PCK' 'DS2THR')) then continue;
|
||||
put '%put NOTE- Element of type ' type 'generated from the file "' file +(-1) '" will be deleted;'
|
||||
/ '%put NOTE- ;'
|
||||
/ '%let _DS2_2_del_ = %sysfunc(open(' fileshort '));'
|
||||
/ '%sysfunc(ifc(&_DS2_2_del_. AND %sysfunc(ATTRC(&_DS2_2_del_.,LABEL))='
|
||||
/ '%str(' "Package: &packageName. ; Type: " type "; Name: " fileshort +(-1) '),drop table ' fileshort ',)) '
|
||||
/ '%let _DS2_2_del_ = %sysfunc(close(&_DS2_2_del_.));'
|
||||
;
|
||||
put ';' /; /* this is semicolon closing drop table statement */
|
||||
end;
|
||||
put "quit;" /;
|
||||
|
||||
@@ -2392,12 +2530,13 @@ data _null_;
|
||||
|
||||
length fileshort2 $ 256;
|
||||
select;
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'");
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'" );
|
||||
when (upcase(type) =: "FUNCTION" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "IMLMODULE" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "PROTO" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "FORMAT" ) fileshort2 = cats("'$", fileshort, ".'" );
|
||||
when (upcase(type) in ('DS2PCK' 'DS2THR')) fileshort2 = cats("'DS2", fileshort, "'" );
|
||||
otherwise fileshort2 = fileshort;
|
||||
end;
|
||||
strX = catx('/', folder, order, type, file, fileshort, fileshort2);
|
||||
@@ -2529,7 +2668,7 @@ data _null_;
|
||||
%end;
|
||||
|
||||
put 'put " " / @3 "--------------------------------------------------------------------" / " ";'
|
||||
/ 'put @3 "*SAS package generated by SAS Package Framework, version `20240711`*";'
|
||||
/ 'put @3 "*SAS package generated by SAS Package Framework, version `20241207`*";'
|
||||
/ 'put " " / @3 "--------------------------------------------------------------------";';
|
||||
|
||||
put 'run; ' /;
|
||||
@@ -2568,13 +2707,14 @@ data _null_;
|
||||
|
||||
length fileshort2 $ 256;
|
||||
select;
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'");
|
||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = cats("'", fileshort, "'" );
|
||||
when (upcase(type) =: "MACRO" ) fileshort2 = cats('''%', fileshort, "()'" );
|
||||
when (upcase(type) =: "FUNCTION" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "IMLMODULE" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "PROTO" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) =: "FORMAT" ) fileshort2 = cats("'$", fileshort, ".'" );
|
||||
when (upcase(type) =: "CASLUDF" ) fileshort2 = cats("'", fileshort, "()'" );
|
||||
when (upcase(type) in ('DS2PCK' 'DS2THR')) fileshort2 = cats("'DS2", fileshort, "'" );
|
||||
otherwise fileshort2 = fileshort;
|
||||
end;
|
||||
strX = catx('/', folder, order, type, file, fileshort, fileshort2);
|
||||
@@ -3057,7 +3197,7 @@ run;
|
||||
|
||||
%if %Qupcase(&sascfgFile.) = DEF %then /* the DEF value points to the sasv9.cfg file in the sasroot directory */
|
||||
%do;
|
||||
%let SASCONFIG = -config ""&SASROOT./sasv9.cfg"";
|
||||
%let SASCONFIG = -config "&SASROOT./sasv9.cfg";
|
||||
%put NOTE: The following SAS config file will be used:;
|
||||
%put NOTE- &=SASCONFIG.;
|
||||
%end;
|
||||
@@ -3065,7 +3205,7 @@ run;
|
||||
%do;
|
||||
%if %sysfunc(fileexist(&sascfgFile.)) %then
|
||||
%do;
|
||||
%let SASCONFIG = -config ""&SASCFGFILE."";
|
||||
%let SASCONFIG = -config "&SASCFGFILE.";
|
||||
%put NOTE: The following SAS config file will be used:;
|
||||
%put NOTE- &=SASCONFIG.;
|
||||
%end;
|
||||
@@ -3566,7 +3706,7 @@ data &filesWithCodes.markdown;
|
||||
%end;
|
||||
|
||||
put " " / "--------------------------------------------------------------------" / " "
|
||||
/ "*SAS package generated by SAS Package Framework, version `20240711`*"
|
||||
/ "*SAS package generated by SAS Package Framework, version `20241207`*"
|
||||
/ " " / "--------------------------------------------------------------------" / " ";
|
||||
|
||||
put "# The `&packageName.` package content";
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to get help about SAS package, version 20240711. Run %helpPackage() for help info.'
|
||||
des = 'Macro to get help about SAS package, version 20241207. Run %helpPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -43,7 +43,7 @@ des = 'Macro to get help about SAS package, version 20240711. Run %helpPackage()
|
||||
%put ### This is short help information for the `helpPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to get help about SAS packages, version `20240711` #;
|
||||
%put # Macro to get help about SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -120,14 +120,15 @@ des = 'Macro to get help about SAS package, version 20240711. Run %helpPackage()
|
||||
%end;
|
||||
|
||||
/* local variables for options */
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp mautocomploc_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));
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N NOmautocomploc;
|
||||
|
||||
%local _PackageFileref_;
|
||||
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
|
||||
@@ -170,7 +171,8 @@ des = 'Macro to get help about SAS package, version 20240711. Run %helpPackage()
|
||||
%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.;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.
|
||||
msglevel = &msglevel_tmp. &mautocomploc_tmp.;
|
||||
|
||||
%ENDofhelpPackage:
|
||||
%mend helpPackage;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*+installPackage+*/
|
||||
/* Macros to install SAS packages, version 20240711 */
|
||||
/* Macros to install SAS packages, version 20241207 */
|
||||
/* A SAS package is a zip file containing a group of files
|
||||
with SAS code (macros, functions, data steps generating
|
||||
data, etc.) wrapped up together and %INCLUDEed by
|
||||
@@ -18,11 +18,14 @@
|
||||
, URLoptions = /* options for the `sourcePath` URLs */
|
||||
, loadAddCnt=0 /* should the additional content be loaded?
|
||||
default is 0 - means No, 1 means Yes */
|
||||
, instDoc=0 /* should the markdown file with documentation be installed?
|
||||
default is 0 - means No, 1 means Yes */
|
||||
, SFRCVN = /* name of a macro variable to store success-failure return code value */
|
||||
)
|
||||
/secure
|
||||
minoperator
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to install SAS package, version 20240711. Run %%installPackage() for help info.'
|
||||
des = 'Macro to install SAS package, version 20241207. Run %%installPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
|
||||
%do;
|
||||
@@ -37,7 +40,7 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%put ### This is short help information for the `installPackage` macro #;
|
||||
%put #--------------------------------------------------------------------------------------------#;;
|
||||
%put # #;
|
||||
%put # Macro to install SAS packages, version `20240711` #;
|
||||
%put # Macro to install SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -81,7 +84,7 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%put # - `version=` Indicates which historical version of a package to install. #;
|
||||
%put # Historical version are available only if `mirror=0` is set. #;
|
||||
%put # Default value is null which means "install the latest". #;
|
||||
%put # When there are multiple packages to install version #;
|
||||
%put # When there are multiple packages to install version variable #;
|
||||
%put # is scan sequentially. #;
|
||||
%put # #;
|
||||
%put # - `replace=` With default value of `1` it causes existing package file #;
|
||||
@@ -101,6 +104,16 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%put # directory in `<packageName>_AdditionalContent` folder. #;
|
||||
%put # For other locations use `%nrstr(%%loadPackageAddCnt())` macro. #;
|
||||
%put # #;
|
||||
%put # - `instDoc=` *Optional.* A package may be provided with a markdown file #;
|
||||
%put # containing combined documentation of the package. The option #;
|
||||
%put # indicates if the `.md` file should be also downloaded. #;
|
||||
%put # Default value of zero (`0`) means "No", one (`1`) means "Yes". #;
|
||||
%put # #;
|
||||
%put # - `SFRCVN=` *Optional.* Provides a NAME for a macro variable to store value of the #;
|
||||
%put # *success-failure return code* of the installation process. Return value #;
|
||||
%put # has the following form: `<number of successes>.<number of failures>` #;
|
||||
%put # The macro variable is created as a *global* macro variable. #;
|
||||
%put # #;
|
||||
%put #--------------------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #;
|
||||
@@ -149,7 +162,7 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%end;
|
||||
|
||||
/* local variables for options */
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp mautocomploc_tmp;
|
||||
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
@@ -158,8 +171,9 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N NOmautocomploc;
|
||||
|
||||
/*
|
||||
Reference:
|
||||
@@ -175,30 +189,39 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
call symputX("firstPackagesPath", pathname("packages"), "L");
|
||||
run;
|
||||
|
||||
%let loadAddCnt = %sysevalf(NOT(0=%superq(loadAddCnt)));
|
||||
%let instDoc = %sysevalf(NOT(0=%superq(instDoc)));
|
||||
|
||||
%let replace = %sysevalf(1=%superq(replace));
|
||||
|
||||
%if %superq(sourcePath)= %then
|
||||
%do;
|
||||
%local SPFinitMirror;
|
||||
%local SPFinitMirror SPFinitMirrorMD;
|
||||
/* the defaults are: */
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.md;
|
||||
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/packages/;
|
||||
|
||||
%if 0 = %superq(mirror) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.md;
|
||||
%let sourcePath = https://github.com/SASPAC/; /*usercontent*/
|
||||
%goto mirrorEnd;
|
||||
%end;
|
||||
|
||||
%if 1 = %superq(mirror) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.md;
|
||||
%let sourcePath = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/packages/;
|
||||
%goto mirrorEnd;
|
||||
%end;
|
||||
|
||||
%if 2 = %superq(mirror) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/SPF/SPFinit.md;
|
||||
%let sourcePath = https://pages.mini.pw.edu.pl/~jablonskib/SASpublic/SAS_PACKAGES/packages/;
|
||||
%goto mirrorEnd;
|
||||
%end;
|
||||
@@ -208,7 +231,8 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%else
|
||||
%do;
|
||||
%let mirror=-1;
|
||||
%let SPFinitMirror = &sourcePath.SPFinit.sas;
|
||||
%let SPFinitMirror = &sourcePath.SPFinit.sas;
|
||||
%let SPFinitMirrorMD = &sourcePath.SPFinit.md;
|
||||
%end;
|
||||
|
||||
%local i str;
|
||||
@@ -233,6 +257,10 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%put ;
|
||||
%put INFO: Calling: &packagesNames.;
|
||||
|
||||
%Local PackagesInstalledSussess PackagesInstalledFail;
|
||||
%Let PackagesInstalledSussess=;
|
||||
%let PackagesInstalledFail=;
|
||||
|
||||
%do i = 1 %to %sysfunc(countw(&packagesNames., , S));
|
||||
/*-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-*/
|
||||
%local packageName packageSubDir vers versA versB;
|
||||
@@ -251,10 +279,13 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%put ### &packageName.(&vers.) ###;
|
||||
|
||||
%put *** %lowcase(&packageName.) start *****************************************;
|
||||
%local in out _IOFileref_;
|
||||
%local in out inMD outMD _IOFileref_;
|
||||
data _null_; call symputX("_IOFileref_", put(MD5("%lowcase(&packageName.)"), hex7. -L), "L"); run;
|
||||
%let in = i&_IOFileref_.;
|
||||
%let out = o&_IOFileref_.;
|
||||
%let inMD = j&_IOFileref_.;
|
||||
%let outMD = u&_IOFileref_.;
|
||||
|
||||
/* %let in = i%sysfunc(md5(&packageName.),hex7.); */
|
||||
/* %let out = o%sysfunc(md5(&packageName.),hex7.); */
|
||||
|
||||
@@ -264,15 +295,27 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
/* allows to install/download the framework file like any other package */
|
||||
%if %superq(mirror) in (0 1) AND (%superq(vers) ne) %then
|
||||
%do;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/&vers./SPF/SPFinit.sas;
|
||||
%let SPFinitMirror = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/&vers./SPF/SPFinit.sas;
|
||||
%let SPFinitMirrorMD = https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/&vers./SPF/SPFinit.md;
|
||||
%end;
|
||||
|
||||
filename &in URL
|
||||
%if %superq(mirror) > 1 %then
|
||||
%put %str( )Mirror %superq(mirror) does not support versioning.;
|
||||
|
||||
/* source code file */
|
||||
filename &in. URL
|
||||
"&SPFinitMirror."
|
||||
recfm=N lrecl=1;
|
||||
filename &out
|
||||
filename &out.
|
||||
"&firstPackagesPath./SPFinit.sas"
|
||||
recfm=N lrecl=1;
|
||||
|
||||
/* documentation MD file */
|
||||
filename &inMD. URL
|
||||
"&SPFinitMirrorMD."
|
||||
recfm=N lrecl=1;
|
||||
filename &outMD.
|
||||
"&firstPackagesPath./SPFinit.md"
|
||||
recfm=N lrecl=1;
|
||||
%end;
|
||||
%else
|
||||
%do;
|
||||
@@ -286,7 +329,14 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%let packageSubDir = %lowcase(&packageName.)/raw/&vers./;
|
||||
%end;
|
||||
%end;
|
||||
filename &in URL "&sourcePath.&packageSubDir.%lowcase(&packageName.).zip"
|
||||
%else
|
||||
%do;
|
||||
%if %superq(mirror) > 0 %then
|
||||
%put %str( )Mirror %superq(mirror) does not support versioning.;
|
||||
%end;
|
||||
|
||||
/* zip */
|
||||
filename &in. URL "&sourcePath.&packageSubDir.%lowcase(&packageName.).zip"
|
||||
%if (%superq(URLuser) ne ) %then
|
||||
%do;
|
||||
user = "&URLuser."
|
||||
@@ -294,7 +344,17 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%end;
|
||||
&URLoptions.
|
||||
recfm=N lrecl=1;
|
||||
filename &out "&firstPackagesPath./%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
filename &out. "&firstPackagesPath./%lowcase(&packageName.).zip" recfm=N lrecl=1;
|
||||
/* markdown */
|
||||
filename &inMD. URL "&sourcePath.&packageSubDir.%lowcase(&packageName.).md"
|
||||
%if (%superq(URLuser) ne ) %then
|
||||
%do;
|
||||
user = "&URLuser."
|
||||
pass = "&URLuser."
|
||||
%end;
|
||||
&URLoptions.
|
||||
recfm=N lrecl=1;
|
||||
filename &outMD. "&firstPackagesPath./%lowcase(&packageName.).md" recfm=N lrecl=1;
|
||||
%end;
|
||||
/*
|
||||
filename in list;
|
||||
@@ -304,12 +364,21 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%local installationRC;
|
||||
%let installationRC=1;
|
||||
data _null_;
|
||||
length filein 8 out_path in_path $ 4096;
|
||||
length filein fileinMD 8
|
||||
out_path in_path out_pathMD in_pathMD rcTXT $ 4096
|
||||
out_ref in_ref out_refMD in_refMD $ 8
|
||||
;
|
||||
out_path = pathname ("&out");
|
||||
in_path = pathname ("&in" );
|
||||
out_pathMD = pathname ("&outMD");
|
||||
in_pathMD = pathname ("&inMD" );
|
||||
out_ref = symget ("out");
|
||||
in_ref = symget ("in" );
|
||||
out_refMD = symget ("outMD");
|
||||
in_refMD = symget ("inMD" );
|
||||
rcTXT=' ';
|
||||
|
||||
|
||||
filein = fopen( "&in", 'S', 1, 'B');
|
||||
filein = fopen(in_ref, 'S', 1, 'B');
|
||||
if filein = 0 then
|
||||
put "ERROR: Source file:" /
|
||||
"ERROR- " in_path /
|
||||
@@ -329,21 +398,23 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
rc = FCLOSE(filein);
|
||||
put;
|
||||
|
||||
if FEXIST("&out") = 0 then
|
||||
if FEXIST(out_ref) = 0 then
|
||||
do;
|
||||
put @2 "Installing the &packageName. package"
|
||||
/ @2 "in the &firstPackagesPath. directory.";
|
||||
rc = FCOPY("&in", "&out");
|
||||
rc = FCOPY(in_ref, out_ref);
|
||||
rcTXT=sysmsg();
|
||||
end;
|
||||
else if FEXIST("&out") = 1 then
|
||||
else if FEXIST(out_ref) = 1 then
|
||||
do;
|
||||
if symgetn("replace")=1 then
|
||||
do;
|
||||
put @2 "The following file will be replaced during "
|
||||
/ @2 "installation of the &packageName. package: "
|
||||
/ @5 out_path;
|
||||
rc = FDELETE("&out");
|
||||
rc = FCOPY("&in", "&out");
|
||||
rc = FDELETE(out_ref);
|
||||
rc = FCOPY(in_ref, out_ref);
|
||||
rcTXT=sysmsg();
|
||||
end;
|
||||
else
|
||||
do;
|
||||
@@ -352,13 +423,56 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
rc = 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
put @2 "Done with return code " rc= "(zero = success)";
|
||||
put @2 "Done with return code " rc= "(zero = success)" / rcTXT;
|
||||
call symputX("installationRC", rc, "L");
|
||||
|
||||
/* try to install documentation file */
|
||||
if 1=symgetn("instDoc") then
|
||||
do;
|
||||
fileinMD = fopen(in_refMD, 'S', 1, 'B');
|
||||
rcMD = FCLOSE(fileinMD);
|
||||
|
||||
if fileinMD then
|
||||
do;
|
||||
if 0=FEXIST(out_refMD) then
|
||||
do;
|
||||
rcMD = FCOPY(in_refMD, out_refMD);
|
||||
if rcMD=0 then
|
||||
put @2 "Package documentation installed on request." ; /* / out_pathMD / in_pathMD; */
|
||||
end;
|
||||
else if 1=FEXIST(out_refMD) and 1=symgetn("replace") then
|
||||
do;
|
||||
rcMD = FDELETE(out_refMD);
|
||||
if rcMD=0 then
|
||||
rcMD2 = FCOPY(in_refMD, out_refMD);
|
||||
if rcMD=0 AND rcMD2=0 then
|
||||
put @2 "Package documentation installed on demand." ; /* / out_pathMD / in_pathMD; */
|
||||
end;
|
||||
end;
|
||||
else
|
||||
put @2 "Package documentation in markdown format not available." ; /* / out_pathMD / in_pathMD;*/
|
||||
end;
|
||||
run;
|
||||
|
||||
filename &in clear;
|
||||
filename &out clear;
|
||||
filename &in. clear;
|
||||
filename &out. clear;
|
||||
filename &inMD. clear;
|
||||
filename &outMD. clear;
|
||||
|
||||
%if 0 = &installationRC. %then
|
||||
%do;
|
||||
%if %superq(vers)= %then
|
||||
%Let PackagesInstalledSussess=&PackagesInstalledSussess. &packageName.;
|
||||
%else
|
||||
%Let PackagesInstalledSussess=&PackagesInstalledSussess. &packageName.(&vers.);
|
||||
%end;
|
||||
%else
|
||||
%do;
|
||||
%if %superq(vers)= %then
|
||||
%Let PackagesInstalledFail=&PackagesInstalledFail. &packageName.;
|
||||
%else
|
||||
%let PackagesInstalledFail=&PackagesInstalledFail. &packageName.(&vers.);
|
||||
%end;
|
||||
|
||||
%if 1 = &loadAddCnt.
|
||||
AND 0 = &installationRC.
|
||||
@@ -375,14 +489,60 @@ des = 'Macro to install SAS package, version 20240711. Run %%installPackage() fo
|
||||
%put *** %lowcase(&packageName.) end *******************************************;
|
||||
/*-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-*/
|
||||
%end;
|
||||
|
||||
|
||||
%local sucsCount sucsCountWords;
|
||||
%let sucsCount=0;
|
||||
%if NOT(%superq(PackagesInstalledSussess)=) %then
|
||||
%do;
|
||||
%put %str( );
|
||||
%let sucsCount=%sysfunc(countw(%superq(PackagesInstalledSussess),%str( )));
|
||||
%if 1=&sucsCount. %then
|
||||
%put INFO: Package %superq(PackagesInstalledSussess) installed.;
|
||||
%else %if 1<&sucsCount. %then
|
||||
%do;
|
||||
%let sucsCountWords=%sysfunc(abs(&sucsCount.),words.);
|
||||
%put INFO: Successfully installed &sucsCountWords. packages:;
|
||||
%put %str( )&PackagesInstalledSussess.;
|
||||
%end;
|
||||
%end;
|
||||
|
||||
%local failCount failCountWords;
|
||||
%let failCount=0;
|
||||
%if NOT(%superq(PackagesInstalledFail)=) %then
|
||||
%do;
|
||||
%put %str( );
|
||||
%let failCount=%sysfunc(countw(%superq(PackagesInstalledFail),%str( )));
|
||||
%if 1=&failCount. %then
|
||||
%put WARNING: Failed to install %superq(PackagesInstalledFail) package.;
|
||||
%else %if 1<&failCount. %then
|
||||
%do;
|
||||
%let failCountWords=%sysfunc(abs(&failCount.),words.);
|
||||
%put WARNING: Failed to install &failCountWords. packages:;
|
||||
%put WARNING- &PackagesInstalledFail.;
|
||||
%end;
|
||||
%end;
|
||||
%put %str( );
|
||||
|
||||
%if NOT(%superq(SFRCVN)=) %then
|
||||
%do;
|
||||
data _null_;
|
||||
length SFRCVN $ 32;
|
||||
SFRCVN = compress(symget('SFRCVN'),"_","KAD");
|
||||
value = "&sucsCount..&failCount.";
|
||||
put 'INFO: Success-Failure-Return-Code macroVariable Name is: ' SFRCVN
|
||||
/ ' with value: ' value
|
||||
/ ;
|
||||
call symputX(SFRCVN, value, "G");
|
||||
run;
|
||||
%end;
|
||||
|
||||
%packagesListError:
|
||||
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
|
||||
msglevel=&msglevel_tmp. &mautocomploc_tmp.;
|
||||
%ENDofinstallPackage:
|
||||
%mend installPackage;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Macro to list SAS packages in packages folder.
|
||||
|
||||
Version 20240711
|
||||
Version 20241207
|
||||
|
||||
A SAS package is a zip file containing a group
|
||||
of SAS codes (macros, functions, data steps generating
|
||||
@@ -21,8 +21,9 @@
|
||||
*//*** HELP END ***/
|
||||
|
||||
|
||||
%macro listPackages()/secure PARMBUFF
|
||||
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20240711.'
|
||||
%macro listPackages()
|
||||
/secure PARMBUFF
|
||||
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20241207.'
|
||||
;
|
||||
%if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then
|
||||
%do;
|
||||
@@ -37,7 +38,7 @@ des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HE
|
||||
%put ### This is short help information for the `listPackages` macro #;
|
||||
%put #-----------------------------------------------------------------------------------------#;;
|
||||
%put # #;
|
||||
%put # Macro to list available SAS packages, version `20240711` #;
|
||||
%put # Macro to list available SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
|
||||
@@ -30,11 +30,13 @@
|
||||
, loadAddCnt=0 /* should the additional content be loaded?
|
||||
default is 0 - means No, 1 means Yes */
|
||||
, suppressExec=0 /* indicates if loading of exec files
|
||||
should be suppressed, 1=suppress
|
||||
should be suppressed, 1=suppress */
|
||||
, DS2force=0 /* indicates if PROC DS2 packages and threads
|
||||
should be loaded if a data set exists, 0=do not load
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load SAS package, version 20240711. Run %loadPackage() for help info.'
|
||||
des = 'Macro to load SAS package, version 20241207. Run %loadPackage() for help info.'
|
||||
minoperator
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
@@ -50,7 +52,7 @@ minoperator
|
||||
%put ### This is short help information for the `loadPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to *load* SAS packages, version `20240711` #;
|
||||
%put # Macro to *load* SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -110,6 +112,10 @@ minoperator
|
||||
%put # should be suppressed, default value is `0`, #;
|
||||
%put # when set to `1` `exec` files are *not* loaded #;
|
||||
%put # #;
|
||||
%put # - `DS2force=` *Optional.* Indicates if loading of `PROC DS2` packages #;
|
||||
%put # or threads should overwrite existing SAS data sets. #;
|
||||
%put # Default value of `0` means "do not overwrite". #;
|
||||
%put # #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #;
|
||||
@@ -159,7 +165,7 @@ minoperator
|
||||
%GOTO ENDofloadPackage;
|
||||
%end;
|
||||
/* local variables for options */
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp mautocomploc_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
@@ -167,8 +173,9 @@ minoperator
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N NOmautocomploc;
|
||||
|
||||
%local _PackageFileref_;
|
||||
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
|
||||
@@ -211,6 +218,11 @@ minoperator
|
||||
%let suppressExec = 0;
|
||||
%end;
|
||||
|
||||
%if %superq(DS2force) NE 1 %then
|
||||
%do;
|
||||
%let DS2force = 0;
|
||||
%end;
|
||||
|
||||
filename &_PackageFileref_. &ZIP.
|
||||
/* put location of package myPackageFile.zip here */
|
||||
"&path./%lowcase(&packageName.).&zip." %unquote(&options.)
|
||||
@@ -221,21 +233,31 @@ minoperator
|
||||
filename &_PackageFileref_. clear;
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
%local rV pV;
|
||||
%let pV = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV.,3,.,M)+0)*1e0);
|
||||
%let rV = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rV = %sysevalf((%scan(&rV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV.,3,.,M)+0)*1e0);
|
||||
%local rV pV rV0 pV0 rVsign;
|
||||
%let pV0 = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%let rV0 = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rVsign = %sysfunc(compress(&requiredVersion.,<=>,k));
|
||||
%if %superq(rVsign)= %then %let rVsign=<=;
|
||||
%else %if NOT (%superq(rVsign) IN (%str(=) %str(<=) %str(=<) %str(=>) %str(>=) %str(<) %str(>))) %then
|
||||
%do;
|
||||
%put WARNING: Illegal operatopr "%superq(rVsign)"! Default(<=) will be used.;
|
||||
%put WARNING- Supported operators are: %str(= <= =< => >= < >);
|
||||
%let rVsign=<=;
|
||||
%end;
|
||||
%let rV = %sysevalf((%scan(&rV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%if %sysevalf(&rV. > &pV.) %then
|
||||
%if NOT %sysevalf(&rV. &rVsign. &pV.) %then
|
||||
%do;
|
||||
%put ERROR: Package &packageName. will not be loaded!;
|
||||
%put ERROR- Required version is &requiredVersion.;
|
||||
%put ERROR- Provided version is &packageVersion.;
|
||||
%put ERROR- Required version is &rV0.;
|
||||
%put ERROR- Provided version is &pV0.;
|
||||
%put ERROR- Condition %bquote((&rV0. &rVsign. &pV0.)) evaluates to %sysevalf(&rV. &rVsign. &pV.);
|
||||
%put ERROR- Verify installed version of the package.;
|
||||
%put ERROR- ;
|
||||
%GOTO WrongVersionOFPackage; /*%RETURN;*/
|
||||
@@ -278,7 +300,7 @@ minoperator
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
msglevel=&msglevel_tmp. &mautocomploc_tmp.;
|
||||
|
||||
%ENDofloadPackage:
|
||||
%mend loadPackage;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
is provided in required version */
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load additional content for a SAS package, version 20240711. Run %loadPackageAddCnt() for help info.'
|
||||
des = 'Macro to load additional content for a SAS package, version 20241207. Run %loadPackageAddCnt() for help info.'
|
||||
minoperator
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
@@ -35,7 +35,7 @@ minoperator
|
||||
%put ### This is short help information for the `loadPackageAddCnt` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to *load* additional content for a SAS package, version `20240711` #;
|
||||
%put # Macro to *load* additional content for a SAS package, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -100,7 +100,7 @@ minoperator
|
||||
%GOTO ENDofloadPackageAddCnt;
|
||||
%end;
|
||||
/* local variables for options */
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp zip;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp mautocomploc_tmp zip;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
@@ -108,10 +108,11 @@ minoperator
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
%let zip = zip;
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N NOmautocomploc;
|
||||
|
||||
%local _PackageFileref_;
|
||||
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
|
||||
@@ -156,22 +157,33 @@ minoperator
|
||||
%include &_PackageFileref_.(packagemetadata.sas) / &source2.;
|
||||
filename &_PackageFileref_. clear;
|
||||
|
||||
|
||||
/* test if required version of package is "good enough" */
|
||||
%local rV pV;
|
||||
%let pV = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV.,3,.,M)+0)*1e0);
|
||||
%let rV = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rV = %sysevalf((%scan(&rV.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV.,3,.,M)+0)*1e0);
|
||||
%local rV pV rV0 pV0 rVsign;
|
||||
%let pV0 = %sysfunc(compress(&packageVersion.,.,kd));
|
||||
%let pV = %sysevalf((%scan(&pV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&pV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&pV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%let rV0 = %sysfunc(compress(&requiredVersion.,.,kd));
|
||||
%let rVsign = %sysfunc(compress(&requiredVersion.,<=>,k));
|
||||
%if %superq(rVsign)= %then %let rVsign=<=;
|
||||
%else %if NOT (%superq(rVsign) IN (%str(=) %str(<=) %str(=<) %str(=>) %str(>=) %str(<) %str(>))) %then
|
||||
%do;
|
||||
%put WARNING: Illegal operatopr "%superq(rVsign)"! Default(<=) will be used.;
|
||||
%put WARNING- Supported operators are: %str(= <= =< => >= < >);
|
||||
%let rVsign=<=;
|
||||
%end;
|
||||
%let rV = %sysevalf((%scan(&rV0.,1,.,M)+0)*1e8
|
||||
+ (%scan(&rV0.,2,.,M)+0)*1e4
|
||||
+ (%scan(&rV0.,3,.,M)+0)*1e0);
|
||||
|
||||
%if %sysevalf(&rV. > &pV.) %then
|
||||
%if NOT %sysevalf(&rV. &rVsign. &pV.) %then
|
||||
%do;
|
||||
%put ERROR: Additional content for package &packageName. will not be loaded!;
|
||||
%put ERROR- Required version is &requiredVersion.;
|
||||
%put ERROR- Provided version is &packageVersion.;
|
||||
%put ERROR- Required version is &rV0.;
|
||||
%put ERROR- Provided version is &pV0.;
|
||||
%put ERROR- Condition %bquote((&rV0. &rVsign. &pV0.)) evaluates to %sysevalf(&rV. &rVsign. &pV.);
|
||||
%put ERROR- Verify installed version of the package.;
|
||||
%put ERROR- ;
|
||||
%GOTO WrongVersionOFPackageAddCnt; /*%RETURN;*/
|
||||
@@ -364,12 +376,10 @@ minoperator
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
msglevel=&msglevel_tmp. &mautocomploc_tmp.;
|
||||
|
||||
%ENDofloadPackageAddCnt:
|
||||
%mend loadPackageAddCnt;
|
||||
|
||||
|
||||
|
||||
|
||||
/**/
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to load multiple SAS packages at one run, version 20240711. Run %loadPackages() for help info.'
|
||||
des = 'Macro to load multiple SAS packages at one run, version 20241207. Run %loadPackages() for help info.'
|
||||
parmbuff
|
||||
;
|
||||
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
|
||||
@@ -27,7 +27,7 @@ parmbuff
|
||||
%put ### This is short help information for the `loadPackageS` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro wrapper for the loadPackage macro, version `20240711` #;
|
||||
%put # Macro wrapper for the loadPackage macro, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -79,7 +79,7 @@ parmbuff
|
||||
%local lengthOfsyspbuff numberOfPackagesNames i packageElement packageName packageVersion str;
|
||||
|
||||
%let lengthOfsyspbuff = %qsysfunc(length(&syspbuff.));
|
||||
%let packagesNames = %qsysfunc(compress(%qsubstr(&syspbuff., 2, %eval(&lengthOfsyspbuff.-2)), {[(. _,)]}, KDA));
|
||||
%let packagesNames = %qsysfunc(compress(%qsubstr(&syspbuff., 2, %eval(&lengthOfsyspbuff.-2)), {[(. <=>_,)]}, KDA));
|
||||
|
||||
%let str = %qsysfunc(translate(%superq(packagesNames),[[ ]],{(,)}));
|
||||
%let str = %qsysfunc(transtrn(%superq(str),],%str(] )));
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to preview content of a SAS package, version 20240711. Run %previewPackage() for help info.'
|
||||
des = 'Macro to preview content of a SAS package, version 20241207. Run %previewPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -38,7 +38,7 @@ des = 'Macro to preview content of a SAS package, version 20240711. Run %preview
|
||||
%put ### This is short help information for the `previewPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to get preview of a SAS packages, version `20240711` #;
|
||||
%put # Macro to get preview of a SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -106,13 +106,15 @@ des = 'Macro to preview content of a SAS package, version 20240711. Run %preview
|
||||
%GOTO ENDofpreviewPackage;
|
||||
%end;
|
||||
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp mautocomploc_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;
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N NOmautocomploc;
|
||||
|
||||
%local _PackageFileref_;
|
||||
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
|
||||
@@ -152,7 +154,8 @@ des = 'Macro to preview content of a SAS package, version 20240711. Run %preview
|
||||
%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.;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.
|
||||
msglevel = &msglevel_tmp. &mautocomploc_tmp.;
|
||||
|
||||
%ENDofpreviewPackage:
|
||||
%mend previewPackage;
|
||||
|
||||
422
SPF/Macros/splitcodeforpackage.sas
Normal file
422
SPF/Macros/splitcodeforpackage.sas
Normal file
@@ -0,0 +1,422 @@
|
||||
/*+splitCodeForPackage+*/
|
||||
/*** HELP START ***/
|
||||
|
||||
%macro splitCodeForPackage(
|
||||
codeFile /* a code file to split */
|
||||
,packagePath= /* location for results */
|
||||
,debug=0 /* technical parameter */
|
||||
,nobs=0 /* technical parameter */
|
||||
)
|
||||
/*** HELP START ***/
|
||||
/ des = 'Utility macro to split "one big" code into multiple files for a SAS package, version 20241207. Run %splitCodeForPackage() for help info.'
|
||||
;
|
||||
/*%macro _();%mend _;*/
|
||||
%if (%superq(codeFile) = ) OR (%qupcase(&codeFile.) = HELP) %then
|
||||
%do;
|
||||
%local options_tmp ;
|
||||
%let options_tmp = ls=%sysfunc(getoption(ls))ps=%sysfunc(getoption(ps))
|
||||
%sysfunc(getoption(notes)) %sysfunc(getoption(source))
|
||||
msglevel=%sysfunc(getoption(msglevel))
|
||||
;
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
|
||||
%put ;
|
||||
%put #################################################################################;
|
||||
%put ### This is short help information for the `splitCodeForPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Utility macro to *split* single file with SAS package code into multiple #;
|
||||
%put # files with separate snippets, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
%put # data, etc.) wrapped up together and included by #;
|
||||
%put # a single `load.sas` file (also embedded inside the zip). #;
|
||||
%put # #;
|
||||
%put # The `%nrstr(%%splitCodeForPackage())` macro takes a file with SAS code #;
|
||||
%put # snippets surrounded by `%str(/)*##$##-code-block-start-##$## <tag spec> *%str(/)` and #;
|
||||
%put # `%str(/)*##$##-code-block-end-##$## <tag spec> *%str(/)` tags and split that file into #;
|
||||
%put # multiple files and directories according to a tag specification. #;
|
||||
%put # #;
|
||||
%put # The `<tag spec>` is a list of pairs of the form: `type(object)` that #;
|
||||
%put # indicates how the file should be split. See example 1 below for details. #;
|
||||
%put # #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put #### Parameters: #;
|
||||
%put # #;
|
||||
%put # 1. `codeFile=` *Required.* Name of a file containing code #;
|
||||
%put # that will be split. Required and not null. #;
|
||||
%put # If empty displays this help information. #;
|
||||
%put # #;
|
||||
%put # - `packagePath=` *Required.* Location for package files after #;
|
||||
%put # splitting into separate files and directories. #;
|
||||
%put # If missing or not exist then `WORK` is uded. #;
|
||||
%put # #;
|
||||
%put # - `debug=` *Optional.* Turns on code printing for debugging. #;
|
||||
%put # #;
|
||||
%put # - `nobs=` *Optional.* Technical parameter with value `0`. #;
|
||||
%put # Do not change. #;
|
||||
%put # #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #;
|
||||
%put # to learn more. #;
|
||||
%put # #;
|
||||
%put ### Example 1 ###################################################################;
|
||||
%put # #;
|
||||
%put # Assume that the `myPackageCode.sas` file #;
|
||||
%put # is located in the `C:/lazy/` folder and #;
|
||||
%put # contain the following code and tags: #;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas;
|
||||
%put ;
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-start-##$## 01_macro(abc) */ );
|
||||
%put %nrstr( %%macro abc(); );
|
||||
%put %nrstr( %%put I am "abc".; );
|
||||
%put %nrstr( %%mend abc; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-end-##$## 01_macro(abc) */ );
|
||||
%put ;
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-start-##$## 01_macro(efg) */ );
|
||||
%put %nrstr( %%macro efg(); );
|
||||
%put %nrstr( %%put I am "efg".; );
|
||||
%put %nrstr( %%mend efg; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-end-##$## 01_macro(efg) */ );
|
||||
%put ;
|
||||
%put %nrstr( proc FCMP outlib=work.f.p; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-start-##$## 02_functions(xyz) */ );
|
||||
%put %nrstr( function xyz(n); );
|
||||
%put %nrstr( return(n**2 + n + 1) );
|
||||
%put %nrstr( endfunc; );
|
||||
%put %nrstr( /)%nrstr(*##$##-code-block-end-##$## 02_functions(xyz) */ );
|
||||
%put %nrstr( quit; );
|
||||
%put ;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
%put # #;
|
||||
%put # and we want results in `C:/split/` folder, we run the following: #;
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas;
|
||||
%put %nrstr( filename packages "C:/SAS_PACKAGES"; %%* setup a directory for packages;);
|
||||
%put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; );
|
||||
%put ;
|
||||
%put %nrstr( %%splitCodeForPackage%( );
|
||||
%put %nrstr( codeFile=C:/lazy/myPackageCode.sas );
|
||||
%put %nrstr( ,packagePath=C:/split/ %) );
|
||||
%put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
%put # #;
|
||||
%put #################################################################################;
|
||||
%put ;
|
||||
options &options_tmp.;
|
||||
%GOTO ENDofsplitCodeForPackage;
|
||||
%end;
|
||||
|
||||
|
||||
%local options_tmp2 ;
|
||||
%let options_tmp2 = ls=%sysfunc(getoption(ls)) ps=%sysfunc(getoption(ps))
|
||||
%sysfunc(getoption(notes)) %sysfunc(getoption(source))
|
||||
msglevel=%sysfunc(getoption(msglevel))
|
||||
;
|
||||
options nomprint nosymbolgen nomlogic notes source ls=MAX ps=MAX msglevel=N ;
|
||||
|
||||
%let debug = %sysevalf(NOT(0=%superq(debug)));
|
||||
%if 1=&debug. %then
|
||||
%do;
|
||||
options mprint symbolgen mlogic source source2 msglevel=i;
|
||||
%end;
|
||||
|
||||
%put NOTE- --&SYSMACRONAME.-START--;
|
||||
%local rc;
|
||||
%let rc = %sysfunc(doSubL(%nrstr(
|
||||
options
|
||||
%sysfunc(ifc(1=&debug.
|
||||
,msglevel=I ls=max ps=64 notes mprint symbolgen mlogic source source2
|
||||
,msglevel=N ls=max ps=64 nonotes nomprint nosymbolgen nomlogic nosource nosource2
|
||||
))
|
||||
;;;;
|
||||
|
||||
options DLcreateDir;
|
||||
libname w "%sysfunc(pathname(WORK))/_splitCodeForPackage_";
|
||||
filename d "%sysfunc(pathname(WORK))/_splitCodeForPackage_/dummy";
|
||||
data _null_;
|
||||
file d;
|
||||
put "dummy";
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
length codeFile $ 4096;
|
||||
codeFile = symget('codeFile');
|
||||
codeFile = dequote(codeFile);
|
||||
|
||||
if fileexist(codeFile) then
|
||||
do;
|
||||
codeFile = quote(strip(codeFile),"'");
|
||||
call symputX("codeFile",codeFile,"L");
|
||||
end;
|
||||
else
|
||||
do;
|
||||
put "ERROR: [splitCodeForPackage] File " codeFile 'does not exist!';
|
||||
call symputX("codeFile",quote(strip(pathname('d'))),"L");
|
||||
end;
|
||||
run;
|
||||
|
||||
options notes;
|
||||
filename source &codeFile.;
|
||||
filename source LIST;
|
||||
options nonotes;
|
||||
|
||||
data _null_;
|
||||
length packagePath work $ 4096;
|
||||
work = pathname('WORK');
|
||||
packagePath = coalescec(symget('packagePath'), work);
|
||||
rc = fileexist(packagePath);
|
||||
if NOT rc then packagePath = work;
|
||||
if rc = 1 then put "INFO: " @;
|
||||
else put "WARNING: " @;
|
||||
put packagePath=;
|
||||
call symputX('packagePath',packagePath,"L");
|
||||
run;
|
||||
|
||||
|
||||
data w.files;
|
||||
stop;
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
if 1 = _N_ then
|
||||
do;
|
||||
declare hash H(ordered:"A");
|
||||
H.defineKey('token');
|
||||
H.defineData('token','start','end','lineNumber');
|
||||
H.defineDone();
|
||||
end;
|
||||
if 1 = _E_ then
|
||||
do;
|
||||
H.output(dataset:'w.files');
|
||||
end;
|
||||
|
||||
infile source END=_E_;
|
||||
lineNumberN+1;
|
||||
input;
|
||||
|
||||
length line $ 4096 lineNumber $ 256;
|
||||
line = left(lowcase(_infile_));
|
||||
block=scan(line,1," ");
|
||||
|
||||
if block in (
|
||||
'/*##$##-code-block-start-##$##'
|
||||
'/*##$##-code-block-end-##$##'
|
||||
);
|
||||
|
||||
if substr(block,20,1) = 's' then
|
||||
do; s=1; e=0; end;
|
||||
else
|
||||
do; s=0; e=1; end;
|
||||
|
||||
i=1;
|
||||
token=block;
|
||||
do while(i);
|
||||
i+1;
|
||||
token=scan(line,i," ");
|
||||
if token='*/' OR token=' ' then i=0;
|
||||
else
|
||||
do;
|
||||
start=0; end=0;
|
||||
if H.find() then
|
||||
do;
|
||||
start=s;
|
||||
end =e;
|
||||
lineNumber = cats(lineNumberN);
|
||||
end;
|
||||
else
|
||||
do;
|
||||
start+s;
|
||||
end +e;
|
||||
lineNumber = catx(",",lineNumber,lineNumberN);
|
||||
end;
|
||||
H.replace();
|
||||
/*putlog token= s= e= start= end=;*/
|
||||
end;
|
||||
end;
|
||||
run;
|
||||
|
||||
title;
|
||||
title1 "Attention!!! Not Matching Tags!";
|
||||
title2 "Verify following tags in file:";
|
||||
title3 &codeFile.;
|
||||
proc print data=w.files(where=(start NE end));
|
||||
run;
|
||||
title;
|
||||
|
||||
data w.files;
|
||||
set w.files end=_E_ nobs=nobs;
|
||||
where start=end;
|
||||
length dir $ 128 code $ 32 path $ 160;
|
||||
dir =coalescec(scan(token,1,'()'),'!BAD_DIRECTORY');
|
||||
code=coalescec(scan(token,2,'()'),'!BAD_CODE_FILE');
|
||||
if dir = '!BAD_DIRECTORY' or code = '!BAD_CODE_FILE' then
|
||||
put "WARNING: Bad directory or code file name!"
|
||||
/ "WARNING- Check tag: " token ;
|
||||
path=cats('/',dir,'/',code,'.sas'); /* .sas */
|
||||
run;
|
||||
|
||||
title;
|
||||
title1 "List of tags with value _ALL_ for 'dir' or 'code' variable.";
|
||||
title2 "Snippets tagged this way will be copied to multiple files.";
|
||||
proc print data=w.files(where=(dir = '_all_' OR code = '_all_'));
|
||||
run;
|
||||
title;
|
||||
|
||||
data w.files;
|
||||
if 0=nobs then
|
||||
put "WARNING: No tags found in the file";
|
||||
|
||||
set w.files end=_E_ nobs=nobs;
|
||||
where dir NE '_all_' AND code NE '_all_';
|
||||
n+1;
|
||||
if 1 = _E_ then
|
||||
call symputX('nobs',n,"L");
|
||||
run;
|
||||
|
||||
title;
|
||||
title "List of files";
|
||||
proc print data=w.files;
|
||||
run;
|
||||
title;
|
||||
|
||||
data _null_;
|
||||
set w.files;
|
||||
rc = libname("_",catx("/",symget('packagePath'),dir));
|
||||
rc = libname("_");
|
||||
run;
|
||||
|
||||
filename f DUMMY;
|
||||
data _null_;
|
||||
if 1 =_N_ then
|
||||
do;
|
||||
array paths[0:&nobs.] $ 128 _temporary_;
|
||||
array starts[0:&nobs.] _temporary_;
|
||||
array ends[0:&nobs.] _temporary_;
|
||||
array write[0:&nobs.] _temporary_;
|
||||
array firstLine[0:&nobs.] _temporary_;
|
||||
|
||||
declare hash H();
|
||||
H.defineKey('token');
|
||||
H.defineData('n');
|
||||
H.defineDone();
|
||||
|
||||
do until(_E_);
|
||||
set w.files end=_E_;
|
||||
paths[n]=path;
|
||||
starts[n]=start;
|
||||
ends[n]=end;
|
||||
write[n]=0;
|
||||
rc=H.add();
|
||||
firstLine[n]=1;
|
||||
end;
|
||||
_E_=.;
|
||||
length packagePath $ 4096;
|
||||
retain packagePath " ";
|
||||
packagePath=symget('packagePath');
|
||||
end;
|
||||
|
||||
infile source END=_E_;
|
||||
input;
|
||||
|
||||
length line /*lineToPrint*/ $ 4096;
|
||||
line = left(lowcase(_infile_));
|
||||
/*lineToPrint=_infile_;*/
|
||||
block=scan(line,1," ");
|
||||
|
||||
if block in (
|
||||
'/*##$##-code-block-start-##$##'
|
||||
'/*##$##-code-block-end-##$##'
|
||||
) then
|
||||
do;
|
||||
/********************************************************/
|
||||
if substr(block,20,1) = 's' then
|
||||
do; s=1; e=0; end;
|
||||
else
|
||||
do; s=0; e=1; end;
|
||||
|
||||
i=1;
|
||||
token=block;
|
||||
do while(i);
|
||||
i+1;
|
||||
token=scan(line,i," ");
|
||||
if token='*/' OR token=' ' then i=0; /* if it is the end of list - stop */
|
||||
else if token='_all_(_all_)' then /* if this is a snippet for ALL files in a package */
|
||||
do k=1 to &nobs.;
|
||||
starts[k]+ -s;
|
||||
ends[k] + -e;
|
||||
write[k] + (s-e);
|
||||
end;
|
||||
else if scan(token,2,'()')='_all_' then /* if this is a snippet for ALL files in a type */
|
||||
do k=1 to &nobs.;
|
||||
if scan(token,1,'()')=scan(paths[k],1,'/\') then
|
||||
do;
|
||||
starts[k]+ -s;
|
||||
ends[k] + -e;
|
||||
write[k] + (s-e);
|
||||
end;
|
||||
end;
|
||||
else if scan(token,1,'()')='_all_' then /* if this is a snippet for ALL files with the same name */
|
||||
do k=1 to &nobs.;
|
||||
if (scan(token,2,'()')!!'.sas')=scan(paths[k],2,'/\') then
|
||||
do;
|
||||
starts[k]+ -s;
|
||||
ends[k] + -e;
|
||||
write[k] + (s-e);
|
||||
end;
|
||||
end;
|
||||
else /* all other "regular" cases */
|
||||
do;
|
||||
if 0=H.find() then
|
||||
do;
|
||||
starts[n]+ -s;
|
||||
ends[n] + -e;
|
||||
write[n] + (s-e);
|
||||
select;
|
||||
when(write[n]<0)
|
||||
putlog "ERROR: Wrong tags order for " token=;
|
||||
when(write[n]>1)
|
||||
do;
|
||||
putlog "WARNING: Doubled value for tag" token=;
|
||||
putlog "WARNING- detected in line " _N_;
|
||||
putlog "WARNING- Check also counterpart block.";
|
||||
end;
|
||||
otherwise;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
/********************************************************/
|
||||
end;
|
||||
else
|
||||
do j = 1 to hbound(write);
|
||||
if write[j]>0 then
|
||||
do;
|
||||
length fvariable $ 4096;
|
||||
fvariable=catx("/",packagePath,paths[j]);
|
||||
file f FILEVAR=fvariable MOD;
|
||||
/*
|
||||
lineToPrintLen=(lengthn(lineToPrint));
|
||||
if lineToPrintLen then
|
||||
put @1 lineToPrint $varying4096. lineToPrintLen;
|
||||
else put;
|
||||
*/
|
||||
if firstLine[j] then
|
||||
do;
|
||||
put '/* File generated with help of SAS Packages Framework, version 20241207. */';
|
||||
firstLine[j]=0;
|
||||
end;
|
||||
put _infile_;
|
||||
end;
|
||||
end;
|
||||
run;
|
||||
|
||||
filename f clear;
|
||||
libname w clear;
|
||||
)));
|
||||
%put NOTE- --&sysmacroname.-END--;
|
||||
options &options_tmp2.;
|
||||
%ENDofsplitCodeForPackage:
|
||||
%mend splitCodeForPackage;
|
||||
|
||||
|
||||
/**/
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to unload SAS package, version 20240711. Run %unloadPackage() for help info.'
|
||||
des = 'Macro to unload SAS package, version 20241207. Run %unloadPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -35,7 +35,7 @@ des = 'Macro to unload SAS package, version 20240711. Run %unloadPackage() for h
|
||||
%put ### This is short help information for the `unloadPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to unload SAS packages, version `20240711` #;
|
||||
%put # Macro to unload SAS packages, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -102,14 +102,15 @@ des = 'Macro to unload SAS package, version 20240711. Run %unloadPackage() for h
|
||||
%end;
|
||||
|
||||
/* local variables for options */
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp msglevel_tmp mautocomploc_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));
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N;
|
||||
options NOnotes NOsource ls=MAX ps=MAX msglevel=N NOmautocomploc;
|
||||
|
||||
%local _PackageFileref_;
|
||||
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
|
||||
@@ -149,7 +150,8 @@ des = 'Macro to unload SAS package, version 20240711. Run %unloadPackage() for h
|
||||
%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.;
|
||||
options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.
|
||||
msglevel = &msglevel_tmp. &mautocomploc_tmp.;
|
||||
|
||||
%ENDofunloadPackage:
|
||||
%mend unloadPackage;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
hashing_file() function, SAS 9.4M6 */
|
||||
)/secure
|
||||
/*** HELP END ***/
|
||||
des = 'Macro to verify SAS package with the hash digest, version 20240711. Run %verifyPackage() for help info.'
|
||||
des = 'Macro to verify SAS package with the hash digest, version 20241207. Run %verifyPackage() for help info.'
|
||||
;
|
||||
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
|
||||
%do;
|
||||
@@ -28,7 +28,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20240711. Run %
|
||||
%put ### This is short help information for the `verifyPackage` macro #;
|
||||
%put #-------------------------------------------------------------------------------#;
|
||||
%put # #;
|
||||
%put # Macro to verify SAS package with it hash digest, version `20240711` #;
|
||||
%put # Macro to verify SAS package with it hash digest, version `20241207` #;
|
||||
%put # #;
|
||||
%put # A SAS package is a zip file containing a group #;
|
||||
%put # of SAS codes (macros, functions, data steps generating #;
|
||||
@@ -83,7 +83,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20240711. Run %
|
||||
%GOTO ENDofverifyPackage;
|
||||
%end;
|
||||
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp;
|
||||
%local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp mautocomploc_tmp;
|
||||
%let ls_tmp = %sysfunc(getoption(ls));
|
||||
%let ps_tmp = %sysfunc(getoption(ps));
|
||||
%let notes_tmp = %sysfunc(getoption(notes));
|
||||
@@ -91,8 +91,9 @@ des = 'Macro to verify SAS package with the hash digest, version 20240711. Run %
|
||||
%let stimer_tmp = %sysfunc(getoption(stimer));
|
||||
%let fullstimer_tmp = %sysfunc(getoption(fullstimer));
|
||||
%let msglevel_tmp = %sysfunc(getoption(msglevel));
|
||||
%let mautocomploc_tmp = %sysfunc(getoption(mautocomploc));
|
||||
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N;
|
||||
options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N NOmautocomploc;
|
||||
|
||||
%local _PackageFileref_;
|
||||
/* %let _PackageFileref_ = P%sysfunc(MD5(%lowcase(&packageName.)),hex7.); */
|
||||
@@ -176,7 +177,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20240711. Run %
|
||||
options ls = &ls_tmp. ps = &ps_tmp.
|
||||
¬es_tmp. &source_tmp.
|
||||
&stimer_tmp. &fullstimer_tmp.
|
||||
msglevel=&msglevel_tmp.;
|
||||
msglevel=&msglevel_tmp. &mautocomploc_tmp.;
|
||||
|
||||
%ENDofverifyPackage:
|
||||
%mend verifyPackage;
|
||||
|
||||
1297
SPF/SPFinit.md
1297
SPF/SPFinit.md
File diff suppressed because it is too large
Load Diff
1053
SPF/SPFinit.sas
1053
SPF/SPFinit.sas
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2019 - 2023 Bartosz Jablonski
|
||||
Copyright (c) 2019 - 2024 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
|
||||
|
||||
@@ -24,7 +24,7 @@ run;
|
||||
```
|
||||
SHA256 digest for SQLinDS: F*3C010734B76CA7459C4D35087C899121011CD4AA2932B56335FF11A805C8EF8D
|
||||
|
||||
[Documentation for SQLinDS](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/sqlinds.md "Documentation for SQLinDS")
|
||||
[Documentation for SQLinDS](https://github.com/SASPAC/blob/main/sqlinds.md "Documentation for SQLinDS")
|
||||
|
||||
---
|
||||
|
||||
@@ -57,7 +57,7 @@ run;
|
||||
```
|
||||
SHA256 digest for DFA: F*012375D87F66EB3A7BF5DDD0CC5AEE28851733EE33CC63231DF9045BEB958168
|
||||
|
||||
[Documentation for DFA](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/dfa.md "Documentation for DFA")
|
||||
[Documentation for DFA](https://github.com/SASPAC/blob/main/dfa.md "Documentation for DFA")
|
||||
|
||||
---
|
||||
|
||||
@@ -82,11 +82,11 @@ SHA256 digest for DFA: F*012375D87F66EB3A7BF5DDD0CC5AEE28851733EE33CC63231DF9045
|
||||
```
|
||||
SHA256 digest for macroArray: F*3F3893F1FCD78719543703E4353F4CC19811D247C016F220FF729B283C1AD790
|
||||
|
||||
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
|
||||
[Documentation for macroArray](https://github.com/SASPAC/blob/main/macroarray.md "Documentation for macroArray")
|
||||
|
||||
---
|
||||
|
||||
- **BasePlus**\[1.42.1\] adds a bunch of functionalities I am missing in BASE SAS, such as:
|
||||
- **BasePlus**\[2.1.0\] adds a bunch of functionalities I am missing in BASE SAS, such as:
|
||||
```sas
|
||||
call arrMissToRight(myArray);
|
||||
call arrFillMiss(17, myArray);
|
||||
@@ -115,10 +115,12 @@ format x bool.;
|
||||
%put %date(yymmddn10.) %time(time5.) %datetime(e8601dt.);
|
||||
|
||||
%put %monthShift(2023,1,-5);
|
||||
```
|
||||
SHA256 digest for BasePlus: F*2129F372D72A34A4FB1F368A581EA33D64AD4D8F3707213D5B9553F3C3122003
|
||||
|
||||
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
|
||||
%put #%expandDataSetsList(lib=sashelp,datasets=_all_)#;
|
||||
```
|
||||
SHA256 digest for BasePlus: F*DFA83F8E0D7424DEB63D49620392068BC68D766552E2804CB6B01DE8E5A87769
|
||||
|
||||
[Documentation for BasePlus](https://github.com/SASPAC/blob/main/baseplus.md "Documentation for BasePlus")
|
||||
|
||||
---
|
||||
|
||||
@@ -133,7 +135,7 @@ SHA256 digest for BasePlus: F*2129F372D72A34A4FB1F368A581EA33D64AD4D8F3707213D5B
|
||||
|
||||
SHA256 digest for GSM: F*80197391195C3EC41BD436DF0C8802D3920E4D22B64009A7DE872FBDF8D4B86E
|
||||
|
||||
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")
|
||||
[Documentation for GSM](https://github.com/SASPAC/blob/main/gsm.md "Documentation for GSM")
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
/* 202406719 */
|
||||
/* 20240909 */
|
||||
BasePlus: F*DFA83F8E0D7424DEB63D49620392068BC68D766552E2804CB6B01DE8E5A87769
|
||||
|
||||
/* 20240724 */
|
||||
BasePlus: F*FB102C9B12E870666C15A651017D48E0141E47D64C11437350D0EC75A7E9E609
|
||||
|
||||
/* 20240723 */
|
||||
BasePlus: F*0730DD793516E5C193842126A7EC9D339ADADD19F0F40B071F938CABDE4E66AD
|
||||
|
||||
/* 20240722 */
|
||||
BasePlus: F*68BB953CD732EB43119A3339656670292317FE1C3B764EC57484C7D5C9DF23EB
|
||||
|
||||
/* 20240719 */
|
||||
BasePlus: F*2129F372D72A34A4FB1F368A581EA33D64AD4D8F3707213D5B9553F3C3122003
|
||||
|
||||
/* 202406710 */
|
||||
/* 20240710 */
|
||||
BasePlus: F*6012D1475AE22A4445C032D8EAE092BE515D8CD2AE390CC087F5987ACB8BCB13
|
||||
|
||||
/* 20240609 */
|
||||
|
||||
@@ -9,22 +9,22 @@
|
||||
### Version information:
|
||||
|
||||
- Package: BasePlus
|
||||
- Version: 1.42.1
|
||||
- Generated: 2024-07-19T10:19:18
|
||||
- Version: 2.1.0
|
||||
- Generated: 2024-09-09T12:55:04
|
||||
- Author(s): Bartosz Jablonski (yabwon@gmail.com), Quentin McMullen (qmcmullen@gmail.com)
|
||||
- Maintainer(s): Bartosz Jablonski (yabwon@gmail.com)
|
||||
- License: MIT
|
||||
- File SHA256: `F*2129F372D72A34A4FB1F368A581EA33D64AD4D8F3707213D5B9553F3C3122003` for this version
|
||||
- Content SHA256: `C*565555B57455548ABAFB1E30A77C9BEE008F601697300B01518FD05A97A1F9F9` for this version
|
||||
- File SHA256: `F*DFA83F8E0D7424DEB63D49620392068BC68D766552E2804CB6B01DE8E5A87769` for this version
|
||||
- Content SHA256: `C*AB16F5B6538515607C3C254E401DC1ACA7293AB36990227F6E7792145CEEAB87` for this version
|
||||
|
||||
---
|
||||
|
||||
# The `BasePlus` package, version: `1.42.1`;
|
||||
# The `BasePlus` package, version: `2.1.0`;
|
||||
|
||||
---
|
||||
|
||||
|
||||
# The BasePlus package [ver. 1.42.1] <a name="baseplus-package"></a> ###############################################
|
||||
# The BasePlus package [ver. 2.1.0] <a name="baseplus-package"></a> ###############################################
|
||||
|
||||
The **BasePlus** package implements useful
|
||||
functions and functionalities I miss in the BASE SAS.
|
||||
@@ -368,6 +368,25 @@ run;
|
||||
%put &=y.;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**EXAMPLE 28** Converting variables names to lowercases:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data a1 a2 a3 b_x b_y b_z;
|
||||
set sashelp.class(obs=1);
|
||||
run;
|
||||
|
||||
%put #%expandDataSetsList(lib=work,datasets=a1-a3 b_:)#;
|
||||
|
||||
proc print data=a1;
|
||||
proc print data=b_x;
|
||||
run;
|
||||
|
||||
%unifyVarsCaseSize(work,a1-a3 b_:)
|
||||
|
||||
proc print data=a1;
|
||||
proc print data=b_x;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
@@ -439,38 +458,42 @@ The `BasePlus` package consists of the following content:
|
||||
46. [`deldataset()` function ](#deldataset-functions-46 )
|
||||
47. [`semicolonc()` function ](#semicolonc-functions-47 )
|
||||
48. [`semicolonn()` function ](#semicolonn-functions-48 )
|
||||
49. [`$brackets.` format/informat ](#brackets-format-49 )
|
||||
50. [`$semicolon.` format/informat ](#semicolon-format-50 )
|
||||
51. [`qsortincbyprocproto()` proto ](#qsortincbyprocproto-proto-51 )
|
||||
52. [`frommissingtonumberbs()` function ](#frommissingtonumberbs-functions-52 )
|
||||
53. [`fromnumbertomissing()` function ](#fromnumbertomissing-functions-53 )
|
||||
54. [`quicksort4notmiss()` function ](#quicksort4notmiss-functions-54 )
|
||||
55. [`quicksorthash()` function ](#quicksorthash-functions-55 )
|
||||
56. [`quicksorthashsddv()` function ](#quicksorthashsddv-functions-56 )
|
||||
57. [`quicksortlight()` function ](#quicksortlight-functions-57 )
|
||||
58. [`%date()` macro ](#date-macro-58 )
|
||||
59. [`%datetime()` macro ](#datetime-macro-59 )
|
||||
60. [`%downloadfilesto()` macro ](#downloadfilesto-macro-60 )
|
||||
61. [`%filepath()` macro ](#filepath-macro-61 )
|
||||
62. [`%finddswithvarval()` macro ](#finddswithvarval-macro-62 )
|
||||
63. [`%fmt()` macro ](#fmt-macro-63 )
|
||||
64. [`%generateoneliners()` macro ](#generateoneliners-macro-64 )
|
||||
65. [`%gettitle()` macro ](#gettitle-macro-65 )
|
||||
66. [`%iffunc()` macro ](#iffunc-macro-66 )
|
||||
67. [`%infmt()` macro ](#infmt-macro-67 )
|
||||
68. [`%letters()` macro ](#letters-macro-68 )
|
||||
69. [`%libpath()` macro ](#libpath-macro-69 )
|
||||
70. [`%minclude()` macro ](#minclude-macro-70 )
|
||||
71. [`%monthshift()` macro ](#monthshift-macro-71 )
|
||||
72. [`%replist()` macro ](#replist-macro-72 )
|
||||
73. [`%time()` macro ](#time-macro-73 )
|
||||
74. [`%today()` macro ](#today-macro-74 )
|
||||
75. [`%translate()` macro ](#translate-macro-75 )
|
||||
76. [`%tranwrd()` macro ](#tranwrd-macro-76 )
|
||||
77. [`%workpath()` macro ](#workpath-macro-77 )
|
||||
49. [`$bpklenght.` format/informat ](#bpklenght-formats-49 )
|
||||
50. [`$bplenght.` format/informat ](#bplenght-formats-50 )
|
||||
51. [`$brackets.` format/informat ](#brackets-formats-51 )
|
||||
52. [`$semicolon.` format/informat ](#semicolon-formats-52 )
|
||||
53. [`qsortincbyprocproto()` proto ](#qsortincbyprocproto-proto-53 )
|
||||
54. [`frommissingtonumberbs()` function ](#frommissingtonumberbs-functions-54 )
|
||||
55. [`fromnumbertomissing()` function ](#fromnumbertomissing-functions-55 )
|
||||
56. [`quicksort4notmiss()` function ](#quicksort4notmiss-functions-56 )
|
||||
57. [`quicksorthash()` function ](#quicksorthash-functions-57 )
|
||||
58. [`quicksorthashsddv()` function ](#quicksorthashsddv-functions-58 )
|
||||
59. [`quicksortlight()` function ](#quicksortlight-functions-59 )
|
||||
60. [`%date()` macro ](#date-macro-60 )
|
||||
61. [`%datetime()` macro ](#datetime-macro-61 )
|
||||
62. [`%downloadfilesto()` macro ](#downloadfilesto-macro-62 )
|
||||
63. [`%expanddatasetslist()` macro ](#expanddatasetslist-macro-63 )
|
||||
64. [`%filepath()` macro ](#filepath-macro-64 )
|
||||
65. [`%finddswithvarval()` macro ](#finddswithvarval-macro-65 )
|
||||
66. [`%fmt()` macro ](#fmt-macro-66 )
|
||||
67. [`%generateoneliners()` macro ](#generateoneliners-macro-67 )
|
||||
68. [`%gettitle()` macro ](#gettitle-macro-68 )
|
||||
69. [`%iffunc()` macro ](#iffunc-macro-69 )
|
||||
70. [`%infmt()` macro ](#infmt-macro-70 )
|
||||
71. [`%letters()` macro ](#letters-macro-71 )
|
||||
72. [`%libpath()` macro ](#libpath-macro-72 )
|
||||
73. [`%minclude()` macro ](#minclude-macro-73 )
|
||||
74. [`%monthshift()` macro ](#monthshift-macro-74 )
|
||||
75. [`%replist()` macro ](#replist-macro-75 )
|
||||
76. [`%time()` macro ](#time-macro-76 )
|
||||
77. [`%today()` macro ](#today-macro-77 )
|
||||
78. [`%translate()` macro ](#translate-macro-78 )
|
||||
79. [`%tranwrd()` macro ](#tranwrd-macro-79 )
|
||||
80. [`%unifyvarscasesize()` macro ](#unifyvarscasesize-macro-80 )
|
||||
81. [`%workpath()` macro ](#workpath-macro-81 )
|
||||
|
||||
|
||||
78. [License note](#license)
|
||||
82. [License note](#license)
|
||||
|
||||
---
|
||||
|
||||
@@ -979,6 +1002,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
<,varRange=>
|
||||
<,quote=>
|
||||
<,mcArray=>
|
||||
<,ignoreCases>
|
||||
)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -991,7 +1015,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
a variables separator on the created list.
|
||||
|
||||
* `pattern = .*` - *Optional*, default value `.*` (i.e. any text),
|
||||
a variable name regexp pattern, case INSENSITIVE!
|
||||
a variable name regexp pattern, by default case INSENSITIVE!
|
||||
|
||||
* `varRange = _all_` - *Optional*, default value `_all_`,
|
||||
a named range list of variables.
|
||||
@@ -1012,6 +1036,8 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
`%put %getVars(..., mcArray=XXX);` will result with
|
||||
an Explicit & Radical Refuse Of Run (aka ERROR).
|
||||
|
||||
* `ignoreCases=` - *Optional*, default value is 1.
|
||||
Indicates if search should be case insensitive.
|
||||
|
||||
|
||||
### EXAMPLES AND USECASES: ####################################################
|
||||
@@ -1878,7 +1904,8 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
<,sep=>
|
||||
<,pattern=>
|
||||
<,varRange=>
|
||||
<,quote=>
|
||||
<,quote=>
|
||||
<,ignoreCases=>
|
||||
)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1899,6 +1926,9 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
* `quote =` - *Optional*, default value is blank, a quotation
|
||||
symbol to be used around values.
|
||||
|
||||
* `ignoreCases=` - *Optional*, default value is 1.
|
||||
Indicates if search should be case insensitive.
|
||||
|
||||
|
||||
### EXAMPLES AND USECASES: ####################################################
|
||||
|
||||
@@ -2005,6 +2035,9 @@ plots of kernel density estimates, jitter data values, and box-and-whiskers plot
|
||||
|
||||
See examples below for the details.
|
||||
|
||||
The "Here Comes the Rain (Cloud Plot) Again" (B. Jablonski, 2024) article
|
||||
describing the macro is attached as an additional content to the package.
|
||||
|
||||
### SYNTAX: ###################################################################
|
||||
|
||||
The basic syntax is the following, the `<...>` means optional parameters:
|
||||
@@ -2022,6 +2055,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
<,boxPlotSymbolSize=>
|
||||
<,boxPlotLineSize=>
|
||||
<,boxPlotFill=>
|
||||
<,whiskerScale=>
|
||||
<,meanShiftLine=>
|
||||
<,meanShiftStep=>
|
||||
<,meanShiftColors=>
|
||||
@@ -2117,6 +2151,12 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
Transparency of the box plot.
|
||||
Ranges from 0.0 (opaque) to 1.0 (full translucent).
|
||||
|
||||
* `whiskerScale=` - *Optional*, default value `1.5`.
|
||||
It provides `WS` parameter in the `Q1 - WS*IQR`
|
||||
formula and the `Q3 + WS*IQR` formula.
|
||||
Provided value should be a positive number.
|
||||
Otherwise it is set to 0.
|
||||
|
||||
* `meanShiftLine` - *Optional*, default value `0`.
|
||||
Indicates if a line connecting mean symbol
|
||||
on the Box Plot should be added.
|
||||
@@ -2336,12 +2376,14 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
The box-and-whiskers plot has the following interpretation:
|
||||
- left vertical bar indicates the *minimum*,
|
||||
- left whisker line starts at `max(Q1 - 1.5IQR, minimum)` and ends at lower quartile (Q1),
|
||||
- left whisker line starts at `max(Q1 - WS*IQR, minimum)` and ends at lower quartile (Q1),
|
||||
- diamond indicates mean,
|
||||
- vertical bar inside of the box indicates median,
|
||||
- right whisker line starts at upper quartile (Q3) and ends at `min(Q3 + 1.5IQR, maximum)`,
|
||||
- right whisker line starts at upper quartile (Q3) and ends at `min(Q3 + WS*IQR, maximum)`,
|
||||
- right vertical bar indicates the *maximum*.
|
||||
|
||||
The `WS` value is provided through `whiskerScale=` parameter. Default value is `1.5`.
|
||||
|
||||
With above setup it may happen that
|
||||
there is a gap between the minimum marker and the beginning of the left whisker
|
||||
or
|
||||
@@ -2503,6 +2545,7 @@ The output can be seen in the `md` file.
|
||||
, vertical = 1
|
||||
, title = %nrstr(title1 J=C HEIGHT=3 "The VERTICAL plotting is cool, ...";)
|
||||
, footnote = %nrstr(footnote1 J=L HEIGHT=2 "... isn't it?";)
|
||||
, whiskerScale = 1.5
|
||||
)
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -4489,7 +4532,129 @@ semicolonN(X)
|
||||
|
||||
---
|
||||
|
||||
## `$brackets.` format/informat <a name="brackets-format-49"></a> ######
|
||||
## `$bpklenght.` format/informat <a name="bpklenght-formats-49"></a> ######
|
||||
|
||||
## >>> `bpklength` format/informat: <<< <a name="bpklength-format"></a> #######################
|
||||
|
||||
The **bpklength** format and informats uses the `klength()` function
|
||||
to count the number of letters in a word. For empty string returns 0.
|
||||
|
||||
|
||||
### EXAMPLES AND USECASES: ####################################################
|
||||
|
||||
**Example 1.** Informats and format:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data work.count_letters;
|
||||
input x $ 32.;
|
||||
n = input (x, bpklength.);
|
||||
c = input (x, $bpklength.);
|
||||
format x $bpklength.;
|
||||
cards;
|
||||
ż
|
||||
żó
|
||||
żół
|
||||
żółć
|
||||
a
|
||||
ab
|
||||
abc
|
||||
abcd
|
||||
空
|
||||
空手
|
||||
空手道
|
||||
1
|
||||
12
|
||||
123
|
||||
1234
|
||||
12345
|
||||
123456
|
||||
1234567
|
||||
12345678
|
||||
123456789
|
||||
1234567890
|
||||
;
|
||||
run;
|
||||
proc print data=work.count_letters;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Example 2.** Format:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data _null_;
|
||||
length x $ 32767;
|
||||
do i = 32767/3 to 0 by -1111, 10 to 0 by -1;
|
||||
x=repeat("空",i);
|
||||
put x $bpklength.;
|
||||
end;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
## `$bplenght.` format/informat <a name="bplenght-formats-50"></a> ######
|
||||
|
||||
## >>> `bplength` format/informat: <<< <a name="bplength-format"></a> #######################
|
||||
|
||||
The **bplength** format and informats use the `lengthn()` function
|
||||
to count the number of bytes in a word.
|
||||
|
||||
|
||||
### EXAMPLES AND USECASES: ####################################################
|
||||
|
||||
**Example 1.** Informats and format:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data work.count_bytes;
|
||||
input x $ 32.;
|
||||
n = input (x, bplength.);
|
||||
c = input (x, $bplength.);
|
||||
format x $bplength.;
|
||||
cards;
|
||||
ż
|
||||
żó
|
||||
żół
|
||||
żółć
|
||||
a
|
||||
ab
|
||||
abc
|
||||
abcd
|
||||
空
|
||||
空手
|
||||
空手道
|
||||
1
|
||||
12
|
||||
123
|
||||
1234
|
||||
12345
|
||||
123456
|
||||
1234567
|
||||
12345678
|
||||
123456789
|
||||
1234567890
|
||||
;
|
||||
run;
|
||||
proc print data=work.count_bytes;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Example 2.** Format:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data _null_;
|
||||
length x $ 32767;
|
||||
do i = 32767/3 to 0 by -1111, 10 to 0 by -1;
|
||||
x=repeat("空",i);
|
||||
put x $bplength.;
|
||||
end;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
## `$brackets.` format/informat <a name="brackets-formats-51"></a> ######
|
||||
|
||||
## >>> `brackets.` format: <<< <a name="brackets-format"></a> #######################
|
||||
|
||||
@@ -4520,7 +4685,7 @@ run;
|
||||
|
||||
---
|
||||
|
||||
## `$semicolon.` format/informat <a name="semicolon-format-50"></a> ######
|
||||
## `$semicolon.` format/informat <a name="semicolon-formats-52"></a> ######
|
||||
|
||||
## >>> `semicolon.` format: <<< <a name="semicolon-format"></a> #######################
|
||||
|
||||
@@ -4544,7 +4709,7 @@ run;
|
||||
|
||||
---
|
||||
|
||||
## `qsortincbyprocproto()` proto <a name="qsortincbyprocproto-proto-51"></a> ######
|
||||
## `qsortincbyprocproto()` proto <a name="qsortincbyprocproto-proto-53"></a> ######
|
||||
|
||||
## >>> `qsortInCbyProcProto()` proto function: <<< <a name="qsortincbyprocproto-proto-function"></a> #######################
|
||||
|
||||
@@ -4606,7 +4771,7 @@ Based on the code from the following pages [2020.08.14]:
|
||||
|
||||
---
|
||||
|
||||
## `frommissingtonumberbs()` function <a name="frommissingtonumberbs-functions-52"></a> ######
|
||||
## `frommissingtonumberbs()` function <a name="frommissingtonumberbs-functions-54"></a> ######
|
||||
|
||||
## >>> `fromMissingToNumberBS()` function: <<< <a name="frommissingtonumberbs-function"></a> #######################
|
||||
|
||||
@@ -4659,7 +4824,7 @@ fromMissingToNumberBS(x)
|
||||
|
||||
---
|
||||
|
||||
## `fromnumbertomissing()` function <a name="fromnumbertomissing-functions-53"></a> ######
|
||||
## `fromnumbertomissing()` function <a name="fromnumbertomissing-functions-55"></a> ######
|
||||
|
||||
## >>> `fromNumberToMissing()` function: <<< <a name="fromnumbertomissing-function"></a> #######################
|
||||
|
||||
@@ -4711,7 +4876,7 @@ fromNumberToMissing(x)
|
||||
|
||||
---
|
||||
|
||||
## `quicksort4notmiss()` function <a name="quicksort4notmiss-functions-54"></a> ######
|
||||
## `quicksort4notmiss()` function <a name="quicksort4notmiss-functions-56"></a> ######
|
||||
|
||||
## >>> `quickSort4NotMiss()` subroutine: <<< <a name="quicksort4notmiss-subroutine"></a> #######################
|
||||
|
||||
@@ -4805,7 +4970,7 @@ call quickSort4NotMiss(A)
|
||||
|
||||
---
|
||||
|
||||
## `quicksorthash()` function <a name="quicksorthash-functions-55"></a> ######
|
||||
## `quicksorthash()` function <a name="quicksorthash-functions-57"></a> ######
|
||||
|
||||
## >>> `quickSortHash()` subroutine: <<< <a name="quicksorthash-subroutine"></a> #######################
|
||||
|
||||
@@ -5046,7 +5211,7 @@ call quickSortHash(A)
|
||||
|
||||
---
|
||||
|
||||
## `quicksorthashsddv()` function <a name="quicksorthashsddv-functions-56"></a> ######
|
||||
## `quicksorthashsddv()` function <a name="quicksorthashsddv-functions-58"></a> ######
|
||||
|
||||
## >>> `quickSortHashSDDV()` subroutine: <<< <a name="quicksorthashsddv-subroutine"></a> #######################
|
||||
|
||||
@@ -5177,7 +5342,7 @@ call quickSortHashSDDV(A, SDDV)
|
||||
|
||||
---
|
||||
|
||||
## `quicksortlight()` function <a name="quicksortlight-functions-57"></a> ######
|
||||
## `quicksortlight()` function <a name="quicksortlight-functions-59"></a> ######
|
||||
|
||||
## >>> `quickSortLight()` subroutine: <<< <a name="quicksortlight-subroutine"></a> #######################
|
||||
|
||||
@@ -5386,7 +5551,7 @@ call quickSortLight(A)
|
||||
|
||||
---
|
||||
|
||||
## `%date()` macro <a name="date-macro-58"></a> ######
|
||||
## `%date()` macro <a name="date-macro-60"></a> ######
|
||||
|
||||
## >>> `%date()` macro: <<< <a name="date-macro"></a> #######################
|
||||
|
||||
@@ -5429,7 +5594,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%datetime()` macro <a name="datetime-macro-59"></a> ######
|
||||
## `%datetime()` macro <a name="datetime-macro-61"></a> ######
|
||||
|
||||
## >>> `%datetime()` macro: <<< <a name="datetime-macro"></a> #######################
|
||||
|
||||
@@ -5486,7 +5651,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%downloadfilesto()` macro <a name="downloadfilesto-macro-60"></a> ######
|
||||
## `%downloadfilesto()` macro <a name="downloadfilesto-macro-62"></a> ######
|
||||
|
||||
## >>> `%downloadFilesTo()` macro: <<< <a name="downloadfilesto-macro"></a> #######################
|
||||
|
||||
@@ -5618,7 +5783,111 @@ run;
|
||||
|
||||
---
|
||||
|
||||
## `%filepath()` macro <a name="filepath-macro-61"></a> ######
|
||||
## `%expanddatasetslist()` macro <a name="expanddatasetslist-macro-63"></a> ######
|
||||
|
||||
## >>> `%expandDataSetsList()` macro: <<< <a name="expanddatasetslist-macro"></a> #######################
|
||||
|
||||
The `%expandDataSetsList()` macro is dedicated to "lazy typers".
|
||||
|
||||
It allows to expand data set names provides in form of a SAS list for a given library.
|
||||
|
||||
See examples below for the details.
|
||||
|
||||
The `%expandDataSetsList()` macro works as pure macro code.
|
||||
|
||||
### SYNTAX: ###################################################################
|
||||
|
||||
The basic syntax is the following, the `<...>` means optional parameters:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%expandDataSetsList(
|
||||
lib
|
||||
,datasets
|
||||
<,quote=>
|
||||
<,views=>
|
||||
)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Arguments description**:
|
||||
|
||||
1. `lib` - *Required*, is a name of a library
|
||||
where data sets are looked-up.
|
||||
|
||||
2. `datasets` - *Required*, is a list of data sets or views
|
||||
to be expanded. Can be named list (e.g. `x_:`),
|
||||
can be enumerated list (e.g. `y_1-y_5`), or both.
|
||||
Also the `_ALL_` value is accepted.
|
||||
|
||||
*. `quote` - *Optional*, binary indicator (default `0` means "no").
|
||||
Tells if data set names should be quoted.
|
||||
|
||||
*. `views` - *Optional*, binary indicator (default `1` means "yes").
|
||||
Tells if views names should be listed too.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### EXAMPLES AND USECASES: ####################################################
|
||||
|
||||
**EXAMPLE 0.** Create data sets for tests:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data x_a x_b x_c x_d x_e x_f;
|
||||
x=17;
|
||||
run;
|
||||
data y1 y2 y3 y4 y9 y10 y11 y12;
|
||||
y=42;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 1.** Display names of listed datasets, handle not existing too:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%PUT #%expandDataSetsList(lib=work,datasets=x_: y1-y4 y9)#;
|
||||
|
||||
%PUT #%expandDataSetsList(lib=work,datasets=x_: y1-y4 notExist_1-notExist_10)#;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 2.** Display one and all datasets from `WORK`, names quoted:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%PUT %expandDataSetsList(lib=work,datasets=_ALL_, quote=1);
|
||||
|
||||
%PUT %expandDataSetsList(lib=work,datasets=x_a, quote=1);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 3.** In tandem with the `resolve()` function:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data _null_;
|
||||
test=resolve('%expandDataSetsList(lib=work,datasets=x_:, quote=1)');
|
||||
put test / test hex72.;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 4.** Workaround for `proc delete` not working with colon operator,
|
||||
observe a warning info for `x_:` list:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
proc delete lib=work data=%expandDataSetsList(lib=work,datasets=x_:)
|
||||
;
|
||||
run;
|
||||
|
||||
%PUT #%expandDataSetsList(lib=work,datasets=x_: y1-y4 y9)#;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 5.** Including and excluding views:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%PUT %expandDataSetsList(lib=sashelp,datasets=_ALL_);
|
||||
|
||||
%PUT %expandDataSetsList(lib=sashelp,datasets=_ALL_,views=0);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
## `%filepath()` macro <a name="filepath-macro-64"></a> ######
|
||||
|
||||
## >>> `%filePath()` macro: <<< <a name="filepath-macro"></a> #######################
|
||||
|
||||
@@ -5658,7 +5927,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%finddswithvarval()` macro <a name="finddswithvarval-macro-62"></a> ######
|
||||
## `%finddswithvarval()` macro <a name="finddswithvarval-macro-65"></a> ######
|
||||
|
||||
## >>> `%findDSwithVarVal()` macro: <<< <a name="finddswithvarval-macro"></a> #######################
|
||||
|
||||
@@ -5786,7 +6055,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%fmt()` macro <a name="fmt-macro-63"></a> ######
|
||||
## `%fmt()` macro <a name="fmt-macro-66"></a> ######
|
||||
|
||||
## >>> `%fmt()` macro: <<< <a name="fmt-macro"></a> #######################
|
||||
|
||||
@@ -5855,7 +6124,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%generateoneliners()` macro <a name="generateoneliners-macro-64"></a> ######
|
||||
## `%generateoneliners()` macro <a name="generateoneliners-macro-67"></a> ######
|
||||
|
||||
## >>> `%GenerateOneLiners()` macro: <<< <a name="generateoneliners-macro"></a> #######################
|
||||
|
||||
@@ -5973,7 +6242,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%gettitle()` macro <a name="gettitle-macro-65"></a> ######
|
||||
## `%gettitle()` macro <a name="gettitle-macro-68"></a> ######
|
||||
|
||||
## >>> `%getTitle()` macro: <<< <a name="gettitle-macro"></a> #######################
|
||||
|
||||
@@ -6059,7 +6328,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%iffunc()` macro <a name="iffunc-macro-66"></a> ######
|
||||
## `%iffunc()` macro <a name="iffunc-macro-69"></a> ######
|
||||
|
||||
## >>> `%iffunc()` macro: <<< <a name="iffunc-macro"></a> #######################
|
||||
|
||||
@@ -6260,7 +6529,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%infmt()` macro <a name="infmt-macro-67"></a> ######
|
||||
## `%infmt()` macro <a name="infmt-macro-70"></a> ######
|
||||
|
||||
## >>> `%infmt()` macro: <<< <a name="infmt-macro"></a> #######################
|
||||
|
||||
@@ -6317,7 +6586,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%letters()` macro <a name="letters-macro-68"></a> ######
|
||||
## `%letters()` macro <a name="letters-macro-71"></a> ######
|
||||
|
||||
## >>> `%letters()` macro: <<< <a name="letters-macro"></a> #######################
|
||||
|
||||
@@ -6435,7 +6704,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%libpath()` macro <a name="libpath-macro-69"></a> ######
|
||||
## `%libpath()` macro <a name="libpath-macro-72"></a> ######
|
||||
|
||||
## >>> `%libPath()` macro: <<< <a name="libpath-macro"></a> #######################
|
||||
|
||||
@@ -6480,7 +6749,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%minclude()` macro <a name="minclude-macro-70"></a> ######
|
||||
## `%minclude()` macro <a name="minclude-macro-73"></a> ######
|
||||
|
||||
## >>> `%mInclude()` macro: <<< <a name="minclude-macro"></a> #######################
|
||||
|
||||
@@ -6693,7 +6962,7 @@ quit;
|
||||
|
||||
---
|
||||
|
||||
## `%monthshift()` macro <a name="monthshift-macro-71"></a> ######
|
||||
## `%monthshift()` macro <a name="monthshift-macro-74"></a> ######
|
||||
|
||||
## >>> `%monthShift()` macro: <<< <a name="monthshift-macro"></a> #######################
|
||||
|
||||
@@ -6842,7 +7111,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%replist()` macro <a name="replist-macro-72"></a> ######
|
||||
## `%replist()` macro <a name="replist-macro-75"></a> ######
|
||||
|
||||
## >>> `%repList()` macro: <<< <a name="replist-macro"></a> #######################
|
||||
|
||||
@@ -6958,7 +7227,7 @@ run;
|
||||
|
||||
---
|
||||
|
||||
## `%time()` macro <a name="time-macro-73"></a> ######
|
||||
## `%time()` macro <a name="time-macro-76"></a> ######
|
||||
|
||||
## >>> `%time()` macro: <<< <a name="time-macro"></a> #######################
|
||||
|
||||
@@ -7001,7 +7270,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%today()` macro <a name="today-macro-74"></a> ######
|
||||
## `%today()` macro <a name="today-macro-77"></a> ######
|
||||
|
||||
## >>> `%today()` macro: <<< <a name="today-macro"></a> #######################
|
||||
|
||||
@@ -7044,7 +7313,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%translate()` macro <a name="translate-macro-75"></a> ######
|
||||
## `%translate()` macro <a name="translate-macro-78"></a> ######
|
||||
|
||||
## >>> `%translate()` macro: <<< <a name="translate-macro"></a> #######################
|
||||
|
||||
@@ -7108,7 +7377,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%tranwrd()` macro <a name="tranwrd-macro-76"></a> ######
|
||||
## `%tranwrd()` macro <a name="tranwrd-macro-79"></a> ######
|
||||
|
||||
## >>> `%tranwrd()` macro: <<< <a name="tranwrd-macro"></a> #######################
|
||||
|
||||
@@ -7175,7 +7444,118 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
---
|
||||
|
||||
## `%workpath()` macro <a name="workpath-macro-77"></a> ######
|
||||
## `%unifyvarscasesize()` macro <a name="unifyvarscasesize-macro-80"></a> ######
|
||||
|
||||
## >>> `%unifyVarsCaseSize()` macro: <<< <a name="unifyvarscasesize-macro"></a> #######################
|
||||
|
||||
The `%unifyVarsCaseSize()` macro converts *all* variables names into low-case or
|
||||
upcase letters for given library and list of datasets. Only necessary conversion is
|
||||
done, i.e., variable `abc` will not be converted to low-case letters.
|
||||
|
||||
See examples below for the details.
|
||||
|
||||
The `%unifyVarsCaseSize()` macro works as pure macro code.
|
||||
|
||||
[NOTE:] The macro internally uses the `%expandDataSetsList()` macro.
|
||||
|
||||
### SYNTAX: ###################################################################
|
||||
|
||||
The basic syntax is the following, the `<...>` means optional parameters:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%unifyVarsCaseSize(
|
||||
lib
|
||||
,ds
|
||||
<,case=>
|
||||
<,debug=>
|
||||
)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Arguments description**:
|
||||
|
||||
1. `lib` - *Required*, is a name of a library
|
||||
where data sets are looked-up.
|
||||
|
||||
2. `ds` - *Required*, is a list of data sets
|
||||
to be expanded. Can be named list (e.g. `x_:`),
|
||||
can be enumerated list (e.g. `y_1-y_5`), or both.
|
||||
Also the `_ALL_` value is accepted.
|
||||
|
||||
*. `case` - *Optional*, single letter indicator (default `L` means "low-case").
|
||||
Tells if variables names should low-cased (`l`,`L`) or upcased ("u", "U").
|
||||
|
||||
*. `debug` - *Optional*, binary indicator (default `0` means "no").
|
||||
Tells if processing notes should be printed.
|
||||
---
|
||||
|
||||
|
||||
### EXAMPLES AND USECASES: ####################################################
|
||||
|
||||
**EXAMPLE 0.** Create data sets for tests:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data aclass1 aclass2 aclass3 bclass4 bclass5 bclass6;
|
||||
set sashelp.class(obs=6);
|
||||
Nn=_N_;
|
||||
if 1=_N_ then output aclass1;
|
||||
if 2=_N_ then output aclass2;
|
||||
if 3=_N_ then output aclass3;
|
||||
if 4=_N_ then output bclass4;
|
||||
if 5=_N_ then output bclass5;
|
||||
if 6=_N_ then output bclass6;
|
||||
run;
|
||||
proc print data=aclass1;
|
||||
run;
|
||||
proc print data=bclass6;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 1.** Convert all variables names to low-case:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%unifyVarsCaseSize(work,aclass:)
|
||||
|
||||
proc print data=aclass1;
|
||||
proc print data=aclass2;
|
||||
proc print data=aclass3;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 2.** Convert all variables names to upcase:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%unifyVarsCaseSize(work,bclass4-bclass6,case=U)
|
||||
|
||||
proc print data=bclass4;
|
||||
proc print data=bclass5;
|
||||
proc print data=bclass6;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 3.** No conversion done:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data work.abc;
|
||||
abc=42;
|
||||
run;
|
||||
|
||||
%unifyVarsCaseSize(work,abc,debug=1)
|
||||
|
||||
proc print data=abc;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
**EXAMPLE 4.** Variables in all data sets in `WORK` converted to upcase:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
%unifyVarsCaseSize(work,_ALL_,case=L)
|
||||
%unifyVarsCaseSize(work,_ALL_,case=U)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
## `%workpath()` macro <a name="workpath-macro-81"></a> ######
|
||||
|
||||
## >>> `%workPath()` macro: <<< <a name="workpath-macro"></a> #######################
|
||||
|
||||
@@ -7218,7 +7598,7 @@ The basic syntax is the following, the `<...>` means optional parameters:
|
||||
|
||||
# License <a name="license"></a> ######
|
||||
|
||||
Copyright (c) 2020 - 2023 Bartosz Jablonski
|
||||
Copyright (c) 2020 - 2024 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
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user