Un momento, un momento, un momento...
Las condiciones de poner un 'NaN' ahora son otras... Hay que poner un 'NaN' cuando en la celda contiene un '-'. Y solo en ese caso.
Pero, además... ocurre que por fin nos enteremos de cómo es en realidad las celdas de la hoja: resulta que las filas están "dobladas" (una celda de una fila comparte contenido con la celda que le sigue en la fila de abajo) para las celdas que solo contienen números; y son simples (una celda con número y una celda con un texto) cuando vienen acompañadas de un texto.
Entonces... mal iba a funcionar la expresión regular de esa manera... En realidad, son dos las celdas que hay que leer. Hay que ver si la celda que hay debajo de ella contiene un '-' o no.
La siguiente solución tiene en cuenta todo eso:
Using perl Syntax Highlighting
#!/usr/bin/perl
use v5.10; # lo necesitamos para el 'say' y el operador '//'
use strict;
use warnings;
use diagnostics;
use Spreadsheet::Read;
## Constantes
my $year = 2013;
my $ruta = "/home/modelacion/Escritorio/excel_perl";
my @meses = (
[ 'Enero', 'January', 31 ],
[ 'Febrero', 'February', 29 ],
[ 'Marzo', 'March', 31 ],
[ 'Abril', 'April', 30 ],
[ 'Mayo', 'May', 31 ],
[ 'Junio', 'June', 30 ],
[ 'Julio', 'July', 31 ],
[ 'Agosto', 'August', 31 ],
[ 'Septiembre', 'September', 30 ],
[ 'Octubre', 'October', 31 ],
[ 'Noviembre', 'November', 30 ],
[ 'Diciembre', 'December', 31 ],
);
## Proceso
open my $OUT, '>', 'datos.txt';
for my $mes (@meses) {
my ( $mes_spa, $mes_eng, $mes_dias ) = @{$mes};
my $archivo = "$ruta/Inf-WS-$mes_eng$year.xls";
next if not -e $archivo; # saltamos al siguiente, si no existe archivo de ese mes
my $ref = ReadData($archivo);;
my $HOJA = $ref->[1]->{cell};
for my $fila ( 0 .. 23 ) { # son 24 filas dobles
my @fila;
for my $columna ( 1 .. $mes_dias ) {
my $celda_arriba = $HOJA->[$columna]->[1+2*$fila] // '';
my $celda_abajo = $HOJA->[$columna]->[2+2*$fila] // '';
if (index($celda_abajo, '-') != -1) { # si la parte de abajo contiene un '-'
$celda_arriba = 'NaN'; # 'NaN'deamos la parte de arriba
}
push @fila, $celda_arriba;
}
say $OUT "@fila";
}
}
close $OUT;
Coloreado en 0.006 segundos, usando
GeSHi 1.0.8.4
Se procede de la siguiente manera: hacemos un bucle por las 24 filas dobles. No son filas de la hoja, sino filas de datos. Usamos $fila como índice para acceder a la posición que nos interesa (una celda en la parte superior y otra en la inferior).
Si la celda que contiene un número, está compartida con la que le sigue abajo. Ésta última no está definida, pero con el operador '//' la convertimos a un cadena vacía.
Si la celda contiene un número más un texto, el número aparece en la primera celda (igual que el caso anterior), y la celda que le sigue abajo contiene el texto. Entonces, comprobamos si en ese texto aparece un '-' (con la función
index()). Si es así, modificamos el valor numérico a 'NaN'.
Las primeras filas que salen:
Using text Syntax Highlighting
2.93 0.58 5.88 5.93 8.6 4.94 1.18 2.44 0.92 6.36 2.58 6.48 1.9 4.68 5.79 3.64 3.37 2.28 5.07 1.93 2.16 3.43 1.24 1.74 1.99 1.33 3.19 1.48 NaN NaN 1.89
2.67 0.68 4.72 6.17 4.75 4.98 0.68 2.07 1.54 7.1 2.58 6.77 0.77 4.38 2.95 3.64 3.37 0.76 3.26 2.22 1.93 4.09 1.59 1.19 1.76 2.82 3.23 1.33 NaN NaN 1.86
1.81 0.99 4.33 7.69 4.89 3.44 1.15 1.73 2.3 6.12 2.58 2.82 1.19 2.95 2.07 3.49 3.37 2.67 1.09 2.29 2.48 4.23 2.19 0.74 1.38 1.44 2.44 0.96 NaN NaN 2.09
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Esta es otra versión, con dos modificaciones: genera por si sola los nombres de los meses en inglés (solo si en el sistema, se ha compilado la configuración regional 'en_IE'. Comprobarlo con el comando
locale -a), y siempre genera 31 columnas, que facilita el procesado posterior.
Using perl Syntax Highlighting
#!/usr/bin/perl
use v5.10;
use strict;
use warnings;
use diagnostics;
use Spreadsheet::Read;
## Constantes
my $year = 2013;
my $ruta = "/home/modelacion/Escritorio/excel_perl";
use POSIX qw(strftime locale_h);
my $anterior_locale = setlocale(LC_TIME, "en_IE"); # pasar a inglés
my @meses = map { strftime '%B', 0,0,0, 1,$_,$year, 0,0,0 } 0 .. 11; # nombres de los meses, en inglés
setlocale(LC_TIME, $anterior_locale); # volvemos a español
## Proceso
open my $OUT, '>', 'datos.txt';
for my $mes (@meses) {
my $archivo = "$ruta/Inf-WS-$mes$year.xls";
next if not -e $archivo; # saltamos al siguiente, si no existe archivo de ese mes
my $ref = ReadData($archivo);;
my $HOJA = $ref->[1]->{cell};
for my $fila ( 0 .. 23 ) { # son 24 dobles filas
my @fila;
for my $columna ( 1 .. 31 ) {
my $celda_arriba = $HOJA->[$columna]->[1+2*$fila] // '';
my $celda_abajo = $HOJA->[$columna]->[2+2*$fila] // '';
if (index($celda_abajo, '-') != -1) { # si la parte de abajo contiene un '-'
$celda_arriba = 'NaN'; # 'NaN'deamos la parte de arriba
}
push @fila, $celda_arriba;
}
say $OUT "@fila";
}
}
close $OUT;
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4