mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-06-08 19:30:20 +00:00
@@ -45,6 +45,11 @@ Videos presenting the SPF and packages, from various conferences and meetups (th
|
||||
- ["SAS Packages - State of the Union" - SaSensei International Dojo No. 13](https://www.youtube.com/watch?v=1GEldZYQjj0&t=0s "SID no. 13") (November 10th 2022, ~50 minutes, general overview with the latest technical details)
|
||||
- ["SAS Packages Framework - an easy code sharing medium for SAS" - Warsaw IT Days 2023](https://youtu.be/T52Omisi0dk&t=0s "Warsaw IT Days 2023") (March 31st 2023, ~60 minutes, general overview with technical details for user and developer)
|
||||
- ["SAS Package ー その共有、もっとスマートに" - SASユーザー総会 2025](https://youtu.be/4QRr7sUhO9E "SASユーザー総会2025") (September 25th 2025, ~22 minutes, general overview with the list of reasons: why is it worth to use SAS packages?)
|
||||
- ["SQLinDS and evExpress SAS packages - a tribute to SAS rock-stars!" - SAS Innovate 2026 Users Day](https://www.youtube.com/watch?v=ONSmt_l2TtU&t=6433s "SAS Innovate 2026 Users Day") (April 27th 2026, ~30 minutes, introduction to `SQLinDS` and `evExpress` SAS packages)
|
||||
- ["Introducing SAS Packages: A Modern Code Sharing Medium for SAS" - SAS Innovate 2026](https://drive.google.com/file/d/1zr7MC5Ca1Lb6TFwq6vbqaHv5DUFdNNYA/view?usp=sharing "SAS Innovate 2026") (April 28th 2026, ~36 minutes, general overview and itroduction to SAS packages)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Tutorials:
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
@@ -0,0 +1,735 @@
|
||||
/*
|
||||
# **Le petit SAS package**
|
||||
## a workshop about the "*Hello World*" SAS package.
|
||||
|
||||
by [**Bartosz Jabłoński**](https://linkedin.com/in/yabwon)
|
||||
|
||||
[LinkedIn](https://linkedin.com/in/yabwon)
|
||||
[GitHub](https://github.com/yabwon)
|
||||
|
||||
---
|
||||
|
||||
<!--  -->
|
||||
<img src="./le_petit_SAS_package.png" alt="Le petit SAS package" style="height:800px;"/>
|
||||
|
||||
|
||||
|
||||
---
|
||||
*/
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
## Links and locations
|
||||
|
||||
[**SAS Packages Framework**](https://github.com/yabwon/SAS_PACKAGES) - this is the place where the SAS Packages Framework lives.
|
||||
|
||||
|
||||
[**Hands on Workshop Materials**](https://github.com/yabwon/HoW-SASPackages) - this is the location for tutorial materials that will teach you how to work with SAS packages and that will take you "from 0 to hero" in SAS packages world.
|
||||
|
||||
[SPF's introductory video series](https://www.youtube.com/playlist?list=PLeMzGEImIT5eV13IGXQIgWmTFCJt_cLZG) - this is a YouTube introductory video series explaining the basics.
|
||||
|
||||
|
||||
[**SAS Packages Archive**](https://github.com/SASPAC) - some of publicly available SAS packages are located here.
|
||||
|
||||
[PharmaForest](https://github.com/PharmaForest) - pharma industry dedicated SAS packages are there.
|
||||
|
||||
---
|
||||
*/
|
||||
|
||||
options nofullstimer stimer nomprint nosymbolgen nomlogic;
|
||||
data _null_;
|
||||
put "WARNING- Welcome at NJSUG meetup!";
|
||||
run;
|
||||
|
||||
/*
|
||||
## autoexec.sas
|
||||
|
||||
I'm keeping my session setup in the `autoexec.sas` file.
|
||||
*/
|
||||
|
||||
/* this is an optional step - I basically have my session configuration in autoexec */
|
||||
/*
|
||||
%include "C:\SAS_WORK\autoexec.sas";
|
||||
|
||||
%put %workpath();
|
||||
|
||||
%put &sysLoadedPackages.;
|
||||
*/
|
||||
|
||||
/*
|
||||
But it can be replaced, for example, by something like this:
|
||||
*/
|
||||
|
||||
/* set "current working path" to WORK location */
|
||||
%put %sysfunc(DLGCDIR(%sysfunc(PATHNAME(work))));
|
||||
filename _ ".";
|
||||
filename _ list;
|
||||
filename _ clear;
|
||||
|
||||
|
||||
/* enable the SAS Packages Framework */
|
||||
filename packages "C:\SAS_WORK\SAS_PACKAGES"; /* filename packages "/sas/PACKAGES"; */
|
||||
%include packages(SPFinit.sas);
|
||||
|
||||
/* Load SAS packages */
|
||||
%loadPackageS(SQLinDS BasePlus)
|
||||
/* %loadPackageS(macroArray, DFA, GSM, bpUTiL, maxims4sas, evExpress) */
|
||||
|
||||
|
||||
resetline;
|
||||
/* List loaded packages */
|
||||
%put NOTE- SAS session with SAS Packages: &SYSLoadedPackages.;
|
||||
|
||||
%put NOTE- %workpath(); /* basePlus macro */
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
# Code types
|
||||
|
||||
SAS Packages can contain various code types, including:
|
||||
- macros,
|
||||
- FCMP functions,
|
||||
- formats & informats,
|
||||
- IML modules,
|
||||
- DS2 packages & threads,
|
||||
- CAS-L functions,
|
||||
- data sets,
|
||||
- libraries, etc.
|
||||
|
||||
Full list is provided in the [Training Materials](https://github.com/yabwon/HoW-SASPackages).
|
||||
|
||||
Today we will go with 3 basic: a macros, a function, and a format.
|
||||
*/
|
||||
|
||||
/*
|
||||
## A Macro
|
||||
|
||||
This macro prints the fox's quotes to the log.
|
||||
*/
|
||||
|
||||
resetline;
|
||||
|
||||
%macro fox(quote);
|
||||
%local n e w;
|
||||
%let n = NOTE;
|
||||
%let e = ERROR;
|
||||
%let w = WARNING;
|
||||
%if 1=%superq(quote) %then
|
||||
%do;
|
||||
%put &n.- And now here is my secret, a very simple secret:;
|
||||
%put &n.- It is only with the heart that one can see rightly%str(;);
|
||||
%put &n.- what is essential is invisible to the eye.;
|
||||
%end;
|
||||
%else
|
||||
%if 2=%superq(quote) %then
|
||||
%do;
|
||||
%put &w.- It is the time you have wasted for your rose;
|
||||
%put &w.- that makes your rose so important.;
|
||||
%put &w.- Men have forgotten this truth. But you must not forget it.;
|
||||
%put &w.- You become responsible, forever, for what you have tamed.;
|
||||
%put &w.- You are responsible for your rose...;
|
||||
%end;
|
||||
%else
|
||||
%do;
|
||||
%put &e.- One only understands the things that one tames.;
|
||||
%put &e.- Men have no more time to understand anything.;
|
||||
%put &e.- They buy things all ready made at the shops.;
|
||||
%put &e.- But there is no shop anywhere where one can buy friendship,;
|
||||
%put &e.- and so men have no friends any more. If you want a friend, tame me...;
|
||||
%end;
|
||||
%mend fox;
|
||||
|
||||
%fox(1)
|
||||
%fox(2)
|
||||
%fox()
|
||||
|
||||
/*
|
||||
## A Format
|
||||
|
||||
This format displays values from 1 to 4 as rose's quotes.
|
||||
*/
|
||||
|
||||
resetline;
|
||||
|
||||
PROC FORMAT;
|
||||
value rose
|
||||
1="Ah! I am scarcely awake. I beg that you will excuse me. My petals are still all disarranged..."
|
||||
2="Of course I love you. It is my fault that you have not known it all the while. [...] Try to be happy..."
|
||||
3="My cold is not so bad as all that... The cool night air will do me good. I am a flower."
|
||||
4="Well, I must endure the presence of two or three caterpillars if I wish to become acquainted with the butterflies."
|
||||
other="ERROR: QUOTE OUT OF RANGE!"
|
||||
;
|
||||
RUN;
|
||||
|
||||
|
||||
data _null_;
|
||||
do i = 1 to 5;
|
||||
put "NOTE- " i rose. /;
|
||||
end;
|
||||
run;
|
||||
|
||||
/*
|
||||
## A Function
|
||||
|
||||
This FCMP function returns the prince's quote: "*If you please--draw me a sheep!*", and generates random rose's quote in the LOG.
|
||||
*/
|
||||
|
||||
resetline;
|
||||
|
||||
PROC FCMP outlib=work.little.prince;
|
||||
function prince() $ 42;
|
||||
file log;
|
||||
|
||||
length i $ 256;
|
||||
r=rand('integer',1,4);
|
||||
i = put(r, rose.);
|
||||
put @1 "RANDOM NOTE:" i /;
|
||||
|
||||
return("If you please--draw me a sheep!");
|
||||
endfunc;
|
||||
QUIT;
|
||||
|
||||
proc options option=cmplib;
|
||||
run;
|
||||
|
||||
/*
|
||||
For an FCMP function to work the `CMPLIB` option has to be updated.
|
||||
*/
|
||||
|
||||
options append=(cmplib=work.little);
|
||||
|
||||
proc options option=cmplib;
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
do i = 1 to 5;
|
||||
prince=prince();
|
||||
rc=sleep(1,0.2);
|
||||
end;
|
||||
put prince=;
|
||||
run;
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
# **##############################**
|
||||
|
||||
# *If you please - build me a SAS package!*
|
||||
|
||||
# **##############################**
|
||||
|
||||
---
|
||||
*/
|
||||
|
||||
/*
|
||||
## The Directory
|
||||
|
||||
In the firs step, a directory for the package source has to be created.
|
||||
*/
|
||||
|
||||
options dlcreatedir;
|
||||
%let dir = R:\NJSUG\LePetitSASpackageDirectory;
|
||||
|
||||
libname p "&dir.";
|
||||
|
||||
libname p list;
|
||||
|
||||
/*
|
||||
## The Description
|
||||
|
||||
This is the **description** file for the package.
|
||||
|
||||
It should be named `description.sas` and located in the package source directory.
|
||||
|
||||
The colon (`:`) is a field separator and is restricted in lines of the header part.
|
||||
|
||||
The part between `DESCRIPTION START:` and `DESCRIPTION END:` is a "free format" text part where the developer provides package description, additional notes, information, etc.
|
||||
*/
|
||||
|
||||
/* **HEADER** */
|
||||
Type: Package
|
||||
Package: LePetitSASpackage
|
||||
Title: Le petit SAS package - a workshop about the "*Hello World*" SAS package.
|
||||
Version: 0.0.1
|
||||
Author: Bartosz Jablonski
|
||||
Maintainer: Bartosz Jablonski (yabwon@gmail.com)
|
||||
License: MIT
|
||||
Encoding: UTF8
|
||||
|
||||
Required: "Base SAS Software"
|
||||
ReqPackages: "SQLinDS(2.3.3)"
|
||||
|
||||
|
||||
/* **DESCRIPTION** */
|
||||
/* All the text below will be used for help notes */
|
||||
DESCRIPTION START:
|
||||
|
||||
The **LePetitSASpackage** package is an implementation
|
||||
of a little "*Hello World*" SAS package presented during
|
||||
**NJSUG** meetup.
|
||||
|
||||
It is build for fun, but also (or foremost) to show us
|
||||
how easy it is to build SAS packages.
|
||||
|
||||
*"I have serious reason to believe that the planet from which
|
||||
the little package came is the asteroid known as B612.
|
||||
This asteroid has only once been seen through the telescope.
|
||||
That was by a Turkish astronomer, in 1909."*
|
||||
|
||||
---
|
||||
|
||||
DESCRIPTION END:
|
||||
|
||||
/*
|
||||
[**NOTE**] The `SQLinDS` package is added as a dependency just to show the it can be done. In normal circumstances, when a package doesn't have dependencies the `ReqPackage:` tag is skipped. The `Required:` tag is also just for demonstration.
|
||||
*/
|
||||
|
||||
/*
|
||||
## The Directory, cont.
|
||||
*/
|
||||
|
||||
/*
|
||||
### Ordering
|
||||
|
||||
Code files have to be placed in proper type-directories. And ordered accordingly. In this case teh following setup will work.
|
||||
*/
|
||||
|
||||
/* 01_macro -> fox.sas */
|
||||
|
||||
/* 02_formats -> rose.sas */
|
||||
|
||||
/* 03_functions -> prince.sas */
|
||||
|
||||
/*
|
||||
Directories structure can be easily created by ourselves with the `dlcreatedir` option. If the option is not available, then it can be done by hand.
|
||||
*/
|
||||
|
||||
resetline;
|
||||
options dlcreatedir;
|
||||
|
||||
libname p "&dir.\01_macro";
|
||||
libname p "&dir.\02_formats";
|
||||
libname p "&dir.\03_functions";
|
||||
|
||||
libname p clear;
|
||||
|
||||
/*
|
||||
## Code Preparation
|
||||
*/
|
||||
|
||||
/*
|
||||
### Help Notes
|
||||
*/
|
||||
|
||||
/*** HELP START ***//*
|
||||
|
||||
This is a little help note.
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
/*** HELP START ***//*
|
||||
|
||||
The `%fox()` macro prints what does the fox says...
|
||||
|
||||
---
|
||||
|
||||
### Syntax: ###############################
|
||||
|
||||
~~~~~~~~~~sas
|
||||
%fox(<quote>)
|
||||
~~~~~~~~~~
|
||||
|
||||
### Arguments: ############################
|
||||
|
||||
- `quote` - The number of fox's quote.
|
||||
When missing or incorrect,
|
||||
the default quote is displayed.
|
||||
|
||||
|
||||
### Example: ##############################
|
||||
|
||||
Print quote number 1:
|
||||
~~~~~~~~~~sas
|
||||
%fox(1)
|
||||
~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
/*** HELP START ***//*
|
||||
|
||||
The `rose.` format prints what does the rose says...
|
||||
|
||||
---
|
||||
|
||||
### Example: ##############################
|
||||
|
||||
Print quote number 2:
|
||||
~~~~~~~~~~sas
|
||||
data _null_;
|
||||
r=2;
|
||||
put r rose.;
|
||||
run;
|
||||
~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
/*** HELP START ***//*
|
||||
|
||||
The `prince()` function asks to draw a sheep...
|
||||
|
||||
---
|
||||
|
||||
### Arguments: ############################
|
||||
|
||||
The function has no arguments.
|
||||
|
||||
### Dependencies: #########################
|
||||
|
||||
The `prince()` function requires
|
||||
the `rose.` format to work.
|
||||
|
||||
### Example: ##############################
|
||||
|
||||
Ask for a sheep:
|
||||
~~~~~~~~~~sas
|
||||
data _null_;
|
||||
s=prince();
|
||||
put s=;
|
||||
run;
|
||||
~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
/*
|
||||
### One file - one object
|
||||
*/
|
||||
|
||||
resetline;
|
||||
|
||||
/* 01_macro -> fox.sas */
|
||||
filename f "&dir.\01_macro\fox.sas";
|
||||
data _null_;
|
||||
file f;
|
||||
infile CARDS4;
|
||||
input;
|
||||
put _infile_;
|
||||
CARDS4;
|
||||
/*** HELP START ***//*
|
||||
|
||||
The `%fox()` macro prints what does the fox says...
|
||||
|
||||
---
|
||||
|
||||
### Syntax: ###############################
|
||||
|
||||
~~~~~~~~~~sas
|
||||
%fox(<quote>)
|
||||
~~~~~~~~~~
|
||||
|
||||
### Arguments: ############################
|
||||
|
||||
- `quote` - The number of fox's quote.
|
||||
When missing or incorrect,
|
||||
the default quote is displayed.
|
||||
|
||||
|
||||
### Example: ##############################
|
||||
|
||||
Print quote number 1:
|
||||
~~~~~~~~~~sas
|
||||
%fox(1)
|
||||
~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
%macro fox(quote);
|
||||
%local n e w;
|
||||
%let n = NOTE;
|
||||
%let e = ERROR;
|
||||
%let w = WARNING;
|
||||
%if 1=%superq(quote) %then
|
||||
%do;
|
||||
%put &n.- And now here is my secret, a very simple secret:;
|
||||
%put &n.- It is only with the heart that one can see rightly%str(;);
|
||||
%put &n.- what is essential is invisible to the eye.;
|
||||
%end;
|
||||
%else
|
||||
%if 2=%superq(quote) %then
|
||||
%do;
|
||||
%put &w.- It is the time you have wasted for your rose;
|
||||
%put &w.- that makes your rose so important.;
|
||||
%put &w.- Men have forgotten this truth. But you must not forget it.;
|
||||
%put &w.- You become responsible, forever, for what you have tamed.;
|
||||
%put &w.- You are responsible for your rose...;
|
||||
%end;
|
||||
%else
|
||||
%do;
|
||||
%put &e.- One only understands the things that one tames.;
|
||||
%put &e.- Men have no more time to understand anything.;
|
||||
%put &e.- They buy things all ready made at the shops.;
|
||||
%put &e.- But there is no shop anywhere where one can buy friendship,;
|
||||
%put &e.- and so men have no friends any more. If you want a friend, tame me...;
|
||||
%end;
|
||||
%mend fox;
|
||||
;;;;
|
||||
run;
|
||||
|
||||
/* 02_formats -> rose.sas */
|
||||
filename f "&dir.\02_formats\rose.sas";
|
||||
data _null_;
|
||||
file f;
|
||||
infile CARDS4;
|
||||
input;
|
||||
put _infile_;
|
||||
CARDS4;
|
||||
/*** HELP START ***//*
|
||||
|
||||
The `rose.` format prints what does the rose says...
|
||||
|
||||
---
|
||||
|
||||
### Example: ##############################
|
||||
|
||||
Print quote number 2:
|
||||
~~~~~~~~~~sas
|
||||
data _null_;
|
||||
r=2;
|
||||
put r rose.;
|
||||
run;
|
||||
~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
value rose
|
||||
1="Ah! I am scarcely awake. I beg that you will excuse me. My petals are still all disarranged..."
|
||||
2="Of course I love you. It is my fault that you have not known it all the while. [...] Try to be happy..."
|
||||
3="My cold is not so bad as all that... The cool night air will do me good. I am a flower."
|
||||
4="Well, I must endure the presence of two or three caterpillars if I wish to become acquainted with the butterflies."
|
||||
other="ERROR: QUOTE OUT OF RANGE!"
|
||||
;
|
||||
;;;;
|
||||
run;
|
||||
|
||||
/* 03_functions -> prince.sas */
|
||||
filename f "&dir.\03_functions\prince.sas";
|
||||
data _null_;
|
||||
file f;
|
||||
infile CARDS4;
|
||||
input;
|
||||
put _infile_;
|
||||
CARDS4;
|
||||
/*** HELP START ***//*
|
||||
|
||||
The `prince()` function asks to draw a sheep...
|
||||
|
||||
---
|
||||
|
||||
### Arguments: ############################
|
||||
|
||||
The function has no arguments.
|
||||
|
||||
### Dependencies: #########################
|
||||
|
||||
The `prince()` function requires
|
||||
the `rose.` format to work.
|
||||
|
||||
### Example: ##############################
|
||||
|
||||
Ask for a sheep:
|
||||
~~~~~~~~~~sas
|
||||
data _null_;
|
||||
s=prince();
|
||||
put s=;
|
||||
run;
|
||||
~~~~~~~~~~
|
||||
|
||||
---
|
||||
|
||||
*//*** HELP END ***/
|
||||
|
||||
function prince() $ 42;
|
||||
file log;
|
||||
|
||||
length i $ 256;
|
||||
r=rand('integer',1,4);
|
||||
i = put(r, rose.);
|
||||
put @1 "RANDOM NOTE:" i /;
|
||||
|
||||
return("If you please--draw me a sheep!");
|
||||
endfunc;
|
||||
;;;;
|
||||
run;
|
||||
|
||||
/*
|
||||
### Tests
|
||||
|
||||
Tests are optionally available, i.e., they are available if the `XCMD` option is on.
|
||||
|
||||
One test of loading a package is always automatically executed. All other tests are developer's job to do.
|
||||
|
||||
The SPF automatically points to the package location for tests, developer doesn't have to worry.
|
||||
*/
|
||||
|
||||
resetline;
|
||||
options dlcreatedir;
|
||||
|
||||
libname p "&dir.\99_test";
|
||||
libname p clear;
|
||||
|
||||
/* 99_test -> test_success.sas */
|
||||
filename f "&dir.\99_test\test_success.sas";
|
||||
data _null_;
|
||||
file f;
|
||||
infile CARDS4;
|
||||
input;
|
||||
put _infile_;
|
||||
CARDS4;
|
||||
%put testing macro:;
|
||||
%fox(1)
|
||||
%fox(2)
|
||||
%fox()
|
||||
|
||||
data _null_;
|
||||
put "Testing format:";
|
||||
do i = 1 to 4;
|
||||
put "NOTE- " i rose. /;
|
||||
end;
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
put "Testing function:";
|
||||
do i = 1 to 5;
|
||||
prince=prince();
|
||||
rc=sleep(1,0.2);
|
||||
end;
|
||||
put;
|
||||
run;
|
||||
;;;;
|
||||
run;
|
||||
|
||||
/* 99_test -> test_fail_e1w0.sas */
|
||||
filename f "&dir.\99_test\test_fail_e1w0.sas";
|
||||
data _null_;
|
||||
file f;
|
||||
infile CARDS4;
|
||||
input;
|
||||
put _infile_;
|
||||
CARDS4;
|
||||
data _null_;
|
||||
put "Testing format (should print error):";
|
||||
do i = 5;
|
||||
put i rose. /;
|
||||
end;
|
||||
run;
|
||||
;;;;
|
||||
run;
|
||||
|
||||
/*
|
||||
## Generate Package
|
||||
|
||||
In this session we already have the SPF enabled, but in the development process you have to point the location for packages and enable the framework.
|
||||
*/
|
||||
|
||||
filename packages "C:\SAS_WORK\SAS_PACKAGES";
|
||||
%include packages(SPFinit.sas);
|
||||
|
||||
/*
|
||||
Options can be easily reminded (in he LOG) by calling the macro with the `HELP` keyword.
|
||||
*/
|
||||
|
||||
%generatePackage(HELP)
|
||||
|
||||
resetline;
|
||||
|
||||
/* Generate Package */
|
||||
|
||||
%generatePackage(
|
||||
R:\NJSUG\LePetitSASpackageDirectory
|
||||
,markdownDoc=1
|
||||
,packages=C:\SAS_WORK\SAS_PACKAGES
|
||||
)
|
||||
|
||||
/* REMEMBER! Always check the log.*/
|
||||
|
||||
/*
|
||||
# --The End--
|
||||
|
||||
The package is ready! It can be shared with other SAS programmers now.
|
||||
|
||||
---
|
||||
*/
|
||||
|
||||
/*
|
||||
#
|
||||
|
||||
##
|
||||
|
||||
###
|
||||
|
||||
---
|
||||
|
||||
# Start New SAS Session
|
||||
|
||||
In a brand new SAS session try out how the created package works.
|
||||
*/
|
||||
|
||||
/* create directory for SAS packages */
|
||||
|
||||
resetline;
|
||||
options dlcreatedir;
|
||||
libname p "R:\NJSUG\trySASpackages";
|
||||
libname p clear;
|
||||
|
||||
/* install the SAS Packages Framework and the SQLinDS package */
|
||||
|
||||
filename packages "R:\NJSUG\trySASpackages";
|
||||
|
||||
filename SPFinit url "https://bit.ly/SPFinit";
|
||||
%include SPFinit; /* enable the framework */
|
||||
filename SPFinit clear;
|
||||
|
||||
%installPackage(SPFinit SQLinDS)
|
||||
|
||||
/*
|
||||
Copy, manually for now, the LePetitSASpackage (the zip file) to packages directory.
|
||||
*/
|
||||
|
||||
/* enable the SPF and load the LePetitSASpackage */
|
||||
|
||||
filename packages "R:\NJSUG\trySASpackages";
|
||||
%include packages(SPFinit.sas);
|
||||
%listPackages()
|
||||
|
||||
|
||||
%loadPackage(LePetitSASpackage)
|
||||
|
||||
/* try it */
|
||||
%fox(1)
|
||||
%fox(2)
|
||||
|
||||
%put %sysfunc(prince());
|
||||
|
||||
data _null_;
|
||||
p = prince();
|
||||
put p=;
|
||||
run;
|
||||
|
||||
/*
|
||||
---
|
||||
*/
|
||||
|
||||
/*
|
||||
---
|
||||
*/
|
||||
File diff suppressed because one or more lines are too long
+7
-7
@@ -10,7 +10,7 @@ Packages:
|
||||
|
||||
---
|
||||
|
||||
- **SQLinDS**\[2.3.3\], based on Mike Rhoads' article *Use the Full Power of SAS in Your Function-Style Macros*. The package allows to write SQL queries in the data step, e.g.
|
||||
- **SQLinDS**\[2.4.0\], based on Mike Rhoads' article *Use the Full Power of SAS in Your Function-Style Macros*. The package allows to write SQL queries in the data step, e.g.
|
||||
```sas
|
||||
data class;
|
||||
set %SQL(
|
||||
@@ -22,9 +22,9 @@ data class;
|
||||
WH = weight + height;
|
||||
run;
|
||||
```
|
||||
SHA256 digest for SQLinDS: F*6CC51325BDCE164B2E811896DD1C3A6D44242F50CC313D0721350CA49975F628
|
||||
SHA256 digest for SQLinDS: F*A3DC9400DEF1403DC9E191611790244A8B0FB23303D3A98D29777E46A1D4E8B4
|
||||
|
||||
[Documentation for SQLinDS](https://github.com/SASPAC/blob/main/sqlinds.md "Documentation for SQLinDS")
|
||||
[Documentation for SQLinDS](https://github.com/SASPAC/sqlinds/blob/main/sqlinds.md "Documentation for SQLinDS")
|
||||
|
||||
---
|
||||
|
||||
@@ -57,7 +57,7 @@ run;
|
||||
```
|
||||
SHA256 digest for DFA: F*C1E5126D8EDE050A758BCB5DCCA56A37125B3646CE75F1CF41EDE00890901AD9
|
||||
|
||||
[Documentation for DFA](https://github.com/SASPAC/blob/main/dfa.md "Documentation for DFA")
|
||||
[Documentation for DFA](https://github.com/SASPAC/dfa/blob/main/dfa.md "Documentation for DFA")
|
||||
|
||||
---
|
||||
|
||||
@@ -82,7 +82,7 @@ SHA256 digest for DFA: F*C1E5126D8EDE050A758BCB5DCCA56A37125B3646CE75F1CF41EDE00
|
||||
```
|
||||
SHA256 digest for macroArray: F*35A657517CD2B1AB86C4E7C5320B5EDDDFBA9348075AE31DDAF875CF0CC193C9
|
||||
|
||||
[Documentation for macroArray](https://github.com/SASPAC/blob/main/macroarray.md "Documentation for macroArray")
|
||||
[Documentation for macroArray](https://github.com/SASPAC/macroarray/blob/main/macroarray.md "Documentation for macroArray")
|
||||
|
||||
---
|
||||
|
||||
@@ -122,7 +122,7 @@ format x bool.;
|
||||
```
|
||||
SHA256 digest for BasePlus: F*BD248E5F8CBD94B5F45467B723A73D97D646CD665BA98679F87C7A03A484E83E
|
||||
|
||||
[Documentation for BasePlus](https://github.com/SASPAC/blob/main/baseplus.md "Documentation for BasePlus")
|
||||
[Documentation for BasePlus](https://github.com/SASPAC/baseplus/blob/main/baseplus.md "Documentation for BasePlus")
|
||||
|
||||
---
|
||||
|
||||
@@ -137,7 +137,7 @@ SHA256 digest for BasePlus: F*BD248E5F8CBD94B5F45467B723A73D97D646CD665BA98679F8
|
||||
|
||||
SHA256 digest for GSM: F*411452E8388C181800023A01A3B7DC7904A80A915D506D9606638F27CBC282B1
|
||||
|
||||
[Documentation for GSM](https://github.com/SASPAC/blob/main/gsm.md "Documentation for GSM")
|
||||
[Documentation for GSM](https://github.com/SASPAC/gsm/blob/main/gsm.md "Documentation for GSM")
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* 20260511 */
|
||||
SQLinDS: F*A3DC9400DEF1403DC9E191611790244A8B0FB23303D3A98D29777E46A1D4E8B4
|
||||
|
||||
/* 20260217 */
|
||||
BasePlus: F*BD248E5F8CBD94B5F45467B723A73D97D646CD665BA98679F87C7A03A484E83E
|
||||
DFA: F*C1E5126D8EDE050A758BCB5DCCA56A37125B3646CE75F1CF41EDE00890901AD9
|
||||
|
||||
+27
-11
@@ -9,17 +9,17 @@
|
||||
### Version information:
|
||||
|
||||
- Package: SQLinDS
|
||||
- Version: 2.3.3
|
||||
- Generated: 2026-02-17T08:25:24
|
||||
- Version: 2.4.0
|
||||
- Generated: 2026-05-11T14:15:07
|
||||
- Author(s): Mike Rhoads (RhoadsM1@Westat.com), contributor Bartosz Jablonski
|
||||
- Maintainer(s): Bartosz Jablonski (yabwon@gmail.com)
|
||||
- License: MIT
|
||||
- File SHA256: `F*6CC51325BDCE164B2E811896DD1C3A6D44242F50CC313D0721350CA49975F628` for this version
|
||||
- Content SHA256: `C*776741E40EB6DCD907640ACA674F092BFAF0F7DE031519B6B453D37F6D6959D9` for this version
|
||||
- File SHA256: `F*A3DC9400DEF1403DC9E191611790244A8B0FB23303D3A98D29777E46A1D4E8B4` for this version
|
||||
- Content SHA256: `C*4A49F365C4EF8C5523393FDC1E11C344B023F449B3F1759BA27CFC6C1293A499` for this version
|
||||
|
||||
---
|
||||
|
||||
# The `SQLinDS` package, version: `2.3.3`;
|
||||
# The `SQLinDS` package, version: `2.4.0`;
|
||||
|
||||
---
|
||||
|
||||
@@ -75,9 +75,9 @@ localization (only if additional content was deployed during the installation pr
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
*SAS package generated by SAS Package Framework, version `20260216`,*
|
||||
*SAS package generated by SAS Package Framework, version `20260411`,*
|
||||
*under `WIN`(`X64_10PRO`) operating system,*
|
||||
*using SAS release: `9.04.01M9P06042025`.*
|
||||
*using SAS release: `9.04.01M9P06052025`.*
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
@@ -155,18 +155,18 @@ Copy of the article can also be found in *additional content* directory.
|
||||
%sql(<nonempty Proc SQL query code>)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The THE query code is limited to approximately *32000* bytes.
|
||||
The query code is limited to approximately *32000* bytes.
|
||||
|
||||
### EXAMPLES: #################################################################
|
||||
|
||||
**EXAMPLE 1**: simple SQL query
|
||||
**EXAMPLE 1**: A simple SQL query.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data class_subset;
|
||||
set %SQL(select name, sex, height from sashelp.class where age > 12);
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**EXAMPLE 2**: query with dataset options
|
||||
**EXAMPLE 2**: A query with dataset options.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data renamed;
|
||||
set %SQL(select name, age from sashelp.class
|
||||
@@ -175,12 +175,28 @@ data renamed;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**EXAMPLE 3**: Proc SQL dictionaries in the data step
|
||||
**EXAMPLE 3**: Proc SQL dictionaries in the data step.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data dictionary;
|
||||
set %SQL(select dict.* from dictionary.macros as dict);
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**EXAMPLE 4**: Use Proc SQL to populate hash table.
|
||||
Call to `%SQL()` has to be in double-quotes.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
|
||||
data _null_;
|
||||
if 0 then set %SQL(SELECT name, age FROM sashelp.class);
|
||||
|
||||
declare hash H (dataset: "%SQL(SELECT name, age FROM sashelp.class)") ;
|
||||
H.defineKey("age");
|
||||
H.defineKey("name");
|
||||
H.defineDone();
|
||||
|
||||
H.output(dataset:"output");
|
||||
stop;
|
||||
run;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
---
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user