Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > ODS et reporting
ODS et reporting Forum d'entraide sur les fonctionnalités de reporting de SAS : gérer les sorties et graphiques de SAS
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/02/2011, 14h16   #1
Invité de passage
 
Inscription : janvier 2010
Messages : 9
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 9
Points : 2
Points : 2
Par défaut Systématiser l'export de données SAS dans plusieurs onglets XLS

Bonjour,

Cette année encore, je sollicite vos compétences en SAS macro mais plus particulièrement sur les liaisons DDE entre SAS 9.1.3 et excel 2007.

Je vous explique mon cas:
Je dois exporter des données SAS dans des tableaux pré-paramétrés dans excel. Pour ce faire, j'utilise habituellement les liaisons dde pour ouvrir mon classeur et transférer les données dans telle ligne, telle colonne. J'utilise aussi des macros, car les opérations à effectuer sont les mêmes avec des variables différentes. Et le plus important, ici dans ce cas, est le fait que je dois réitérer ce programme 40 fois (pour 40 individus) dans 40 onglets différents.
Je me demandais donc, s'il n'y avait pas un moyen (un code plus exactement) pour systématiser cette manipulation dans 40 onglets?

Voici mon code qui permet de créer un classeur pour un individu:

Code :
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*Il faut que Excel soit ouvert au préalable*/
/*ces deux lignes servent à rendre la liaison possible 
et normalement ouvre excel mais bon la tu l'as deja ouvert*/
options noxwait noxsync;
 
x 'C:\Program Files\Microsoft Office\Office12\EXCEL.EXE';
 
/*tu attends 2 secondes avant de générer la liaison excel 
afin que le process excel soit bien lancée 
mais la aussi c'est un peu inutile vu que excel est déjà ouvert*/
DATA _null_;
	x=sleep(2);
run;
 
/*tu permets la manipulation de excel à partir de sas grâce à cette ligne*/
filename cmds dde 'excel|system';
 
/*tu ouvres le fichier où tu as ton modèle*/
DATA _null_;
	file cmds;
put "%bquote ([OPEN("C:\DONNEE\estelle\.....\diagnostic CR.xls")])";
run;
 
%macro CR(NCR);
 
DATA STICR;
SET STIC;
IF CR=&NCR;
RUN;
 
%macro remp (feuille,nligne,ncol);
DATA CR (KEEP= CR);
SET STICR;
RUN;
PROC SORT DATA=CR NODUPKEY;
BY CR;
RUN;
filename col1 dde "excel|&feuille!L&nligne.C&ncol.:L&nligne.C&ncol.";
DATA _null_ ;
	file col1;
	SET Cr;
	put CR ;
run;
PROC DATASETS LIBRARY=WORK;
DELETE CR C1;
RUN;
%mend;
%remp(EXEMPLE,5,4);
 
/* NB de MENAGE  */
%macro remp1a (base,NB,feuille,nligne,ncol);
DATA C (KEEP= MARCHE ID_MENA &NB);
SET &base;
run;
PROC SORT DATA=C nodupkey;
BY MARCHE ID_MENA;
RUN;
proc means DATA=C noprint;
BY MARCHE ;
var &NB;
output out=C1 (DROP= _TYPE_ _FREQ_ ) SUM = ;
run;
filename col1 dde "excel|&feuille!L&nligne.C&ncol.:L&nligne.C&ncol.";
DATA _null_ ;
	file col1;
	SET C1;
	put &NB ;
ATTRIB &NB FORMAT=numx8.4;
run;
PROC DATASETS LIBRARY=WORK;
DELETE C C1 ;
RUN;
%mend;
%remp1a (STICR,NMENA,EXEMPLE,6,4);
 
/* MARCHE CLIENT_CR */
%macro remp1 (base,NB,feuille,nligne,ncol);
DATA C (KEEP=MARCHE &NB);
SET &base;
run;
PROC SORT DATA=C;
BY MARCHE ;
RUN;
proc means DATA=C noprint;
BY MARCHE ;
var &NB;
output out=C1 (DROP= _TYPE_ _FREQ_ ) SUM = ;
run;
filename col1 dde "excel|&feuille!L&nligne.C&ncol.:L&nligne.C&ncol.";
DATA _null_ ;
	file col1;
	SET C1;
	put &NB ;
ATTRIB &NB FORMAT=numx8.4;
run;
PROC DATASETS LIBRARY=WORK;
DELETE C C1 ;
RUN;
%mend;
%remp1(STICR,NCLI,EXEMPLE,7,4);
%remp1(STICR,NB_DAV,EXEMPLE,11,4);
%remp1(STICR,MPOPU,EXEMPLE,12,4);
%remp1(STICR,NDAV,EXEMPLE,14,4);
%remp1(STICR,MDAV,EXEMPLE,16,4);
 
/*tu enregistres ton classeur rempli
et tu le fermes*/ 
DATA _null_;
	file cmds;
		put " %bquote ([SAVE.AS("C:\DONNEE\estelle\...\CR'&NCR'_diagnostic CR.xls")])";
		put " %bquote([QUIT()])";
run;
 
%mend;
 
%cr(802);
%cr(810);
%cr(812);
.
. /* 40 individus = 40 classeurs */
.
%cr(893);
Et voici ce que j'ai rajouté pour essayer de systématiser l'export de données SAS vers plusieurs onglets (40). Ma variable "repère" est NCR, il y aura autant d'onglet que de NCR.
Code :
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
options noxwait noxsync;
x 'C:\Program Files\Microsoft Office\Office12\EXCEL.EXE';
data _null_;
	x=sleep(2);
run;
filename cmds dde 'excel|system';
data _null_;
	file cmds;
put "%bquote ([OPEN("C:\DONNEE\estelle\.....\diagnostic CR.xls")])";
run;

/* début de la macro CR */
 %macro CR(NCR); 
 /* on passe la variable feuille en global pour l'appeler d'où on veut */
%global feuille ; /* on lui afecte la valeur de NCR */
%let feuille = &NCR ; /* affiche dans la log la valeur de la macro variable feuille, j'ai un doute sur la syntaxe &NCR ou &NCR. ????? */
%put &feuille;
DATA STICR;
SET STIC;
IF CR=&NCR;
RUN;

%macro remp (feuille,nligne,ncol);
DATA CR (KEEP= CR);
SET STICR;
RUN;
PROC SORT DATA=CR NODUPKEY;
BY CR;
RUN;
filename col1 dde "excel|&feuille!L&nligne.C&ncol.:L&nligne.C&ncol.";
data _null_ ;
	file col1;
	set Cr;
	put CR ;
run;
PROC DATASETS LIBRARY=WORK;
DELETE CR C1;
RUN;
%mend;
%remp(EXEMPLE,5,4);

/*
*
*
*/

/* MARCHE CLIENT_CR */
%macro remp1 (base,NB,feuille,nligne,ncol);
data C (KEEP=MARCHE &NB);
SET &base;
run;
PROC SORT DATA=C;
BY MARCHE ;
RUN;
proc means data=C noprint;
by MARCHE ;
var &NB;
output out=C1 (DROP= _TYPE_ _FREQ_ ) SUM = ;
run;
filename col1 dde "excel|&feuille!L&nligne.C&ncol.:L&nligne.C&ncol.";
data _null_ ;
	file col1;
	set C1;
	put &NB ;
ATTRIB &NB FORMAT=numx8.4;
run;
PROC DATASETS LIBRARY=WORK;
DELETE C C1 ;
RUN;
%mend;
%remp1(STICR,NCLI,EXEMPLE,7,4);
%remp1(STICR,NB_DAV,EXEMPLE,11,4);
%remp1(STICR,MPOPU,EXEMPLE,12,4);
%remp1(STICR,NDAV,EXEMPLE,14,4);
%remp1(STICR,MDAV,EXEMPLE,16,4);

/*tu enregistres ton classeur rempli
et tu le fermes*/ 
data _null_;
	file cmds;
		put " %bquote ([SAVE.AS("C:\DONNEE\estelle\...\CR_diagnostic CR.xls")])";
		put " %bquote([QUIT()])";
run;

%mend;

%cr(802 810 ..... 893 );
Mais, quand j'effectue ce drenier code j'ai ce message d'erreur:
ERREUR: Le fichier physique n'existe pas, excel|802 810!L12C4:L12C4.

Je pense qu'il faudrait créer une boucle avec %do i=802 %to=893, mais n'étant pas très avertie sur les macros, j'aimerais avoir votre avis sur ce problème. Si je n'ai pas été assez claire, n'hésitez pas à me demander des précisions.
Merci de votre aide.
dakine est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2011, 15h03   #2
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Bonjour.
Dans ton code, tu écris
Citation:
j'ai un doute sur la syntaxe &NCR ou &NCR. ?????
Les deux syntaxes sont équivalentes. Le point après le nom de la macro-variable n'est indispensable que s'il y a un risque d'ambiguïté sur l'endroit où s'arrête le nom de la macro-variable. Mais on peut en mettre systématiquement, ça ne mange pas de pain.
Par exemple, dans ton code il y a
Code :
L&nligne.C&ncol.:L etc.
Le . après &nLigne est obligatoire. Si tu écrivais SAS croirait que la 1e macro-variable s'appelle &nLigneC ! Par contre, il s'arrêtera forcément aux & et aux : qui ne peuvent pas faire partie du nom d'une macro-variable.

Pour le reste, le problème est effectivement l'absence d'une boucle. Si tous tes identifiants se suivent, tu peux faire mais comme tu parles de seulement 40, il y a trop de valeurs dans la boucle.
Si tu as le courage de les énumérer il faudrait plutôt faire une boucle du genre
Code :
1
2
3
4
5
6
7
8
9
%MACRO CR (liste_ncr) ;
  %LET i=1 ; /* initialisation d'un compteur de boucle */
  %DO %UNTIL(%SCAN(&liste_ncr.,&i.) = ) ; /* jusqu'à épuisement des valeurs */
      %LET feuille = %SCAN(&liste_ncr.,&i.) ;
      etc.
 
      %LET i = %EVAL(&i.+1) ; /* incrémentation du compteur */
  %END ;
%MEND CR ;
La fonction %SCAN te permet de récupérer un élément dans une liste.
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2011, 15h33   #3
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Le problème de ton code est que tu n'arrives pas à scanner chaque élément de ta macro feuille (ce quoi voit dans la log) comme Olivier t'a suggéré, faut faire un scann.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
%let feuille=802 810 811 893;
%let NB=%eval(%sysfunc(count(%cmpres(&feuille),%str( )))+1);/* compter le nombre d'onglets*/
%put There are &NB words in the string "&feuille";

%MACRO CR;
%DO i=1 %TO &NB.;
	%LET CR&i=%SCAN(&feuille,&i.,' ');
	DATA STICR&i;
	SET STIC;
	IF CR="&&NCR&i";
	RUN;
%END;
%MEND;
%CR;
Et je pense qu'il faut créer une table par personne ie 40
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2011, 15h39   #4
Invité de passage
 
Inscription : janvier 2010
Messages : 9
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 9
Points : 2
Points : 2
Merci. Je suis entrain de tester la boucle, et elle a l'air de fonctionner. J'ai juste quelques modifications à faire dans mon code et je pense qu'il sera au poil!

Et je voulais aussi vous remercier de faire des supports compréhensibles par tous, je pense notamment à la série "expliquée à ma fille", elle a le mérite d'être en français. Car je me suis essayée à la doc de Koen Vyverman sur les DDE, qui est bien faite également, mais là, j'en perds mon latin...
dakine est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2011, 15h47   #5
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Heureusement que Olivier a fait une fille
Trop fort Olivier, sincerement !!!
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h10.


 
 
 
 
Partenaires

Hébergement Web