Concaténation macro SAS

Bonjour à tous,

Pour suivre les bonnes pratiques, j’ai créé une macro, qui pour tous les mois d’une année, extrait des prestations selon une liste de codes LPP, et concatène les mois dans la même base à la fin de la macro :

data seq_all;
set %do i = 2 %to %eval(&nb_mois+1); tab_&annee._&i %end;
run;

J’exécute ensuite la macro par année.

J’aimerais bien pouvoir concaténer toutes les années, comment faire pour ajouter à chaque fois les bases extraites sans écraser les années précédentes ?

Par avance, merci

Victor

Bonjour,

Je pense qu’il y a différentes manières de faire mais il me semble que la procédure SAS proc append permet de réaliser l’opération que vous souhaitez faire assez simplement.

Cette procédure permet d’ajouter des tables au fur et à mesure dans une table cible avec la syntaxe suivante :

proc append 
base=table_cible_totale 
data=table_annuelle_a_ajouter;
run;

En espérant que cela réponde bien à votre question,

Bien cordialement,

Tim Vlaar - Health Data Hub

Merci pour votre réponse. J’ai maintenant un souci d’interaction entre la macro, SQL, SAS et oracle. Pourriez-vous m’aider à corriger le code suivant ?
Merci !

%macro audio(annee,mois_deb,nb_mois);

%do i = 1 %to &nb_mois;
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

PROC SQL;
%connectora;

create table tab_&annee._&val as (select * from connection to oracle(
SELECT t2.TIP_PRS_IDE,
t1.EXE_SOI_DTD,
t1.BEN_NIR_PSA,
t1.BEN_RNG_GEM,
t1.BEN_CMU_TOP
FROM ER_PRS_F t1, ER_TIP_F t2
WHERE t1.DCT_ORD_NUM = t2.DCT_ORD_NUM
AND t1.FLX_DIS_DTD = t2.FLX_DIS_DTD
AND t1.FLX_EMT_NUM = t2.FLX_EMT_NUM
AND t1.FLX_EMT_ORD = t2.FLX_EMT_ORD
AND t1.FLX_EMT_TYP = t2.FLX_EMT_TYP
AND t1.FLX_TRT_DTD = t2.FLX_TRT_DTD
AND t1.ORG_CLE_NUM = t2.ORG_CLE_NUM
AND t1.PRS_ORD_NUM = t2.PRS_ORD_NUM
AND t1.REM_TYP_AFF = t2.REM_TYP_AFF
AND t1.EXE_SOI_DTD >= TO_DATE (&annee.0101, ‹ YYYYMMDD ›)
AND t1.FLX_DIS_DTD = add_months(to_date(&annee.&mois_deb.01,‹ YYYYMMDD ›),&i)
AND t2.TIP_PRS_IDE IN (…)));

      disconnect from oracle;

QUIT;
%END;

data tab_&annee.;
set %do i = 1 %to %eval(&nb_mois);
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);
tab_&annee._&val;
%end;
run;

proc append
base=table_tot
data=table_&annee.;
run;

%mend audio;

%AUDIO(2013,1,12);
%AUDIO(2014,1,12);
%AUDIO(2015,1,12);
%AUDIO(2016,1,12);
%AUDIO(2017,1,12);
%AUDIO(2018,1,12);
%AUDIO(2019,1,12);
%AUDIO(2020,1,12);
%AUDIO(2021,1,12);

Bonjour,

J’ai apporté quelques modifications dans votre code, qui devrait fonctionner maintenant (exemple pour le code LPP 1100028) :

%macro audio(annee,mois_deb,nb_mois);

%do i = 1 %to &nb_mois;
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

PROC SQL;
%connectora;

create table tab_&annee._&val as select * from connection to oracle(
SELECT t2.TIP_PRS_IDE,
t1.EXE_SOI_DTD,
t1.BEN_NIR_PSA,
t1.BEN_RNG_GEM,
t1.BEN_CMU_TOP
FROM ER_PRS_F t1, ER_TIP_F t2
WHERE t1.DCT_ORD_NUM = t2.DCT_ORD_NUM
AND t1.FLX_DIS_DTD = t2.FLX_DIS_DTD
AND t1.FLX_EMT_NUM = t2.FLX_EMT_NUM
AND t1.FLX_EMT_ORD = t2.FLX_EMT_ORD
AND t1.FLX_EMT_TYP = t2.FLX_EMT_TYP
AND t1.FLX_TRT_DTD = t2.FLX_TRT_DTD
AND t1.ORG_CLE_NUM = t2.ORG_CLE_NUM
AND t1.PRS_ORD_NUM = t2.PRS_ORD_NUM
AND t1.REM_TYP_AFF = t2.REM_TYP_AFF
AND t1.EXE_SOI_DTD >= TO_DATE (%str(%'&annee.0101%'), 'yyyymmdd')
AND t1.FLX_DIS_DTD = add_months(to_date(%str(%'&annee.&mois_deb.01%'),'yyyymmdd'),&i)
AND t2.TIP_PRS_IDE IN (1100028));

      disconnect from oracle;
QUIT;
%END;

data tab_&annee.;
set %do i = 1 %to %eval(&nb_mois);
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);
tab_&annee._&val;
%end;
run;

proc append
base=table_tot
data=table_&annee.;
run;

%mend audio;

%AUDIO(2013,1,12);
%AUDIO(2014,1,12);
%AUDIO(2015,1,12);
%AUDIO(2016,1,12);
%AUDIO(2017,1,12);
%AUDIO(2018,1,12);
%AUDIO(2019,1,12);
%AUDIO(2020,1,12);
%AUDIO(2021,1,12);

Bien cordialement,

Tim Vlaar - Health Data Hub

Merci beaucoup

Quand j’exécute le code, le journal d’exécution signifie que les tables mensuelles créées ont 0 lignes.

Savez-vous d’où cela peut provenir ?

Bien à vous

Victor Cluzel

Bonjour,

En regardant de plus près, je constate en effet plusieurs erreurs (j’ai lu un peu vite la première fois) :

  1. Un problème dans la définition de la date pour FLX_DIS_DTD dans votre requête SQL. Le format attendu pour la conversion en date est « yyyymmdd ». Or, vous lui donnez &annee.&mois_deb.01 en entrée, avec mois_deb=1 (ce devrait être 01 pour que ça marche). Quand vous appelez la macro AUDIO, essayez de remplacer 1 par 01 (ex : %AUDIO(2013,01,12); ).

  2. Au niveau de la compilation des tables mensuelles, préférez la syntaxe suivante :

%do i = 1 %to %eval(&nb_mois);
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

data tab_&annee.;
set tab_&annee._&val;
run;
%end;
  1. Au niveau du proc append, il y a une erreur sur table_&annee. qui devrait être tab_&annee., et il faut créer au préalable la table_tot avant de l’alimenter avec des proc append :
%if &annee = 2013 %then %do; 
data table_tot ; set tab_&annee. ; run; 
%end;
%else %do; 
proc append
base=table_tot
data=tab_&annee.;
run;
%end;

Des tables vides peuvent également signifier qu’il n’y ait pas eu de prestations pour les code LPP regardés sur la période considérée, mais dans votre cas je pense que c’était lié aux erreurs mentionnés ci-dessus.

Bien cordialement,

Tim Vlaar - Health Data Hub

Voici le code final modifié (qui fonctionne de mon côté) :

%macro audio(annee,mois_deb,nb_mois);

%do i = 1 %to &nb_mois;
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

PROC SQL;
%connectora;

create table tab_&annee._&val as select * from connection to oracle(
SELECT t2.TIP_PRS_IDE,
t1.EXE_SOI_DTD,
t1.BEN_NIR_PSA,
t1.BEN_RNG_GEM,
t1.BEN_CMU_TOP
FROM ER_PRS_F t1, ER_TIP_F t2
WHERE t1.DCT_ORD_NUM = t2.DCT_ORD_NUM
AND t1.FLX_DIS_DTD = t2.FLX_DIS_DTD
AND t1.FLX_EMT_NUM = t2.FLX_EMT_NUM
AND t1.FLX_EMT_ORD = t2.FLX_EMT_ORD
AND t1.FLX_EMT_TYP = t2.FLX_EMT_TYP
AND t1.FLX_TRT_DTD = t2.FLX_TRT_DTD
AND t1.ORG_CLE_NUM = t2.ORG_CLE_NUM
AND t1.PRS_ORD_NUM = t2.PRS_ORD_NUM
AND t1.REM_TYP_AFF = t2.REM_TYP_AFF
AND t1.EXE_SOI_DTD >= TO_DATE (%str(%'&annee.0101%'), 'yyyymmdd')
AND t1.FLX_DIS_DTD = add_months(to_date(%str(%'&annee.&mois_deb.01%'),'yyyymmdd'),&i)
AND t2.TIP_PRS_IDE IN (1304736));

      disconnect from oracle;
QUIT;
%END;


%do i = 1 %to %eval(&nb_mois);
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

data tab_&annee.;
set tab_&annee._&val;
run;
%end;

%if &annee = 2013 %then %do; 
data table_tot ; set tab_&annee. ; run; 
%end;
%else %do; 
proc append
base=table_tot
data=tab_&annee.;
run;
%end;

%mend audio;

%AUDIO(2013,01,12);
%AUDIO(2014,01,12);

Merci beaucoup !

Votre aide est précieuse

Pour information le code final est le suivant (la boucle interne d’agrégation des tables mensuelles en annuelles écrasait les mois précédents) :

%macro audio(annee,mois_deb,nb_mois);

%do i = 1 %to &nb_mois;
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

PROC SQL;
%connectora;

create table tab_&annee._&val as select * from connection to oracle(
SELECT t2.TIP_PRS_IDE,
t1.EXE_SOI_DTD,
t1.BEN_NIR_PSA,
t1.BEN_RNG_GEM,
t1.BEN_CMU_TOP
FROM ER_PRS_F t1, ER_TIP_F t2
WHERE t1.DCT_ORD_NUM = t2.DCT_ORD_NUM
AND t1.FLX_DIS_DTD = t2.FLX_DIS_DTD
AND t1.FLX_EMT_NUM = t2.FLX_EMT_NUM
AND t1.FLX_EMT_ORD = t2.FLX_EMT_ORD
AND t1.FLX_EMT_TYP = t2.FLX_EMT_TYP
AND t1.FLX_TRT_DTD = t2.FLX_TRT_DTD
AND t1.ORG_CLE_NUM = t2.ORG_CLE_NUM
AND t1.PRS_ORD_NUM = t2.PRS_ORD_NUM
AND t1.REM_TYP_AFF = t2.REM_TYP_AFF
AND t1.EXE_SOI_DTD >= TO_DATE (%str(%'&annee.0101%'), 'yyyymmdd')
AND t1.FLX_DIS_DTD = add_months(to_date(%str(%'&annee.&mois_deb.01%'),'yyyymmdd'),&i)
AND t2.TIP_PRS_IDE IN (1304736));

      disconnect from oracle;
QUIT;
%END;


data tab_&annee.;
set tab_&annee._01;
run;

%do i = 2 %to %eval(&nb_mois);
%if &i<10 %then %let i=0&i.;
%else %let i = &i.;
%let val=%eval(&i);

proc append
base=tab_&annee.
data=tab_&annee._&val;
run;
%end;

%if &annee = 2013 %then %do; 
data table_tot ; set tab_&annee. ; run; 
%end;
%else %do; 
proc append
base=table_tot
data=tab_&annee.;
run;
%end;

%mend audio;

%AUDIO(2013,01,12);
%AUDIO(2014,01,12);