Trucos SAS. Ejecutar un código si existe una tabla o un fichero

10 Nov

Esta duda me llegó hace unos días. Se trataba de ejecutar un código si existía determinado fichero o determinada tabla. Para hacer esto os planteo una posible metodología que yo utilizaba cuando programaba SAS en una gran entidad bancaria con Enterprise Guide 1, por aquellos entonces hacía maravillas con la castaña del Guide v1. Entre ellas unas macros que contenían una sentencia condicional que ejecutaba un código en función de la función (bonita expresión) EXIST o FILEEXIST. Lo que yo hacía era algo parecido a esto:

Macro que ejecuta un código SAS si existe una tabla:

data uno;
do i = 1 to 100;
output;
end;
run;
*MACRO QUE SE EJECUTA SI EXISTE UNA TABLA SAS;
%macro proceso(tabla);
%if %sysfunc(exist(&tabla.)) %then %do;
data dos;
set uno;
i=i**2;
run;
%end;
%mend;
*;
%proceso(work.uno);

¡Que sencillo! Pero si alguien ha programado con EGuide 1 entenderá porque era tan útil esta macro. Además es un perfecto ejemplo de uso de la función EXIST. Por otro lado me encontraba con la situación de que las cadenas de carga de diversos JOB en mi compañía generaban ficheros DB2 a determinadas horas y esta hora nunca era la misma y por supuesto no coincidía con la hora prevista de finalización. Para ello hacía algo parecido a lo que os planteo a continuación:

*EXPORTO UN FICHERO PARA QUE TENGÁIS EL EJEMPLO;
PROC EXPORT DATA= WORK.Dos
OUTFILE= "C:\temp\borra.csv"
DBMS=CSV REPLACE;
PUTNAMES=YES;
RUN;
*MACRO QUE SE EJECUTA SI EXISTE UN FICHERO;
%macro proceso2(arch);
%if %sysfunc(fileexist(&arch.)) %then %do;
data WORK.DOS ;
infile 'C:\temp\borra.csv' delimiter = ','
MISSOVER DSD lrecl=32767 firstobs=2 ;
informat i best32. ;
format i best12. ;
input i;
run;
%end;
%mend;
*;
%proceso2("C:\temp\borra.csv");

Realizaba un bucle que, cada 5 minutos, rastreaba la existencia de un determinado fichero en el servidor y si aparecia ejecutaba el código. Para ello empleaba la función FILEEXIST de una forma análoga a la que os planteo en el ejemplo. Este bucle dará lugar a otro truco SAS en breve. Este truco si que es útil para todos aquellos que esperáis que os generen ficheros desde TI para ejecutar vuestros procesos. Saludos.

26 respuestas a «Trucos SAS. Ejecutar un código si existe una tabla o un fichero»

  1. Disculpa la molestia pero necesito ayuda: que código uso para conectarme a una base de datos DB2, trabajo en un banco y necesito saber el codigo que se usa para poder conectarme a su servidor y manipular sus bases, utilizo el sas enterprise 4.2. Por favor ayudame

  2. Buenos días, tengo un problema con un fichero que me envían generado por una aplicación que contiene algún salto de línea aleatorio cortando el registro y continuándolo en el siguiente.
    Tengo un caracter concreto en el fichero que indica el final del registro pero no sé como, al ejecutar el infile y leer el fichero (definiendo las variables y sus posiciones), indicar en la lectura que sólo cuando lea ese carácter ejecute el cambio de registro… ¿sería posible?
    Muchas gracias de antemano por vuestra ayuda.
    Un saludo.

  3. hola, tu problema es que estás leyendo un fichero de algún entorno host que tiene un salto de línea distinto al S.O. donde tienes SAS. Es decir, estás leyendo un unix desde un windows, por ejemplo. Tienes que hacer algo parecido a esto:

    Leer carácter a carácter y cambiar el retorno de carro:

    data _null_;
    length char 1.;
    infile «&fich.» lrecl=1 recfm=F missover dsd;
    file «DEP_&fich.» lrecl=1 recfm=F;
    input char
    ASCII.;
    if rank(char) = 10 /*SI ES WIN PONER EL 13*/ then char= «»;
    put char;
    run;

    Después lo mismo para poner el carácter que no es retorno de carro al S.O. que manejes:

    data _null_;
    length char 1.;
    infile «DEP_&fich.» lrecl=1 recfm=F missover dsd;
    file «DEP_&fich.» lrecl=1 recfm=F;
    input char
    ASCII.;
    if char = «@» /*EJEMPLO DE FINAL DE LINEA*/ then char= byte(10) /*PONER 13 SI ES UNIX*/;
    put char;
    run;

    No sé si lo entiendes, pero tu problema es debido a mover ficheros entre distintos S.O. Muy típico de leer ficheros unix en win. No sé si podrás jugar con el FTP también, con los datos que me das creo que el problema viene por ahí.

  4. Si, justamente es eso lo que me sucede, al ser entornos distintos se generan multitud de problemas. Muchas gracias, voy a ver si soy capaz!
    Un saludo.

  5. Hola, sabes que estoy utilizando el SAS 9.1.3 service pack 3 y la «MACRO QUE SE EJECUTA SI EXISTE UN FICHERO» no funciona, el fichero en cuestion es un TXT que se encuentra en uno de los servidores de mi trabajo.

  6. No sabía donde poner mi comentario asi que lo he puesto aquí, siento si no es el lugar correcto.

    Podrías ayudarme a pasar un código a macro, es relativamente sencillo, pero tengo algún problema a la hora de hacer el output

    Quiero transformarlo en macro para poderla ejecutar en varios programas diferentes con las mismas características.

    Código:

    IF (FC_INICI &G_Fechalimit_fin) or
    (FC_INICI = . and FC_FI = .) or
    (FC_INICI <= &G_Fechalimit_fin and FC_FI= .)

    THEN OUTPUT;

    Gracias.

  7. La verdad es que no te entiendo muy bien, pero puedes hacer:

    %let condicion = (FC_INICI &G_Fechalimit_fin) or
    (FC_INICI = . and FC_FI = .) or
    (FC_INICI <= &G_Fechalimit_fin and FC_FI= .); Y podrás poner if &condicion.; donde quieras.

  8. Igual que el comentario anterior, disculpas si esta pregunta no aplica en esta página.
    Estoy haciendo un web service en .net leyendo una base de datos de SAS. Ya puedo hacer la conexion a la base de datos y abrir la tabla (hasta ahi todo bien) luego el web service hace una busqueda en un bucle (registro a registro hasta fin de archivo, lo que demora mucho) Mi pregunta es: como puedo ejecutar un «proc data» desde mi web servioe para que la tabla resultante tenga 1 registro y luego desde el web service pueda leer esta tabla pequeña. Agradezco mucho su ayuda, llevo bastante tiempo investigando el caso

  9. Hola buenas tardes,
    Necesito saber un codigo sas que me permita ejecutar un proyecto SAS a una hora determinada.
    He tratado de hacerlo mediante HERRAMIENTAS; PLANIFICAR PROYECTO…y no me ejecuta.
    Te agradeceria infinitamete si me ayudaras a solucionar este tema.

  10. Cordial Saludo.
    Necesito conectarme a una base o file por FTP/sFTP desde SAS management console pero no logro generar que me establesca la comunicación…..

  11. Hola, estoy declarando una variable y le estoy asignando un valor (El valor es el nombre de una tabla). Necesito llamar esa tabla y colocarla en un SQL de un DataFlow. alguien sabe si se puede llamar la variable como si fuera una tabla? y como podria hacerlo. Muchas gracias

  12. Hola, a ver si me podéis ayudar.
    Tengo una problema con una macro de carga de archivos y es que quiero unir en una misma tabla ficheros de información de 12 meses y cuando la ejecuto siempre se me queda solo con la info del último fichero cargado y pisa todo el resto.

    Pego el código:

    /*CARGA RECIBOS*/
    %MACRO CARGA_RECIBOS(fichero_recibos, tabla);

    DATA &tabla.;
    %LET _EFIERR_ = 0; /* SET THE ERROR DETECTION MACRO VARIABLE */
    INFILE &fichero_recibos. DELIMITER=’|’ MISSOVER DSD LRECL=50000 FIRSTOBS=2 ;
    INFORMAT POLIZA BEST9.;
    INFORMAT RAMO BEST9.;
    INFORMAT MODALIDAD BEST9.;
    INFORMAT RAMOCONT BEST9.;
    INFORMAT NRECIBO 14.;
    INFORMAT IMPPRIMA COMMAX16.2;
    INFORMAT IMPBONIFIC COMMAX16.2;
    INFORMAT IMPIPS COMMAX16.2;
    INFORMAT IMPCONSORC COMMAX16.2;
    INFORMAT IMPCLEA COMMAX16.2;
    INFORMAT IMPARB COMMAX16.2;
    INFORMAT IMPCOMI COMMAX16.2;
    INFORMAT IMPRECIBO COMMAX16.2;
    INFORMAT FEFECTO DDMMYY10.;
    INFORMAT FVENCIM
    14.;
    INFORMAT FLIQCAR 14.;
    INFORMAT FLIQANU
    14.;
    INFORMAT FLIQCOB 14.;
    INFORMAT FPAGO
    14.;
    INFORMAT TIPODOC 14.;
    INFORMAT AGENCIA
    14.;
    INFORMAT TMEDIADOR 14.;
    INFORMAT MEDIADOR
    14.;

    FORMAT POLIZA BEST9.;
    FORMAT RAMO BEST9.;
    FORMAT MODALIDAD BEST9.;
    FORMAT RAMOCONT BEST9.;
    FORMAT NRECIBO 14.;
    FORMAT IMPPRIMA COMMAX16.2;
    FORMAT IMPBONIFIC COMMAX16.2;
    FORMAT IMPIPS COMMAX16.2;
    FORMAT IMPCONSORC COMMAX16.2;
    FORMAT IMPCLEA COMMAX16.2;
    FORMAT IMPARB COMMAX16.2;
    FORMAT IMPCOMI COMMAX16.2;
    FORMAT IMPRECIBO COMMAX16.2;
    FORMAT FEFECTO DDMMYY10.;
    FORMAT FVENCIM
    14.;
    FORMAT FLIQCAR 14.;
    FORMAT FLIQANU
    14.;
    FORMAT FLIQCOB 14.;
    FORMAT FPAGO
    14.;
    FORMAT TIPODOC 14.;
    FORMAT AGENCIA
    14.;
    FORMAT TMEDIADOR 14.;
    FORMAT MEDIADOR
    14.;

    INPUT
    POLIZA
    RAMO
    MODALIDAD
    RAMOCONT
    NRECIBO IMPPRIMA
    IMPBONIFIC
    IMPIPS
    IMPCONSORC
    IMPCLEA
    IMPARB
    IMPCOMI
    IMPRECIBO
    FEFECTO
    FVENCIM

    FLIQCAR FLIQANU
    FLIQCOB FPAGO
    TIPODOC AGENCIA
    TMEDIADOR MEDIADOR
    ;
    IF _ERROR_ THEN CALL SYMPUT(‘_EFIERR_’,1); /* SET ERROR DETECTION MACRO VARIABLE */
    IF POLIZA EQ «» THEN DELETE;
    RUN;

    proc sql;
    insert into fin.&tabla.
    select * from &tabla.;
    quit;

    %MEND CARGA_RECIBOS;

    proc sql;
    delete from FIN.RECIBOS_COASEG_PPNC0218;
    quit;

    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-03_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-04_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-05_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-06_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-07_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-08_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-09_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-10_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-11_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2017-12_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2018-01_recibos_coaseg», RECIBOS_COASEG_PPNC0218);
    %CARGA_RECIBOS(«/sas/FICHEROS/Input/FINANCIERO/2018/RECIBOS/2018-02_recibos_coaseg», RECIBOS_COASEG_PPNC0218);

    Muchas gracias

  13. Buen dia, alguien me podría ayudar tengo algunos querys realizados en otros servidores (nodos) pero no los puedo ejecutar ahora en mi computadora debido a que no tengo acceso a estos, saben si se pueden migrar o como podría yo ejecutarlos sin que me marque error, gracias, quedo en espero de sus comentarios

  14. Hola, muy interesante esta entrada, mi pregunta es si puede aplicar esto mismo si la tabla existe pero esta vacía, es decir, yo quiero que si al ejecutar una query la tabla salga vacía se haga una cosa y si no, otra.
    Gracias de antemano. Saludos

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *