仕訳データを取り込むの続き(前編)
消耗品の場合は、摘要の内容も入力したいので、
少しばかり修正することにした。
use v5.14; use strict; use warnings; use utf8; use FindBin; my $yyyy = 2013; my $data_dir = $FindBin::Bin . '/' . $yyyy; # debtor: 借方 # creditor: 貸方 # summary: 摘要 # tax_class: 税区分 my $template = 'date,debtor_id,,price,tax_class,creditor_id,,price,,summary'; write_data( 'import/01_book.csv', { file => 'book.txt', debtor_id => 241, tax_class => 3, creditor_id => 100, summary => "書籍代" } ); sub load_csv { my $file = shift; my $in_file = $data_dir . '/' . $file; open(my $fh, $in_file) or die $! . " : cannot open $in_file"; my @data = (); while (<$fh>) { chomp; my @tmp = split /,/, $_; my $h = {}; if ( my ($MM, $dd) = $tmp[0] =~ /(1?\d)\/([1-3]?\d)/ ) { $h->{date} = sprintf( "%04d/%02d/%02d", $yyyy, $MM, $dd ); } else { say $_, ' <<< date is wrong!', " ($.)"; } if ( my ($price) = $tmp[1] =~ /(\d{2,6})/ ) { $h->{price} = $price; } else { say $_, ' <<< price is wrong!', " ($.)"; } if ( 3 <= scalar(@tmp) ) { $h->{summary} = $tmp[2]; } push @data, $h; } close $fh; return \@data; } sub write_data { my $out_file = shift; my $arg_ref = shift; my $data_ref = load_csv( $arg_ref->{file} ); my $replaced = $template =~ s/debtor_id/$arg_ref->{debtor_id}/r =~ s/tax_class/$arg_ref->{tax_class}/r =~ s/creditor_id/$arg_ref->{creditor_id}/r; my $summary = ''; $summary = $arg_ref->{summary} if exists $arg_ref->{summary}; local $\ = "\r"; open my $fh, '>:encoding(utf-8)', $out_file or die $! . " : cannot open $out_file"; foreach (sort { $a->{date} cmp $b->{date} } @{$data_ref}) { my $date = $_->{date}; my $price = $_->{price}; $summary = $_->{summary} if exists $_->{summary}; print $fh $replaced =~ s/price/$price/gr =~ s/date/$date/gr =~ s/summary/$summary/gr; } close $fh; }
これだと、入力するデータの3つ目を摘要として扱える。
ただ、たいぶ不格好なスクリプトになってしまったのと、
出力順を固定にするためにテンプレートを置換をするのはアレなので、
リファクタリングを継続しようと思う。
作戦としては、読み込みを行うタイミングでデフォルト値を渡して、
出力する側が、順番のみ担保する感じしようと思う。
でもって、もっと大切なことは、データを入力すること・・・。
おしまい。
Leave a Comment