ah d'accord, je savais pas je suis encore débutant, merci pour l'info.
Je pense quand même que je vais garder les proc report que j'ai mise au point.
Il faudrait que je fasse la somme sur toutes les tables
(cf mon dernier post).
En espérant avoir été assez clair dans mon explication pour que vous compreniez ce que je souhaite réalisé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 DATA _NULL_; SET TABLE END=EOF;/*table contenant le nom des fichiers*/ IF EOF THEN CALL SYMPUT("NB",_N_);/* comptage du nombre de tables*/ CALL SYMPUT("liste_table"!!LEFT(_N_),nom_table); END;
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 %MACRO SOMME; %DO i=1 %TO &NB.; proc sort DATA=&&liste_table&i.; BY tsbroadstart; run; PROC SQL; CREATE TABLE somme_&&liste_table&i. AS SELECT SUM(itodeliver) AS itodeliver, SUM(iprocessed) AS iprocessed, SUM(isuccess) AS isuccess, ((SUM(isuccess)/SUM(iprocessed))*100) AS successpourcent, SUM(irecipientopen) AS irecipientopen, ((SUM(irecipientopen)/SUM(isuccess))*100) AS ouverturespourcent, SUM(itotalrecipientopen) AS itotalrecipientopen, SUM(ioptout) AS ioptout, ((SUM(ioptout)/SUM(isuccess))*100) AS desinscriptionspourcent, SUM(ipersonclick) AS ipersonclick, ((SUM(ipersonclick)/SUM(isuccess))*100) AS clicsdistinctspourcent, SUM(itotalrecipientclick) AS itotalrecipientclick, ((SUM(ipersonclick)/SUM(irecipientopen))*100) AS reactivite, SUM(ireject) AS ireject, SUM(inewquarantine) AS inewquarantine, ((SUM(inewquarantine)/SUM(isuccess))*100) AS quarantainepourcent, SUM(imirrorpage) AS imirrorpage, ((SUM(imirrorpage)/SUM(isuccess))*100) AS mirroirpourcent, SUM(iforward) AS iforward, ((SUM(iforward)/SUM(isuccess))*100) AS transfertspourcent FROM &&liste_table&i. ; QUIT; %END; %MEND SOMME; %SOMME;
Dans le set du data _null_, je dois laisser "TABLE" ou je remplace par ma table?
J'ai essayé d'éxécuté ton code à la suite de celui de Manoutz mais ça ne fonctionne pas.
Tu importes un fichier Excel en table SAS, appelle le TABLE ou autre chose. La seule colonne dans la table SAS s'appelle nom_table, ça devait marcher normalement
Je dois importer un fichier Excel en table SAS ?
Car moi sinon non, il n'y a rien à faire avec Excel.
@ ludo: Pour info, tu n'as pas besoin de trier ton jeu de données avant une proc sql. quel lien y-a-t-il entre les variables caractère et ta ligne de donnée avec tes sommes? Il est possible peut être possible d'envisager une autre approche quel celle proposée par MGMD. Peux tu décrire l'organisation escomptée de la table en sortie?
@MGMD: pourquoi excel?
Pour chaque "individu" il y a quelques variables caractères et d'autres numériques.
En sortie (qui sera sous Excel) il doit y avoir un onglet par "catégorie" (abc) et dans chaque onglet, les individus sont regroupés lorsqu'ils ont la même fin de "sdeliverycode" (azert). Avec pour chacun de ces groupes, la somme correspondante.
Si j'ai bien compris, tu veux agréger tes 84 tables et tu veux demander à SAS de le faire à ta place car trop fastidiuex, c'est ça?
voici comment faire une somme par substr(sdeliverycode,1,3)||substr(sdeliverycode,17,5)
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 DATA tableorig; input sdeliverycode $50.; cards; abc-de-27042010-azert abc-de-27032010-azert abc-de-27022010-qsdfg abc-de-07112010-yuiop ;run; proc sql noprint; SELECT DISTINCT substr(sdeliverycode,1,3)||substr(sdeliverycode,17,5) INTO :listtab separated BY " " FROM tableorig; CREATE TABLE listtab AS SELECT DISTINCT substr(sdeliverycode,1,3)||substr(sdeliverycode,17,5) AS code FROM tableorig; create table tabletemp as select *, sum(input(substr(sdeliverycode,8,8),best12.)) as somme from tableorig group by substr(sdeliverycode,1,3)||substr(sdeliverycode,17,5) ;quit; DATA _null_; SET listtab; call symput("code"||compress(put(_n_,3.)), code); call symput("nbcode",put(_n_,3.)); run; %macro manageoutput; DATA &listtab ; SET tabletemp; %do i=1 %TO &nbcode.; IF substr(sdeliverycode,1,3)||substr(sdeliverycode,17,5)="&&code&i." then output &&code&i.; %end; run; %mend manageoutput; %manageoutput;
Je ne sais pas comment tu pensais basculer le résultat sous Excel, mais tu n'as pas forcément besoin de créer les 84 tables. SAS propose une manière automatique de répéter le même traitement sur différents blocs d'observations : l'instruction BY. L'ODS vers Excel (TAGSETS.EXCELXP) permet de changer de feuille à chaque bloc BY avecSi je comprends globalement quels sont ton point de départ et le résultat espéré, je ferais quelque chose comme :
Code : Sélectionner tout - Visualiser dans une fenêtre à part option(sheet_interval="BYGROUP")
1) calcul des nouvelles variables te servant à partitionner les données avec des SUBSTR comme les exemples ci-dessus l'ont raconté --> tu as toujours 1 seule table
2) tri de la table selon ces nouvelles variables (facultatif si tu fais l'étape 3 en SQL)
3) calcul des lignes de sommes avec une proc MEANS et une instruction BY (ou du SQL et un GROUP BY, à ta convenance)
4) empilement des lignes de sommes et de la table de détail avec une instruction SET. Tu en profites pour marquer spécifiquement les lignes de totaux.
5) tri de la nouvelle table augmentée des totaux, de manière à retrouver tes blocs d'observations et les totaux à la fin
6) export avec une proc PRINT/TABULATE/REPORT selon les besoins, avec une instruction BY et de l'ODS TAGSETS.EXCELXP autour.
Ca devrait limiter le recours aux macros, aux hash tables, aux tables en nombre déraisonnable, etc. Avec du coup un code qui reste lisible, testable et performant (espérons).
Bon courage.
Olivier
Oui mais là ça ne fait pas la somme par colonne dans chaque groupe?
Ce que je voudrais, c'est ajouté ce code dans ta macro:
L'ajouté à ta macro pour que ça le fasse pour toutes les tables créées et pas seulement pour abcazert (cf code ci-dessus).
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 proc sort DATA=abcazert; BY tsbroadstart; run; PROC SQL; CREATE TABLE somme AS SELECT SUM(itodeliver) AS itodeliver, SUM(iprocessed) AS iprocessed, SUM(isuccess) AS isuccess, ((SUM(isuccess)/SUM(iprocessed))*100) AS successpourcent, SUM(irecipientopen) AS irecipientopen, ((SUM(irecipientopen)/SUM(isuccess))*100) AS ouverturespourcent, SUM(itotalrecipientopen) AS itotalrecipientopen, SUM(ioptout) AS ioptout, ((SUM(ioptout)/SUM(isuccess))*100) AS desinscriptionspourcent, SUM(ipersonclick) AS ipersonclick, ((SUM(ipersonclick)/SUM(isuccess))*100) AS clicsdistinctspourcent, SUM(itotalrecipientclick) AS itotalrecipientclick, ((SUM(ipersonclick)/SUM(irecipientopen))*100) AS reactivite, SUM(ireject) AS ireject, SUM(inewquarantine) AS inewquarantine, ((SUM(inewquarantine)/SUM(isuccess))*100) AS quarantainepourcent, SUM(imirrorpage) AS imirrorpage, ((SUM(imirrorpage)/SUM(isuccess))*100) AS mirroirpourcent, SUM(iforward) AS iforward, ((SUM(iforward)/SUM(isuccess))*100) AS transfertspourcent FROM abcazert; QUIT; DATA tableauavecsommeabcazert; SET abcazert somme; IF sdeliverycode="" then sdeliverycode="Totaux"; run;
Merci de votre aide
Je te propose cette macro.
La macro variable dir ne doit contenir que tes 84 tables, ni moins ni plus.
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 %let dir=C:\Documents and Settings\BEARE\Bureau\ANALYSE; DATA fichiersSAS ; LENGTH fic $ 100; INFILE "&dir.\*.sas7bdat" FILENAME = fic ; INPUT ; fichier = fic ; RUN ; PROC SORT data=fichiersSAS nodupkey; BY fichier; RUN; DATA fichiersSAS ; ATTRIB nom_fichier FORMAT=$100.; SET fichiersSAS ; NOM_F=scan(fichier,-1,'\'); nom_fichier=tranwrd(NOM_F,'.sas7bdat',' '); RUN; DATA _NULL_; SET fichiersSAS; CALL SYMPUT("NB",_N_); CALL SYMPUT("liste_fichier"!!LEFT(_N_),nom_fichier); RUN; %MACRO SOMME; %DO i=1 %TO &NB.; PROC SQL; CREATE TABLE somme_&&liste_table&i. AS SELECT SUM(itodeliver) AS itodeliver, SUM(iprocessed) AS iprocessed, SUM(isuccess) AS isuccess, ((SUM(isuccess)/SUM(iprocessed))*100) AS successpourcent, SUM(irecipientopen) AS irecipientopen, ((SUM(irecipientopen)/SUM(isuccess))*100) AS ouverturespourcent, SUM(itotalrecipientopen) AS itotalrecipientopen, SUM(ioptout) AS ioptout, ((SUM(ioptout)/SUM(isuccess))*100) AS desinscriptionspourcent, SUM(ipersonclick) AS ipersonclick, ((SUM(ipersonclick)/SUM(isuccess))*100) AS clicsdistinctspourcent, SUM(itotalrecipientclick) AS itotalrecipientclick, ((SUM(ipersonclick)/SUM(irecipientopen))*100) AS reactivite, SUM(ireject) AS ireject, SUM(inewquarantine) AS inewquarantine, ((SUM(inewquarantine)/SUM(isuccess))*100) AS quarantainepourcent, SUM(imirrorpage) AS imirrorpage, ((SUM(imirrorpage)/SUM(isuccess))*100) AS mirroirpourcent, SUM(iforward) AS iforward, ((SUM(iforward)/SUM(isuccess))*100) AS transfertspourcent FROM &&liste_table&i.; QUIT; %END; %MEND; %SOMME;
Je souhaite ajouter ce code:
à celui-ci:
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 proc sort DATA=abcazert; BY tsbroadstart; run; PROC SQL; CREATE TABLE somme AS SELECT SUM(itodeliver) AS itodeliver, SUM(iprocessed) AS iprocessed, SUM(isuccess) AS isuccess, ((SUM(isuccess)/SUM(iprocessed))*100) AS successpourcent, SUM(irecipientopen) AS irecipientopen, ((SUM(irecipientopen)/SUM(isuccess))*100) AS ouverturespourcent, SUM(itotalrecipientopen) AS itotalrecipientopen, SUM(ioptout) AS ioptout, ((SUM(ioptout)/SUM(isuccess))*100) AS desinscriptionspourcent, SUM(ipersonclick) AS ipersonclick, ((SUM(ipersonclick)/SUM(isuccess))*100) AS clicsdistinctspourcent, SUM(itotalrecipientclick) AS itotalrecipientclick, ((SUM(ipersonclick)/SUM(irecipientopen))*100) AS reactivite, SUM(ireject) AS ireject, SUM(inewquarantine) AS inewquarantine, ((SUM(inewquarantine)/SUM(isuccess))*100) AS quarantainepourcent, SUM(imirrorpage) AS imirrorpage, ((SUM(imirrorpage)/SUM(isuccess))*100) AS mirroirpourcent, SUM(iforward) AS iforward, ((SUM(iforward)/SUM(isuccess))*100) AS transfertspourcent FROM abcazert; QUIT; DATA tableauavecsommeabcazert; SET abcazert somme; IF sdeliverycode="" then sdeliverycode="Totaux"; run;
J'ai essayé ça mais ça ne marche pas:
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 proc sql noprint; SELECT DISTINCT substr(sdeliverycode,1,3)||substr(sdeliverycode,25,5) INTO :listtab separated BY " " FROM nouveaufichier1; CREATE TABLE listtab AS SELECT DISTINCT substr(sdeliverycode,1,3)||substr(sdeliverycode,25,5) AS code FROM nouveaufichier1; quit; DATA _null_; SET listtab; call symput("code"||compress(put(_n_,3.)), code); call symput("nbcode",put(_n_,3.)); run; %macro manageoutput; DATA &listtab ; SET nouveaufichier1; %do i=1 %TO &nbcode.; IF substr(sdeliverycode,1,3)||substr(sdeliverycode,25,5)="&&code&i." then output &&code&i.; %end; run; %mend manageoutput; %manageoutput;
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 proc sql noprint; SELECT DISTINCT substr(sdeliverycode,1,3)||substr(sdeliverycode,25,5) INTO :listtab separated BY " " FROM nouveaufichier1; CREATE TABLE listtab AS SELECT DISTINCT substr(sdeliverycode,1,3)||substr(sdeliverycode,25,5) AS code FROM nouveaufichier1; quit; DATA _null_; SET listtab; call symput("code"||compress(put(_n_,3.)), code); call symput("nbcode",put(_n_,3.)); run; %macro manageoutput; DATA &listtab ; SET nouveaufichier1; %do i=1 %TO &nbcode.; IF substr(sdeliverycode,1,3)||substr(sdeliverycode,25,5)="&&code&i." then output &&code&i.; %end; run; PROC SQL; CREATE TABLE somme&&code&i. AS SELECT SUM(itodeliver) AS itodeliver, SUM(iprocessed) AS iprocessed, SUM(isuccess) AS isuccess, ((SUM(isuccess)/SUM(iprocessed))*100) AS successpourcent, SUM(irecipientopen) AS irecipientopen, ((SUM(irecipientopen)/SUM(isuccess))*100) AS ouverturespourcent, SUM(itotalrecipientopen) AS itotalrecipientopen, SUM(ioptout) AS ioptout, ((SUM(ioptout)/SUM(isuccess))*100) AS desinscriptionspourcent, SUM(ipersonclick) AS ipersonclick, ((SUM(ipersonclick)/SUM(isuccess))*100) AS clicsdistinctspourcent, SUM(itotalrecipientclick) AS itotalrecipientclick, ((SUM(ipersonclick)/SUM(irecipientopen))*100) AS reactivite, SUM(ireject) AS ireject, SUM(inewquarantine) AS inewquarantine, ((SUM(inewquarantine)/SUM(isuccess))*100) AS quarantainepourcent, SUM(imirrorpage) AS imirrorpage, ((SUM(imirrorpage)/SUM(isuccess))*100) AS mirroirpourcent, SUM(iforward) AS iforward, ((SUM(iforward)/SUM(isuccess))*100) AS transfertspourcent FROM &&code&i.; QUIT; DATA tableauavecsomme&&code&i.; SET &&code&i. somme&&code&i.; IF sdeliverycode="" then sdeliverycode="Totaux"; run; %mend manageoutput; %manageoutput;
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager