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

ODS et reporting Discussion :

Systématiser l'export de données SAS dans plusieurs onglets XLS


Sujet :

ODS et reporting

  1. #1
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 11
    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 : 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
    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 : 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
    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.

  2. #2
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Par défaut
    Bonjour.
    Dans ton code, tu écris
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  3. #3
    Membre Expert
    Avatar de MEGAMIND2
    Homme Profil pro
    Paris
    Inscrit en
    Janvier 2011
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Paris

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 029
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  4. #4
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 11
    Par défaut
    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...

  5. #5
    Membre Expert
    Avatar de MEGAMIND2
    Homme Profil pro
    Paris
    Inscrit en
    Janvier 2011
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Paris

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 029
    Par défaut
    Heureusement que Olivier a fait une fille
    Trop fort Olivier, sincerement !!!

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

Discussions similaires

  1. Importer des données XL dans plusieurs tables
    Par curt dans le forum VBA Access
    Réponses: 0
    Dernier message: 23/05/2008, 22h46
  2. [VBA-E] Exporter des données Excel dans Word
    Par lucarno dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 24/08/2007, 19h25
  3. Réponses: 0
    Dernier message: 24/07/2007, 13h22
  4. Réponses: 1
    Dernier message: 27/10/2006, 12h17
  5. Réponses: 2
    Dernier message: 31/03/2006, 11h29

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