SAS Packages Framework, version 20231107

## SAS Packages Framework, version `20231107`

Minor fix. An ugly note in log removed for `%loadPackageAddCnt()` macro.

## The BasePlus package [ver. 1.33.0]

- New macro [`%unzipArch()`](https://github.com/SASPAC/baseplus/blob/main/baseplus.md#unziparch-macro) added. The macro allows to extract ZIP archive file from SAS session and does not need `XCMD` (is OS independent).
- Documentation updated.

## The GSM package [ver. 0.22.0]

- Article explaining details of "macro hiding" added as an additional content to the package.

## The macroArray package [ver. 1.2.0]

- New parameters added to the [`%mcDictionary()`](https://github.com/SASPAC/macroarray/blob/main/macroarray.md#mcdictionary-macro) macro which allows to populate dictionary directly from a data set (see the last example in doc.).
- Documentation updated.
This commit is contained in:
Bart Jablonski
2023-11-07 12:35:34 +01:00
parent c4bb3ec6a6
commit ee5d4de333
22 changed files with 366 additions and 173 deletions

View File

@@ -61,7 +61,7 @@ SHA256 digest for DFA: F*09EA5201360922A91A9EEE72F4567792E9CFDFB591BA33419E2BF2B
---
- **macroArray**\[1.1.1\], implementation of an array concept in a macro language, e.g.
- **macroArray**\[1.2.0\], implementation of an array concept in a macro language, e.g.
```sas
%array(ABC[17] (111:127), macarray=Y);
@@ -80,13 +80,13 @@ SHA256 digest for DFA: F*09EA5201360922A91A9EEE72F4567792E9CFDFB591BA33419E2BF2B
which = 1:H:2
);
```
SHA256 digest for macroArray: F*E9C0C58FB36AC40C76A518066B8C6F9942202A9DB2C2D737E95D2BB6E4ECED50
SHA256 digest for macroArray: F*8689194590698F9A00B57FB37BE3CA8D7330F16B3E591CEAF49E6BE0B70D61D0
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
---
- **BasePlus**\[1.32.0\] adds a bunch of functionalities I am missing in BASE SAS, such as:
- **BasePlus**\[1.33.0\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```sas
call arrMissToRight(myArray);
call arrFillMiss(17, myArray);
@@ -114,22 +114,22 @@ format x bool.;
%put %monthShift(2023,1,-5);
```
SHA256 digest for BasePlus: F*3407AD8068C7528E129034144F9A44CFDF14B7DC34334C64C2F1D67351D1E01E
SHA256 digest for BasePlus: F*6214654B4575DC8E4BA3CF032924862C2F69A03A6384872BAA9F774EDF6A8DDA
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")
---
- **GSM** (Generate Secure Macros)\[0.21.1\], package allows
- **GSM** (Generate Secure Macros)\[0.22.0\], package allows
to create secured macros stored in SAS Proc FCMP functions.
The dataset with functions can be shared between different operating systems
and allows to generate macros on site without showing their code.
[Recording of presentation with "how it works" description (in Polish)](https://www.youtube.com/watch?v=LtaWPe2sgRY&t=1s "YouTube").
[The WUSS 2023 Conference article describing the idea](https://www.wuss.org/wuss-2023-conference-proceedings/ "Article about the idea GSM")
[The WUSS 2023 Conference article describing the idea](https://www.wuss.org/proceedings/2023/WUSS-2023-Paper-189.pdf "Article about the idea GSM")
SHA256 digest for GSM: F*2FECDDB568B38E206CA4ADA6FDEF5209C0A08B99401A1510D777BABF9DA54682
SHA256 digest for GSM: F*8D80AEB2DB7A4531BA124240E7A12EBE717293048561A877EB5B6B039BD11D18
[Documentation for GSM](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/gsm.md "Documentation for GSM")

View File

@@ -1,3 +1,8 @@
/* 20231107 */
BasePlus: F*6214654B4575DC8E4BA3CF032924862C2F69A03A6384872BAA9F774EDF6A8DDA
GSM: F*8D80AEB2DB7A4531BA124240E7A12EBE717293048561A877EB5B6B039BD11D18
macroArray: F*8689194590698F9A00B57FB37BE3CA8D7330F16B3E591CEAF49E6BE0B70D61D0
/* 20231026 */
BasePlus: F*3407AD8068C7528E129034144F9A44CFDF14B7DC34334C64C2F1D67351D1E01E

View File

@@ -45,6 +45,7 @@
* [`%RainCloudPlot()` macro](#raincloudplot-macro)
* [`%zipLibrary()` macro](#ziplibrary-macro)
* [`%unzipLibrary()` macro](#unziplibrary-macro)
* [`%unzipArch()` macro](#unzipatch-macro)
* [`%LDSN()` macro](#ldsn-macro)
* [`%LDsNm()` macro](#ldsnm-macro)
* [`%LVarNm()` macro](#lvarnm-macro)
@@ -78,7 +79,7 @@
---
# The BasePlus package [ver. 1.32.0] <a name="baseplus-package"></a> ###############################################
# The BasePlus package [ver. 1.33.0] <a name="baseplus-package"></a> ###############################################
The **BasePlus** package implements useful
functions and functionalities I miss in the BASE SAS.
@@ -357,78 +358,79 @@ run;
---
Package contains:
1. macro bppipe
2. macro deduplistc
3. macro deduplistp
4. macro deduplists
5. macro deduplistx
6. macro dirsandfiles
7. macro functionexists
8. macro getvars
9. macro intslist
10. macro ldsn
11. macro ldsnm
12. macro lvarnm
13. macro lvarnmlab
14. macro qdeduplistx
15. macro qgetvars
16. macro qzipevalf
17. macro raincloudplot
18. macro repeattxt
19. macro splitdsintoblocks
20. macro splitdsintoparts
21. macro symdelglobal
22. macro unziplibrary
23. macro zipevalf
24. macro ziplibrary
25. format bool
26. format boolz
27. format ceil
28. format floor
29. format int
30. function arrfill
31. function arrfillc
32. function arrmissfill
33. function arrmissfillc
34. function arrmisstoleft
35. function arrmisstoleftc
36. function arrmisstoright
37. function arrmisstorightc
38. function bracketsc
39. function bracketsn
40. function catxfc
41. function catxfi
42. function catxfj
43. function catxfn
44. function deldataset
45. function semicolonc
46. function semicolonn
47. format brackets
48. format semicolon
49. proto qsortincbyprocproto
50. function frommissingtonumberbs
51. function fromnumbertomissing
52. function quicksort4notmiss
53. function quicksorthash
54. function quicksorthashsddv
55. function quicksortlight
56. macro date
57. macro datetime
58. macro filepath
59. macro finddswithvarval
60. macro fmt
61. macro gettitle
62. macro infmt
63. macro letters
64. macro libpath
65. macro minclude
66. macro monthshift
67. macro replist
68. macro time
69. macro today
70. macro translate
71. macro tranwrd
72. macro workpath
1. macro bppipe
2. macro deduplistc
3. macro deduplistp
4. macro deduplists
5. macro deduplistx
6. macro dirsandfiles
7. macro functionexists
8. macro getvars
9. macro intslist
10. macro ldsn
11. macro ldsnm
12. macro lvarnm
13. macro lvarnmlab
14. macro qdeduplistx
15. macro qgetvars
16. macro qzipevalf
17. macro raincloudplot
18. macro repeattxt
19. macro splitdsintoblocks
20. macro splitdsintoparts
21. macro symdelglobal
22. macro unziparch
23. macro unziplibrary
24. macro zipevalf
25. macro ziplibrary
26. format bool
27. format boolz
28. format ceil
29. format floor
30. format int
31. function arrfill
32. function arrfillc
33. function arrmissfill
34. function arrmissfillc
35. function arrmisstoleft
36. function arrmisstoleftc
37. function arrmisstoright
38. function arrmisstorightc
39. function bracketsc
40. function bracketsn
41. function catxfc
42. function catxfi
43. function catxfj
44. function catxfn
45. function deldataset
46. function semicolonc
47. function semicolonn
48. format brackets
49. format semicolon
50. proto qsortincbyprocproto
51. function frommissingtonumberbs
52. function fromnumbertomissing
53. function quicksort4notmiss
54. function quicksorthash
55. function quicksorthashsddv
56. function quicksortlight
57. macro date
58. macro datetime
59. macro filepath
60. macro finddswithvarval
61. macro fmt
62. macro gettitle
63. macro infmt
64. macro letters
65. macro libpath
66. macro minclude
67. macro monthshift
68. macro replist
69. macro time
70. macro today
71. macro translate
72. macro tranwrd
73. macro workpath
@@ -436,10 +438,10 @@ Package contains additional content, run: %loadPackageAddCnt(BasePlus) to load
or look for the baseplus_AdditionalContent directory in the Packages fileref
localization (only if additional content was deployed during the installation process).
* SAS package generated by generatePackage, version 20231024 *
* SAS package generated by generatePackage, version 20231107 *
The SHA256 hash digest for package BasePlus:
`F*3407AD8068C7528E129034144F9A44CFDF14B7DC34334C64C2F1D67351D1E01E`
`F*6214654B4575DC8E4BA3CF032924862C2F69A03A6384872BAA9F774EDF6A8DDA`
---
# Content description ############################################################################################
@@ -3771,6 +3773,92 @@ run;
---
## >>> `%unzipArch()` macro: <<< <a name="unziparch-macro"></a> #######################
The unzipArch() macro allows to unzip content of a ZIP archive.
Macro is OS independent, the `XCMD` option is not required.
The `dlCreateDir` option is used under the hood.
Content of unzipped archive can be listed in the log.
Source files can be deleted after decompression.
Errors of decompression and are reported. If any occur
the deletion is suspended.
See examples below for the details.
### SYNTAX: ###################################################################
The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%unzipArch(
archName
<,path=>
<,target=>
<,list=>
<,clean=>
)
~~~~~~~~~~~~~~~~~~~~~~~
**Arguments description**:
1. `archName` - *Required*, name of the ZIP archive to be extracted.
Name should be full, i.e., with the extension.
* `path=` - *Optional*, a path pointing to zipped file location.
The path should be provided unquoted.
Default value is `WORK` location.
* `target=` - *Optional*, a path pointing to target location where
files will be extracted.
The path should be provided unquoted.
Default value is `WORK` location.
* `list = 0` - *Optional*, default value is `0`,
indicates if zip content should be listed in the log.
`1` means *yes*, `0` means *no*.
* `clean = 0` - *Optional*, default value is `0`,
indicates if zip file should be deleted after unzipping.
`1` means *yes*, `0` means *no*.
---
### EXAMPLES AND USECASES: ####################################################
**EXAMPLE 1.** Unzip compressed archive. Example requires the `basePlus` package.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
filename arch ZIP "%workPath()/testArch.zip";
data _null_;
file arch(abc/test1.txt);
put "text for test file 1";
data _null_;
file arch(abc/subdir/test2.txt);
put "text for test file 2";
data _null_;
file arch(abc/subdir/test3.txt);
put "text for test file 3";
run;
%unzipArch(
testArch.zip
, path = %workPath()
, target = %workPath()
, list=1
);
%unzipArch(
testArch.zip
, path = %workPath()
, target = %workPath()
, clean=1
);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## >>> `%LDSN()` macro: <<< <a name="ldsn-macro"></a> #######################
The LDSN (Long DataSet Names) macro function

Binary file not shown.

View File

@@ -8,7 +8,7 @@
---
# The GSM package [ver. 0.21.1] <a name="gsm-package"></a> ###############################################
# The GSM package [ver. 0.22.0] <a name="gsm-package"></a> ###############################################
The **GSM** (a.k.a. *Generate Secure Macros*) package allows
to create secured macros stored in SAS Proc FCMP functions.
@@ -94,10 +94,14 @@ Package contains:
Required SAS Components:
`Base SAS Software`
*SAS package generated by generatePackage, version 20230905*
Package contains additional content, run: %loadPackageAddCnt(GSM) to load it
or look for the gsm_AdditionalContent directory in the Packages fileref
localization (only if additional content was deployed during the installation process).
*SAS package generated by generatePackage, version 20231107*
The SHA256 hash digest for package GSM:
`F*2FECDDB568B38E206CA4ADA6FDEF5209C0A08B99401A1510D777BABF9DA54682`
`F*8D80AEB2DB7A4531BA124240E7A12EBE717293048561A877EB5B6B039BD11D18`
## >>> `%GSM()` macro: <<< <a name="gsm-macro"></a> #######################

Binary file not shown.

View File

@@ -19,7 +19,7 @@
---
# The macroArray package [ver. 1.1.1] <a name="macroarray-package"></a> ###############################################
# The macroArray package [ver. 1.2.0] <a name="macroarray-package"></a> ###############################################
The **macroArray** package implements a macro array facility:
- `%array()`,
@@ -75,10 +75,10 @@ Package contains:
Required SAS Components:
*Base SAS Software*
*SAS package generated by generatePackage, version 20230904*
*SAS package generated by generatePackage, version 20231107*
The SHA256 hash digest for package macroArray:
`F*E9C0C58FB36AC40C76A518066B8C6F9942202A9DB2C2D737E95D2BB6E4ECED50`
`F*8689194590698F9A00B57FB37BE3CA8D7330F16B3E591CEAF49E6BE0B70D61D0`
---
# Content description ############################################################################################
@@ -1556,6 +1556,9 @@ The basic syntax is the following, the `<...>` means optional parameters:
%mcDictionary(
H
<,METHOD>
<,DS=>
<,K=Key>
<,D=Data>
)
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1571,6 +1574,18 @@ The basic syntax is the following, the `<...>` means optional parameters:
If `DELETE` then the macro dictionary named by `H` and all
macrovariables named like "`&H._`" are deleted.
* `DS=` - *Optional*, if NOT empty then the `&DS.` dataset is used to
populate dictionary with keys from variable `&K.` and data
from variable `&D.` Works only during declaration.
* `K=` - *Optional*, if the `&DS.` is NOT empty then `&K.` holds a name of
a variable which keeps or an expression which generates keys values.
Default is `Key`.
* `D=` - *Optional*, if the `&DS.` is NOT empty then `&D.` holds a name of
a variable which keeps or an expression which generates data values.
Default is `Data`.
---
### THE CREATED MACRO `%&H.()`: ####################################################
@@ -1704,7 +1719,7 @@ See examples below to see use cases.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 2.** Populate macro dictionary from a dataset.
**EXAMPLE 2A.** Populate macro dictionary from a dataset "by hand".
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%mcDictionary(CLASS)
@@ -1714,6 +1729,7 @@ data _null_;
call execute('%CLASS(ADD,key=' !! name !! ',data=' !! age !! ')');
run;
%put t = %sysevalf(%sysfunc(datetime()) - &t.);
%put &=Class_KEYSNUM.;
%put _user_;
%CLASS(CLEAR)
@@ -1721,25 +1737,52 @@ run;
%mcDictionary(CARS)
%let t = %sysfunc(datetime());
data _null_;
set sashelp.cars;
call execute('%CARS(ADD,key=' !! catx("|",make,model,type) !! ',data=' !! MPG_CITY !! ')');
set sashelp.cars(obs=42);
call execute('%CARS(ADD,key=' !! catx("|",make,model,type) !! ',data=' !! put(MPG_CITY*10,dollar10.2) !! ')');
run;
%put t = %sysevalf(%sysfunc(datetime()) - &t.);
%put &=CARS_KEYSNUM.;
%CARS(LIST);
%put %CARS(F,key=Audi|TT 3.2 coupe 2dr (convertible)|Sports);
%CARS(CLEAR)
%put &=CARS_KEYSNUM.;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 3.** Data portion may require quoting and un-quoting..
**EXAMPLE 2B.** Populate macro dictionary from a dataset "automatically".
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%let t = %sysfunc(datetime());
%mcDictionary(CLASS,DCL,DS=sashelp.class,k=name,d=_N_)
%put t = %sysevalf(%sysfunc(datetime()) - &t.);
%put &=CLASS_KEYSNUM.;
%put _user_;
%CLASS(CLEAR)
%let t = %sysfunc(datetime());
%mcDictionary(CARS,DCL,DS=sashelp.cars(obs=42),k=catx("|",make,model,type),d=put(MPG_CITY*10,dollar10.2))
%put t = %sysevalf(%sysfunc(datetime()) - &t.);
%put &=CARS_KEYSNUM.;
%CARS(LIST);
%put %CARS(F,key=Audi|TT 3.2 coupe 2dr (convertible)|Sports);
%CARS(CLEAR)
%put &=CARS_KEYSNUM.;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 3.** Data portion may require quoting and un-quoting.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%mcDictionary(CODE)
%CODE(CLEAR)
%CODE(ADD,key=data, data=%str(data test; x = 42; run;))
%CODE(ADD,key=proc, data=%str(proc print; run;))
%CODE(ADD,key=macro,data=%nrstr(%put *****;))
%CODE(ADD,key=macro,data=%nrstr(%put *1*2*3*4*;))
%CODE(FIND,key=data)
%CODE(FIND,key=proc)
@@ -1765,6 +1808,7 @@ data _null_;
end;
run;
%put t = %sysevalf(%sysfunc(datetime()) - &t.);
%put %AAA(F,key=A555) %AAA(CHECK,key=A555);
%put &=AAA_KEYSNUM;
%AAA(CLEAR)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1780,6 +1824,43 @@ run;
%mcDictionary(ABCDEFGHIJKLMNOP) %* good;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 6.** More fun with datasets.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data work.metadata;
input key :$16. data :$128.;
cards;
ID ABC-123-XYZ
path /path/to/study/data
cutoffDT 2023-01-01
startDT 2020-01-01
endDT 2024-12-31
MedDRA v26.0
;
run;
proc print;
run;
%mcDictionary(Study,dcl,DS=work.metadata)
%put _user_;
%put *%Study(F,key=ID)**%Study(C,key=ID)*;
title1 "Study %Study(F,key=ID) is located at %Study(F,key=path)";
title2 "it starts %Study(F,key=startDT) and ends %Study(F,key=endDT)";
footnote "MedDRA version: %Study(F,key=MedDRA)";
proc print data=sashelp.class(obs=7);
run;
title;
footnote;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
## >>> `%QzipArrays()` macro: <<< <a name="qziparrays-macro"></a> #######################

Binary file not shown.