BookmarkSubscribeRSS Feed
phil27
Calcite | Level 5
Hi,
I use the following macro to detect if a table exists.

At the first run when MyTableDest does not exist the macro creates MyTableDest.

But at the second run, instead of appending the lines of MyTableSource to MyTableDest the macro behaves like if MyTableDest did not exist.

From the third run it works well.

If someone has an idea, it would be great.
Thanks.

%Macro IntegreTable(MyTableSource, MyTableDest);
/* Vérification si MyTableDest existe */
%LOCAL bTableExiste;
%let bTableExiste=%sysfunc(exist(&MyTableDest));

/* Si table existe déjà alors ajout de MyTableSource */
%IF %eval(&bTableExiste) eq 1 %then %do;
DATA &MyTableDest;
SET &MyTableDest &MyTableSource;
run;
%end;

/* Si la table n'existe pas alors création */
%else %do;
DATA &MyTableDest;
SET &MyTableSource;
run;
%end;
%Mend;

%Macro CreeTableMensuelle(MyTableRef, MyRepIn, MyLibOut, MyTableOut, MyAnnee, MyMois, MyPeriode);
/* Récupération des informations utiles au traitement des fichiers */
Proc Sql NoPrint;
Create Table temp As
Select Distinct Fichier,Mois,Annee,Periode,FicOk
From &MyTableRef;
Quit;

/* On parcourt la liste des fichiers */
DATA _NULL_;
SET temp;

PrefD="D_";
PrefC="C_";
Post="A_TRAITER\";

MyRepIn=&MyRepIn;
MyAnnee=&MyAnnee;
MyMois=&MyMois;
MyPeriode=&MyPeriode;
MyLibOut=&MyLibOut;
MyTableOut=&MyTableOut;

/* Cats et CatX enlèvent les blancs aux extrêmités */
/* CatX permet d'insérer un séparateur (1er argument) entre chaque (autre) argument dans la chaîne résultat */
IF Annee eq MyAnnee AND Mois eq MyMois AND Periode eq MyPeriode AND FicOk eq 1 then do;

IF MyPeriode='A' then stRep=catx('\',MyRepIn,MyAnnee,MyMois,'ANNUEL',Post);
If MyPeriode='M' then stRep=catx('\',MyRepIn,MyAnnee,MyMois,'MENSUEL',Post);

rc=libname('LibSrc',stRep);

/* Agrégation fichier de données */
stFichierIn=cats(PrefD,Fichier);
stTableOut=cats(MyLibOut,'.',PrefD,MyTableOut);
CALL EXECUTE ('%IntegreTable(LibSrc.'||StFichierIn||','||stTableOut||')');

/* Agrégation fichier de tests */
stFichierIn=cats(PrefC,Fichier);
stTableOut=cats(MyLibOut,'.',PrefC,MyTableOut);
CALL EXECUTE ('%IntegreTable(LibSrc.'||StFichierIn||','||stTableOut||')');
end;
run;

/* Suppression des tables temporaires */
Proc Delete Data=temp; Run;

%mend;
8 REPLIES 8
data_null__
Jade | Level 19
See if %NRSTR will fix it.

Change

[pre]CALL EXECUTE ('%IntegreTable(LibSrc.'||StFichierIn||','||stTableOut||')');[/pre]

to

[pre]CALL EXECUTE ('%NRSTR(%IntegreTable LibSrc.'||StFichierIn||','||stTableOut||'))');[/pre]

Usually you want to delay execution of the CALL EXECUTED macro until after the data step finishes. Check docs for details.

Message was edited by: data _null_; Message was edited by: data _null_;
phil27
Calcite | Level 5
Thanks
data _null_;,
it does not work. it produces a syntax error.

May be I should have a look at the proc append instead of testing if the table exist.

phil
data_null__
Jade | Level 19
> it does not work. it produces a syntax error.

That's not very helpful. I would need to see the error.

I expect the missplaced character.
phil27
Calcite | Level 5
The exact error is :

NOTE: L'étape DATA a utilisé (Durée totale du traitement) :
temps réel 0.00 secondes
temps UC 0.00 secondes



-----------------------------------
180
ERROR 180-322: Instruction incorrecte ou mal utilisée.

2 +
)
3 + data AppliCft.C_Agreg200912A;

NOTE: Ligne générée par la routine CALL EXECUTE.
3 + set AppliCft.C_Agreg200912A LibSrc.C_A0200161CERTIV59UCANS1X359;
---
180

ERROR 180-322: Instruction incorrecte ou mal utilisée.
data_null__
Jade | Level 19
I believe there is an extra right parenthesis that is causing the error. Show your code again and the error. Show more of the log.

And use {pre} and {/pre} around the section of the log you post. But, use square brackets instead of the curley backets in the PRE and /PRE above.

[pre]
Example: This is surrounded by [ pre ] and [ /pre ] but without the spaces.
[/pre]
Patrick
Opal | Level 21
Hi

I believe the reason is that the SAS code generated by your macro executes at another time in the process than you assume (..until the step boundary has been passed).

"If an EXECUTE routine argument is a macro invocation or resolves to one, the macro executes immediately. However, any SAS statements produced by the EXECUTE routine do not execute until after the step boundary has been passed."

(http://support.sas.com/onlinedoc/913/getDoc/en/mcrolref.hlp/a000543697.htm)


HTH
Patrick
phil27
Calcite | Level 5
Ok,
thanks Patrick.

So I should try not to use Call Execute.

Phil
phil27
Calcite | Level 5
Ok,
I have removed one parenthesis in the code :

here is the whole log :
[PRE]
34198 %Mend;
34199
34200 /* Test de constitution de la table mensuelle annuelle de Décembre 2009
34200 ! */
34201 dm log 'clear';
34202 dm output 'clear';
34203
34204 option nomlogic symbolgen nomprint notes;
34205 %Global MyRepIn;
34206 %Let MyRepIn="C:\FichiersAImporter\";
34207 %CreeTableMensuelle(AppliCft.Ficrecusdet,&MyRepIn,'AppliCft','Agreg2009
34207 ! 12A',2009,12,'A');
SYMBOLGEN : Macro variable MYREPIN traitée dans "C:\FichiersAImporter\"
SYMBOLGEN : Macro variable MYTABLEREF traitée dans AppliCft.Ficrecusdet
NOTE: La table WORK.TEMP a été créée, avec 4 lignes et 5 col.

NOTE: Procédure SQL a utilisé (Durée totale du traitement) :
temps réel 0.04 secondes
temps UC 0.00 secondes


SYMBOLGEN : Macro variable MYREPIN traitée dans "C:\FichiersAImporter\"
SYMBOLGEN : Macro variable MYANNEE traitée dans 2009
SYMBOLGEN : Macro variable MYMOIS traitée dans 12
SYMBOLGEN : Macro variable MYPERIODE traitée dans 'A'
SYMBOLGEN : Macro variable MYLIBOUT traitée dans 'AppliCft'
SYMBOLGEN : Macro variable MYTABLEOUT traitée dans 'Agreg200912A'

NOTE: Valeurs caractères converties en valeurs numériques
aux emplacements indiqués par : (Ligne):(Colonne).
2:212 2:233
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans AppliCft.C_Agreg200912A
SYMBOLGEN : Macro variable BTABLEEXISTE traitée dans 1
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans AppliCft.C_Agreg200912A
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans AppliCft.C_Agreg200912A
SYMBOLGEN : Macro variable MYTABLESOURCE traitée dans
LibSrc.C_A0200161CERTIV59UCANS1X359
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans AppliCft.C_Agreg200912A
SYMBOLGEN : Macro variable BTABLEEXISTE traitée dans 1
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans AppliCft.C_Agreg200912A
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans AppliCft.C_Agreg200912A
SYMBOLGEN : Macro variable MYTABLESOURCE traitée dans
LibSrc.C_K1422244CERTI06UCANS1V01F
NOTE: 4 observation(s) lue(s) dans la table WORK.TEMP.
NOTE: L'étape DATA a utilisé (Durée totale du traitement) :
temps réel 0.04 secondes
temps UC 0.00 secondes


NOTE: CALL EXECUTE a généré une ligne.
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans
SYMBOLGEN : Macro variable BTABLEEXISTE traitée dans 1
1 + %IntegreTable LibSrc.D_A0200161CERTIV59UCANS1X359


,AppliCft.D_Agreg200912A
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans
SYMBOLGEN : Macro variable MYTABLESOURCE traitée dans

NOTE: 4 observation(s) lue(s) dans la table WORK.TEMP.
NOTE: La table WORK.DATA4 a 4 observation(s) et 5 variable(s).
NOTE: L'étape DATA a utilisé (Durée totale du traitement) :
temps réel 0.00 secondes
temps UC 0.00 secondes



-----------------------------------
180
ERROR 180-322: Instruction incorrecte ou mal utilisée.

2 +
3 + data AppliCft.C_Agreg200912A;

NOTE: Ligne générée par la routine CALL EXECUTE.
3 + set AppliCft.C_Agreg200912A
---
180
3 !+LibSrc.C_A0200161CERTIV59UCANS1X359; run;

ERROR 180-322: Instruction incorrecte ou mal utilisée.

SYMBOLGEN : Macro variable MYTABLEDEST traitée dans
SYMBOLGEN : Macro variable BTABLEEXISTE traitée dans 1
4 + %IntegreTable LibSrc.D_K1422244CERTI06UCANS1V01F


,AppliCft.D_Agreg200912A
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans
SYMBOLGEN : Macro variable MYTABLEDEST traitée dans
SYMBOLGEN : Macro variable MYTABLESOURCE traitée dans

NOTE: 4 observation(s) lue(s) dans la table WORK.DATA4.
NOTE: La table WORK.DATA5 a 4 observation(s) et 5 variable(s).
NOTE: L'étape DATA a utilisé (Durée totale du traitement) :
temps réel 0.00 secondes
temps UC 0.00 secondes



----------------------------------
180
ERROR 180-322: Instruction incorrecte ou mal utilisée.

5 +
6 + data AppliCft.C_Agreg200912A;

NOTE: Ligne générée par la routine CALL EXECUTE.
6 + set AppliCft.C_Agreg200912A
LibSrc.C_K1422244CERTI06UCANS1V01F
---
180
6 !+; run;

ERROR 180-322: Instruction incorrecte ou mal utilisée.


NOTE: Suppression de WORK.TEMP (memtype=DATA).
NOTE: Procédure DELETE a utilisé (Durée totale du traitement) :
temps réel 0.00 secondes
temps UC 0.00 secondes


34208
34209 /* Vérif des résultats */
34210 proc sql;
34211 select fichier, input(nbenreg,best.) as total from
34211 ! applicft.ficrecusdet where annee eq '2009' and mois eq '12' and periode
34211 ! eq 'A' and FicOk eq 1;
34212 quit;
NOTE: Procédure SQL a utilisé (Durée totale du traitement) :
temps réel 0.01 secondes
temps UC 0.00 secondes


34213
34214
34215 proc sql;
34216 select count(1) as total from applicft.d_Agreg200912A;
34217 quit;
NOTE: Procédure SQL a utilisé (Durée totale du traitement) :
temps réel 0.01 secondes
temps UC 0.00 secondes


[/PRE]

And the whole code :

[PRE]

%Global PrefD;
%Global PrefC;
%Global PostRep;

%Global Annee;
%Global Mois;
%Global Periode;
%Global FicOk;
%Global Nom;

%Global Nb;


%Macro CreeTableMensuelle(MyTableRef, MyRepIn, MyLibOut, MyTableOut, MyAnnee, MyMois, MyPeriode);
/* Récupération des informations utiles au traitement des fichiers */
Proc Sql NoPrint;
Create Table temp As
Select Distinct Fichier,Mois,Annee,Periode,FicOk
From &MyTableRef;
Quit;

/* On parcourt la liste des fichiers */
DATA _NULL_;
SET temp;

PrefD="D_";
PrefC="C_";
Post="A_TRAITER\";

MyRepIn=&MyRepIn;
MyAnnee=&MyAnnee;
MyMois=&MyMois;
MyPeriode=&MyPeriode;
MyLibOut=&MyLibOut;
MyTableOut=&MyTableOut;

/* Cats et CatX enlèvent les blancs aux extrêmités */
/* CatX permet d'insérer un séparateur (1er argument) entre chaque (autre) argument dans la chaîne résultat */
IF Annee eq MyAnnee AND Mois eq MyMois AND Periode eq MyPeriode AND FicOk eq 1 then do;

IF MyPeriode='A' then stRep=catx('\',MyRepIn,MyAnnee,MyMois,'ANNUEL',Post);
If MyPeriode='M' then stRep=catx('\',MyRepIn,MyAnnee,MyMois,'MENSUEL',Post);

rc=libname('LibSrc',stRep);

/* Agrégation fichier de données */
stFichierIn=cats(PrefD,Fichier);
stTableOut=cats(MyLibOut,'.',PrefD,MyTableOut);
CALL EXECUTE ('%NRSTR(%IntegreTable LibSrc.'||StFichierIn||','||stTableOut||')');

/* Agrégation fichier de tests */
stFichierIn=cats(PrefC,Fichier);
stTableOut=cats(MyLibOut,'.',PrefC,MyTableOut);
CALL EXECUTE ('%NRSTR(%IntegreTable LibSrc.'||StFichierIn||','||stTableOut||')');
end;
run;

/* Suppression des tables temporaires */
Proc Delete Data=temp; Run;

%mend;


%Macro IntegreTable(MyTableSource, MyTableDest);
/* Vérification si MyTableDest existe */
%local bTableExiste;
%let bTableExiste=%sysfunc(exist(&MyTableDest));

/* Si table existe déjà alors ajout de MyTableSource */
%if %eval(&bTableExiste) eq 1 %then %do;
data &MyTableDest;
set &MyTableDest &MyTableSource;
run;
%end;

/* Si la table n'existe pas alors création */
%else %do;
data &MyTableDest;
set &MyTableSource;
run;
%end;
%Mend;

/* Test de constitution de la table mensuelle annuelle de Décembre 2009 */
dm log 'clear';
dm output 'clear';

option nomlogic symbolgen nomprint notes;
%Global MyRepIn;
%Let MyRepIn="C:\FichiersAImporter\";
%CreeTableMensuelle(A.Fichier,&MyRepIn,'A','Agreg200912A',2009,12,'A');
[/PRE]

Message was edited by: phil27

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 2071 views
  • 0 likes
  • 3 in conversation