IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macro Discussion :

Call SymputX et comparaison macro-variable


Sujet :

Macro

  1. #1
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut Call SymputX et comparaison macro-variable
    Bonjour,
    Dans le macro-programme Tmt, la comparaison
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	%If &stMois eq &MyMois and &stAnnee eq &MyAnnee and &stPeriode eq &MyPeriode and &lFicOk eq 1 %Then %Do;
    est toujours fausse.
    Alors que si je place des %put dans le code, je vois que les valeurs sont les mêmes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    %Macro CopieTable(MyTableSource, MyTableDest);
    	data &MyTableDest;
    		set &MyTableSource;
    	run;
    %Mend;
     
    %Global stFichierSource;
    %Global stRep;
    %Global stPrefD;
     
    %Global stMois;
    %Global stAnnee;
    %Global stPeriode;
    %Global lFicOk;
     
    %Macro Tmt(MyMois,MyAnnee,MyPeriode,MyTableDest);
     
    	Proc Sql;
    		Create table listeFichiers as select distinct Fichier, Mois, Annee, Periode, FicOk, NBENREG
    		From AppliCft.Ficrecusdet;
    	Quit;
     
    	data _null_;
    		set listeFichiers;
    		PrefD="D_";
    		PrefC="C_";
    		Post="A_TRAITER\";
    		RepIn="C:\FichiersAImporter\";
     
    		IF Periode='A' then Rep=catx('\',RepIn,Annee,Mois,'ANNUEL',Post);
    		IF Periode='M' then Rep=catx('\',RepIn,Annee,Mois,'MENSUEL',Post);
     
    		Call SymputX('stMois',Mois);
    		Call SymputX('stAnnee',Annee);
    		Call SymputX('stPeriode',Periode);
    		Call SymputX('lFicOk',FicOk);
     
    		%put &stMois &MyMois;
    		%put &stAnnee &MyAnnee;
    		%put &stPeriode &stPeriode;
    		%put &lFicOk;
     
    		%If &stMois eq &MyMois and &stAnnee eq &MyAnnee and &stPeriode eq &MyPeriode and &lFicOk eq 1 %Then %Do;
     
    			Call SymputX('stPrefD',PrefD);
     
    			Call SymputX('stRep',Rep);
    			libname L "&stRep";
     
    			Call SymputX('stFichierSource',Fichier);
     
    			/* Si &MyTableDest existe déjà */
    			 %if %sysfunc(exist(&MyTableDest)) eq 1 %then %CopieTable(L.&stPrefD&stFichierSource &MyTableDest,&MyTableDest);
     
    			 /* Sinon */
    		    /* Si &MyTableDest existe déjà */
    			 %if %sysfunc(exist(&MyTableDest)) eq 0 %then %CopieTable(L.&stPrefD&stFichierSource,&MyTableDest);
    		%End;
    	run;
    %Mend;
     
    /* Début du traitement */
    %Tmt(12,2009,A,AppliCft.Agreg122009a);
    Là j'avoue que je bloque.

    P.S.
    A priori c'est la clause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    &stPeriode eq &MyPeriode
    qui bloque.

    Pourtant ce champ vaut bien A pour deux enregistrements de la table listeFichiers et M pour deux autres.


    Si quelqu'un a une idée je suis preneur.

    Merci.

  2. #2
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 272
    Points : 417
    Points
    417
    Par défaut juste une remarque
    Bonjour,
    je ne pense pas être d'un grand secours mais il me semble que le code comporte une erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %put &stPeriode &stPeriode;
    au lieu de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %put &stPeriode &MyPeriode
    Peut-être que les champs ne sont pas égaux finalement
    Bon courage

  3. #3
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut
    Merci lilly74,
    oui je m'en suis aperçu mais il y a bien 2 enregistrements de la table listeFichiers pour lesquels la clause (bien orthographiée)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %IF &stMois eq &MyMois AND &stAnnee eq &MyAnnee AND &stPeriode eq &MyPeriode AND &lFicOk eq 1 %Then %Do;
    devrait être vraie.

  4. #4
    Membre éclairé
    Homme Profil pro
    responsable adjoint service stat
    Inscrit en
    Mars 2009
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : responsable adjoint service stat
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2009
    Messages : 448
    Points : 823
    Points
    823
    Par défaut
    Le problème est le suivant : avec call symput, les valeurs ne sont affectées à la macro variable qu'une fois l'étape data terminée.
    Du coup, ton test avec %if donne toujours faux, car il est fait avant que l'étape data ne soit finie.
    Pour t'en convaincre, essaie le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        %symdel stmois / nowarn ; 
        %let mymois = 12;
    	DATA _null_;
            Mois = 12 ;
    		Call SymputX('stMois',Mois);
            %put dans etape data : %nrstr(&stmois.) = &stmois. ;
    	run;
        %put après etape data : %nrstr(&stmois.) = &stmois. ;
    Deux solutions à ton problème
    1- Faire ton test avec %if après l'étape data
    2- Forcer la résolution du call symputX avant la fin de l'étape data.

    Pour le cas 2/, cela se fait avec la fonction resolve(), dont voici un exemple d'application :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        %symdel stmois / nowarn ; 
        %let mymois = 12;
    	DATA _null_;
            Mois = 12 ;
    		Call SymputX('stMois',Mois);
            Test = resolve ('&stmois');
            put Test= ;
            %put dans etape data : %nrstr(&stmois.) = &stmois. ;
    	run;
        %put après etape data : %nrstr(&stmois.) = &stmois. ;

  5. #5
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut
    Merci beaucoup Remi pour ces explications.
    Je comprends mieux le fonctionnement.

    Je ne peux pas faire le test en dehors de l'étape data car je dois tester l'existence d'autant de tables que d'enregistrements dans la table listeFichiers.

    Resolve permet de mettre dans un champ de la table la valeur de la macrovariable mais dans ce cas cela revient pour moi à tester directement les champs de la table :

    au lieu de Et dans ce bloc If Then, je ne vais pas pouvoir créer la table si elle n'existe pas.

  6. #6
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut
    Bon,
    j'ai résolu mon problème avec une solution à l'ancienne.

    Je génère un fichier sas avec des put puis j'exécute ce fichier.

    Ca marche nickel, ça fait ce que je voulais au départ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    dm log 'clear';
    dm output 'clear';
     
    option nosymbolgen nomprint nomlogic;
     
    /* On doit passer par des macrovariables globales pour utiliser les valeurs des paramètres du macroprogramme dans les puts */
    %Global stELibDest;
    %Global stTableDest;
    %Global stLibDest;
     
    %Macro Tmt(MyMois,MyAnnee,MyPeriode,MyLibDest,MyTableDest);
     
    	/* Ajout d'un espace devant nom table de destination pour programme SAS généré automatiquement avec les put */
    	%let stELibDest=" &MyLibDest";
    	%let stLibDest="&MyLibDest";
    	%let stTableDest="&MyTableDest";
     
     
    	Proc Sql;
    		Create table listeFichiers as select distinct Fichier, Mois, Annee, Periode, FicOk, NBENREG
    		From AppliCft.Ficrecusdet;
    	Quit;
     
    	/* Ajout d'un commentaire pour créer le fichier quoi qu'il arrive */
    	data _null_;
    		file "&lecteur.&chemMacros.\tempScript.sas";
    		put '%Macro temp();';
    	run;
     
    	data _null_;
    		/* MOD pour ajouter au fichier existant sans l'écraser */
    		file "&lecteur.&chemMacros.\tempScript.sas" MOD;
    		set listeFichiers;
     
    		PrefD="D_";
    		PrefC="C_";
    		Post="A_TRAITER\";
    		RepIn="&fichiersAImporter";
     
    		IF Periode='A' then Rep=catx('\',RepIn,Annee,Mois,'ANNUEL',Post);
    		IF Periode='M' then Rep=catx('\',RepIn,Annee,Mois,'MENSUEL',Post);
     
    		If Mois eq &MyMois and Annee eq &MyAnnee and Periode eq &MyPeriode and FicOk eq 1 Then Do;
    			put 'Libname L "' Rep '";';
     
    			Cmd=catt('%if %sysfunc(exist(',&stLibDest,'.',&stTableDest,')) eq 1 %Then %Do; Data ',&stELibDest,'.',&stTableDest,'; Set ',&stElibDest,'.',&stTableDest,' L.',PrefD,Fichier,'; Run; %End;');
    		 	put Cmd;
     
    		 	Cmd=catt('%Else %Do; Data ',&stELibDest,'.',&stTableDest,'; Set L.',PrefD,Fichier,'; Run;%End;');
    			put Cmd;
    		End;
    	run;
     
    	data _null_;
    	/* MOD pour ajouter au fichier existant sans l'écraser */
    		file "&lecteur.&chemMacros.\tempScript.sas" MOD;
    		put '%Mend;';
    	run;
    %Mend;
     
    /* Début du traitement */
    dm log 'clear';
     
    /* Génère le fichier sas à partir des enregistrements de la table listeFichiers */
    %Tmt('12','2009','A',AppliCft,Agreg122009a);
     
    /* Exécute le fichier sas généré */
    %Include "&lecteur.&chemMacros.\tempScript.sas";
     
    /* Exécute la macro qui a été créée par l'exécution du chier sas généré automatiquement */
    dm log 'clear';
    %temp();
    Contenu de tempScript.sas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    %Macro temp();
    Libname L "C:\FichiersAImporter\2009\12\ANNUEL\A_TRAITER\ ";
    %if %sysfunc(exist(AppliCft.Agreg122009a)) eq 1 %Then %Do; Data AppliCft.Agreg122009a; Set AppliCft.Agreg122009a L.D_A0200161CERTIV59UCANS1X359; Run; %End;
    %Else %Do; Data AppliCft.Agreg122009a; Set L.D_A0200161CERTIV59UCANS1X359; Run;%End;
    Libname L "C:\FichiersAImporter\2009\12\ANNUEL\A_TRAITER\ ";
    %if %sysfunc(exist(AppliCft.Agreg122009a)) eq 1 %Then %Do; Data AppliCft.Agreg122009a; Set AppliCft.Agreg122009a L.D_K1422244CERTI06UCANS1V01F; Run; %End;
    %Else %Do; Data AppliCft.Agreg122009a; Set L.D_K1422244CERTI06UCANS1V01F; Run;%End;
    %Mend;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comparaison macro variable numérique
    Par Jennn dans le forum Macro
    Réponses: 8
    Dernier message: 26/07/2012, 14h44
  2. Comparaison macro-variable en format date
    Par jogin38 dans le forum Macro
    Réponses: 1
    Dernier message: 07/12/2010, 09h08
  3. Affectation de macro-variables avec Call SymputX
    Par Filippo dans le forum Macro
    Réponses: 2
    Dernier message: 19/04/2010, 15h15
  4. [SAS 9.2] Call SymputX : macro-variable non créee
    Par Filippo dans le forum Macro
    Réponses: 2
    Dernier message: 14/01/2010, 11h40
  5. call symput et macro-variable
    Par fafabzh6 dans le forum Macro
    Réponses: 2
    Dernier message: 11/12/2009, 10h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo