Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Im fairly new to Perl and was wondering why my code isnt printing to the files? Im trying to create 2 sepereate files based on the store number. could it be because I open and close my file within the loop? Thanks in advance. Jim..
$last_4_chars = "0001"; @all_stores = qw("24","25"); foreach $store(@all_stores) { #This sas file will seperate the datasets by stores #Opens file to write to die("Cannot open weekly_$store_pdf.sas to read from ") unless(open(FINAL, ">weekly_$store_pdf.sas")); $prep_pdf = "libname bce '/cdw/dept/dss/home_dir/s006258/BCE';\n". "proc sql;\n". "SELECT FILEDATE,RPTSTORE,RPTTEAM,FIRSTNAME,LASTNAME,WTDTRAN, \n". " WTDOFFERS,WTDAPPS, substr(WTDOFFERS/WTDAPPS,0,5) as WTD_RATE, +\n". " (case\n". " when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= 1. +2 then 'G'\n". " when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) <= 1. +2 and\n". " (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= + .65 then 'Y'\n". " when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) < .65 + then 'R'\n". " end) as WTD_Color \n". " MTDTRAN,MTDOFFERS,MTDAPPS, substr(MTDOFFERS/MTDAPPS,0,5) as M +TD_RATE,\n". " (case\n". " when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= 1. +2 then 'G'\n". " when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) <= 1. +2 and\n". " (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= + .65 then 'Y'\n". " when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) < .65 + then 'R'\n". " end) as MTD_Color\n". "FROM bce.yearly_g$last_4_charsv00\n". "WHERE RPTSTORE = $store\n". "Order by RPTTEAM"; print FINAL "$prep_pdf"; close(FINAL); }

Replies are listed 'Best First'.
Re: Printing to file
by philcrow (Priest) on Jul 12, 2006 at 17:36 UTC
    I think your file name interpolation has a slight problem, in addition to the one mentioned by a previous responder.

    Try replacing the file name with:

    weekly_${store}_pdf.sas
    so Perl does not try to interpolate the non-existent $store_pdf variable.

    You probably want to add use strict; at the top to catch this type of error.

    Phil

Re: Printing to file
by ikegami (Patriarch) on Jul 12, 2006 at 17:49 UTC

    (This continues from where philcrow and runrig left off.)

    In

    die("Cannot open weekly_${store}_pdf.sas to read from ") unless(open(FINAL, ">weekly_${store}_pdf.sas"));
    • the error message is wrong ("read" vs "write"),
    • the error message is grammatically incorrect (nothing follows the preposition "from"),
    • the error message is incomplete (it doesn't state the reason for the failure),
    • the file handle is not localized,
    • package variables are used where lexical variables could be used,
    • the 2 argument calling syntax of open is used rather than the safer 3 argument calling syntax, and
    • the purpose of the statement (open) is hidden deep in the statement.

    Fix:

    open(my $fh_final, '>', "weekly_${store}_pdf.sas") or die("Unable to open weekly_${store}_pdf.sas for writing: $!\n");

    Don't forget to replace the occurences of "FINAL" in the remainder of your code with "$fh_final".

      Hmm I tried using your fix and the error states: "Unable to open weekly_"24,"25"_pdf.sas for writing : Invalid arguments+". I must be doing something wrong...
        That's an unrelated problem, already answered above.
Re: Printing to file
by samtregar (Abbot) on Jul 12, 2006 at 17:32 UTC
    Yup - every time you execute open() the file will be overwritten. You could change your open() mode from ">" to ">>" for appending, but moving the open() and close() outside the loop looks like a more obvious fix.

    -sam

      Well it didnt create any file at all. Also I need it done so that the file name will contain the number 24 and 25 in the title of the files. I also need that store number to be replaced in the file ($store). What would be a better way to do this??? Thanks Jim...
Re: Printing to file
by runrig (Abbot) on Jul 12, 2006 at 17:38 UTC
    You'll want to use ${store} within the double quotes, or else perl will interpolate the entire $store_pdf as the variable name. You'd catch this with use strict (See docs as well as related tutorials in Tutorials.
      I tried using both ($store) and ${store} but they both seem to give me the same error. Error : "Cannot open weekly_"24","25"_pdf.sas to read from"
        On to the next error :-)

        qw() creates an array, from items separated by whitespace. Quotes and commas in qw() are usually a mistake. You want:

        my @all_stores = qw(24 25);
        Or if, e.g., you wanted more stores (e.g. 10 to 99):
        my @all_stores = (10..99); # or even ("10".."99")
        That's due to how you're setting up your @all_stores array. You're mixing up the qw and standard array syntaxes. You need either:
        @all_stores = ("24", "25");
        *or*
        @all_stores = qw(24 25);

        Try put use strict;
        @all_stores = qw("24", "25"); will produce error. Try my @all_stores = qw(24 25); instead

        "The giving hands is better than the one accepting" - Muslim's cleric
Re: Printing to file
by jwkrahn (Abbot) on Jul 12, 2006 at 20:00 UTC
    It looks like you have a few problems with that code. If you want it to work with warnings and strict enabled then:
    my $last_4_chars = '0001'; my @all_stores = map { # This sas file will seperate the datasets by stores # Opens file to write to open my $fh, '>', "weekly_${_}_pdf.sas" or die "Cannot open weekly +_${_}_pdf.sas: $!"; [ $_, $fh ] } qw( 24 25 ); for my $store ( @all_stores ) { print { $store->[ 1 ] } <<STORE; libname bce '/cdw/dept/dss/home_dir/s006258/BCE'; proc sql; SELECT FILEDATE,RPTSTORE,RPTTEAM,FIRSTNAME,LASTNAME,WTDTRAN, WTDOFFERS,WTDAPPS, substr(WTDOFFERS/WTDAPPS,0,5) as WTD_RATE, (case when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= 1.2 then + 'G' when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) <= 1.2 and (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= .65 then + 'Y' when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) < .65 then +'R' end) as WTD_Color MTDTRAN,MTDOFFERS,MTDAPPS, substr(MTDOFFERS/MTDAPPS,0,5) as MTD_RA +TE, (case when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= 1.2 then + 'G' when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) <= 1.2 and (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) >= .65 then + 'Y' when (substr(sum(WTDAPPS)/sum(WTDOFFERS),0,4)*100) < .65 then +'R' end) as MTD_Color FROM bce.yearly_g${last_4_chars}v00 WHERE RPTSTORE = $store->[0] Order by RPTTEAM STORE } close $_->[ 1 ] for @all_stores;
Re: Printing to file
by perl_devel (Friar) on Jul 13, 2006 at 09:06 UTC
    can you change the part of the code like below and try
    $filename="weekly_$store"."_pdf.sas"; open(FINAL, ">$filename") || die ("unable to open file $filename to wr +ite becuase of $!";
Re: Printing to file
by Yunus (Novice) on Jul 14, 2006 at 01:18 UTC
    $variable (no quote) is preferred, than "$variable"
    e.g.
    print FINAL $prep_pdf;
    "The giving hands is better than the one accepting" - Muslim's cleric