2016-09-02 3 views
2

Моя первая работа с Perl. Я использую его, чтобы принимать данные из нескольких ячеек из одного файла Excel и помещать их в другой существующий файл Excel.Почему этот массив печатает только последний номер?

Мне удалось извлечь нужные данные из первого файла и поместить его в файл @array. Я начал новый файл, чтобы экспериментировать с записью данных в конкретные ячейки, которые мне нужны.

Проблема заключается в том, что при запуске скрипта он имеет одинаковое число во всех ячейках 18365. Хотя массивы @rows работают правильно и помещают номер в правильную ячейку, массив @revenue печатает только последний номер.

Есть ли что-то, что я пропускаю или не понимаю? Есть лучший способ сделать это? Я благодарю вас заранее.

use warnings; 
use strict; 
use Spreadsheet::ParseExcel; 
use Spreadsheet::ParseExcel::SaveParser; 

my $parser = Spreadsheet::ParseExcel::SaveParser->new(); 
my $workbook = $parser->Parse('xls_test.xls'); 

if (!defined $workbook) { 
    die $parser->error(), ".\n"; 
} 

my $worksheet = $workbook->worksheet(0); 

my @rows = (2, 10, 17); 
my @revenue = (10200, 9025, 18365); 

my $col = 2; 

foreach my $rev (@revenue) { 
    foreach my $r (@rows) { 
     $worksheet->AddCell($r, $col, "$rev"); 
    } 
} 

$workbook->SaveAs('xls_test.xls'); 
+1

Массивы не печатают ничего. Это ваш код, который делает материал, а не массив. – simbabque

ответ

3

Если вы берете цикл:

foreach my $rev (@revenue) { 
    foreach my $r (@rows) { 
    $worksheet->AddCell($r, $col, "$rev"); 
    } 
} 

Последние $rev писать это 18365, и вы перезаписать предыдущие значения во всех 3-х рядов.

Что вы можете сделать, это создать хэш строки к доходам от обоих списков и пройти через него:

my @rows = (2, 10, 17); 
my @revenue = (10200, 9025, 18365); 
my $col = 2; 

my %data; 
for my $i (0 .. $#rows) { 
    $data{$rows[$i]} = $revenue[$i]; # row => revenue 
} 

foreach $row (keys %data) { 
    $worksheet->AddCell($row, $col, $data{$row}); 
} 
+0

Это работает точно так, как я хотел. Я буду изучать хеши немного больше. Спасибо. – MBH

2

Вот иллюстрация того, что делает ваш код. Я заменил AddCell на простой say, который похож на print с новой строкой в ​​конце.

use strict; 
use warnings 'all'; 
use feature 'say'; 
my @rows = (2, 10, 17); 
my @revenue = (10200, 9025, 18365); 

my $col = 2; 

say "row\tcol\trev"; 
foreach my $rev (@revenue) { 
    foreach my $r (@rows) { 
     say join "\t", $r, $col, $rev; 
    } 
} 

И это выход:

row col rev 
2 2 10200 
10 2 10200 
17 2 10200 
2 2 9025 
10 2 9025 
17 2 9025 
2 2 18365 
10 2 18365 
17 2 18365 

Как вы можете видеть, что перебирает все доходы, а затем для каждого дохода он записывает строки 2, 10 и 17.

2 2 10200 
10 2 10200 
17 2 10200 

И вот оно снова.

2 2 9025 
10 2 9025 
17 2 9025 

Поскольку он всегда находится в одном столбце (это 2), значения будут перезаписаны. Вот почему есть только последний раунд значений.

Я действительно не знаю, что вы ожидаете как правильный вывод, но поскольку у вас есть фиксированные строки, вы можете использовать три столбца? Вы можете увеличить переменную $col после того, как закончите писать все строки для каждого $rev.

foreach my $rev (@revenue) { 
    foreach my $r (@rows) { 
     $worksheet->AddCell($r, $col, $rev); 
    } 
    $col++; 
} 

Теперь результат нашей маленькой программы выше будет таким, и все значения будут там.

row col rev 
2 2 10200 
10 2 10200 
17 2 10200 
2 3 9025 
10 3 9025 
17 3 9025 
2 4 18365 
10 4 18365 
17 4 18365 

Обратите внимание, что я удалил двойные кавычки вокруг ""$rev. Вам не нужно указывать такие переменные.

+0

Благодарим вас за четкое объяснение. Кажется, я понимаю, где я раньше ошибался. Желаемый результат будет строки Col оборотов 2 2 10200 - 10 2 9025 - 17 2 18365 - Поэтому мне нужно их в цикле, но только один раз. К сожалению, я работаю с существующей таблицей, поэтому использование дополнительных столбцов не работает. – MBH

Смежные вопросы