質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

909閲覧

PHP 年ごとに集計出力

yoheiiii

総合スコア91

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/06/21 10:11

編集2020/06/22 11:48

Windows10にXAMPPを入れ
CSVデータを取り込み集計出力を行っています。

2019-1-1,150,
2019-1-3,,100
2019-2-1,100,
2019-2-19,,150
2019-3-11,50,
2019-6-19,,100
2019-7-19,150,
2019-7-21,,100
2019-8-19,100,
2019-8-20,,150
2019-9-20,50,
2019-12-20,,100
2020-1-1,150,
2020-1-10,,100
2020-2-10,100,
2020-2-26,,150
2020-3-26,50,
2020-6-26,,100

上記データを取り込み下記のように
出力できるまでできました。

2019年1月入金集計:150、出金合計:100
2019年2月入金集計:100、出金合計:150
2019年3月入金集計:50、出金合計:0
2019年6月入金集計:0、出金合計:100
2019年7月入金集計:150、出金合計:100
2019年8月入金集計:100、出金合計:150
2019年9月入金集計:50、出金合計:0
2019年12月入金集計:0、出金合計:100
2020年1月入金集計:150、出金合計:100
2020年2月入金集計:100、出金合計:150
2020年3月入金集計:50、出金合計:0
2020年6月入金集計:0、出金合計:100

=========================================
トータル:入金合計:900、出金合計:1050

下記のように一度年で合計を入れたいです。

2019年1月入金集計:150、出金合計:100
2019年2月入金集計:100、出金合計:150
2019年3月入金集計:50、出金合計:0
2019年6月入金集計:0、出金合計:100
2019年7月入金集計:150、出金合計:100
2019年8月入金集計:100、出金合計:150
2019年9月入金集計:50、出金合計:0
2019年12月入金集計:0、出金合計:100
----------------------
2019年:入金合計:600、出金合計:700

2020年1月入金集計:150、出金合計:100
2020年2月入金集計:100、出金合計:150
2020年3月入金集計:50、出金合計:0
2020年6月入金集計:0、出金合計:100
----------------------
2020年:入金合計:300、出金合計:350

=========================================
トータル:入金合計:900、出金合計:1050

【現状のコード】

<?php if (sizeof($argv) <= 1) { echo "ファイルが指定されていませんので処理終了します。".PHP_EOL; exit; } $input_file = $argv[1]; if (!file_exists($input_file)) { echo "指定された情報はファイルではありませんので処理終了します。".PHP_EOL; exit; } $fp = fopen($input_file, 'r'); if ($fp === false) { echo "ファイルオープン時に失敗したので処理終了します。".PHP_EOL; exit; } $is_error = false; $break_key_year = ''; $break_key_month = ''; $i=0; // ★From $nyukin = 0; // 入金ワーク $syukin = 0; // 出金ワーク // ★To while ($line = fgets($fp)) { $i++; // ファイル読込終了判定 if (feof($fp)) { break; } // ファイル読込エラー判定 if ($line === false) { echo "ファイル読込時に失敗したので処理終了します。".PHP_EOL; $is_error = true; break; } // カンマ分割 $work_field = explode(',', $line); // 日付分割 $work_date = explode('-', $work_field[0]); // ★From $a[] = $work_field[1]; $b = array_sum($a); $c[] = $work_field[2]; $d = array_sum($c); // ★To // ブレイク判定 if(($break_key_year != $work_date[0])){ if ($i != 1) { echo '---------------------------------------------------'.PHP_EOL; echo $break_key_year.'年:'.'入金合計:'.$b.'出金合計:'.$d.PHP_EOL; echo PHP_EOL; } } if (($break_key_year != $work_date[0]) || ($break_key_month != $work_date[1])) { if ($i != 1) { echo $break_key_year.'年'.$break_key_month.'月'.'入金集計:'.$nyukin.'、出金合計:'.$syukin.PHP_EOL; $nyukin = 0; $syukin = 0; // ★To } // ブレイク判定変数に現在の行の情報を退避 $break_key_year = $work_date[0]; $break_key_month = $work_date[1]; } // ★From $w_nyukin = trim($work_field[1]); $w_syukin = trim($work_field[2]); if(empty($w_nyukin) && empty($w_syukin)){ echo $i.'行目のデータがありませんのでデータをスキップします。'.PHP_EOL; continue; } //通常処理 if (empty($w_nyukin)) { $syukin += $w_syukin; } else { $nyukin += $w_nyukin; } if(($break_key_year != $work_date[0])){ if($i != 1){ echo $break_key_year.'年:'.'入金合計:'.$b.'出金合計:'.$d.PHP_EOL; } } } echo $break_key_year.'年'.$break_key_month.'月'.'入金集計:'.$nyukin.'、出金合計:'.$syukin.PHP_EOL; echo '---------------------------------------------------'.PHP_EOL; echo $break_key_year.'年:'.'入金合計:'.$b.'出金合計:'.$d.PHP_EOL; echo PHP_EOL; echo '========================================='.PHP_EOL; echo 'トータル:'.'入金合計:'.$b.'、出金合計:'.$d.PHP_EOL; fclose($fp); if ($i == 0) { echo "指定されたファイルは空ファイルでした。".PHP_EOL; }

【試したこと】
下記コードを追加しました。

if(($break_key_year != $work_date[0])){
if ($i != 1) {
echo '---------------------------------------------------'.PHP_EOL;
echo $break_key_year.'年:'.'入金合計:'.$b.'出金合計:'.$d.PHP_EOL;
echo PHP_EOL;
}
}

イメージ説明

しかし結果は上記のように2019年の12月だけが2020年側にいってしまいます。

ご教授頂ければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

csv の仕様が不明ですが、時系列で確実に記述されているのであれば、ループの中で$work_date[0]が変化したときに、年の合計を表示させ、年の合計を初期化してやるように条件文を記述すればよいです。

月の集計と同じ考え方なので、何が理解できていないのかちょっとわかりません。

csv がそれほど大きくないのであれば、csv を一度配列にし、単純な配列の計算処理として設計しなおせば、途中のファイルに対しての分岐処理が整理できて読みやすいコードになります。
(ただ、その分余計な時間がかかるようにはなりますが。。。)

投稿2020/06/21 21:02

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoheiiii

2020/06/22 11:49

コードを最新に更新し現状の結果も添付させて頂きましたが、 なぜか2019年の12月だけが2020年側にいってしまいます。
guest

0

<?php if (sizeof($argv) <= 1) { echo "ファイルが指定されていませんので処理終了します。".PHP_EOL; exit; } $input_file = $argv[1]; if (!file_exists($input_file)) { echo "指定された情報はファイルではありませんので処理終了します。".PHP_EOL; exit; } $fp = fopen($input_file, 'r'); if ($fp === false) { echo "ファイルオープン時に失敗したので処理終了します。".PHP_EOL; exit; } $is_error = false; $break_key_ym = date("Y", strtotime("-1 year")).'01'; //2019.01 $i=0; $m_nyukin = 0; // 月次入金ワーク $m_syukin = 0; // 月次出金ワーク $y_nyukin = 0; // 年次入金ワーク $y_syukin = 0; // 年次出金ワーク $t_nyukin = 0; // 合計入金ワーク $t_syukin = 0; // 合計出金ワーク while ($line = fgets($fp)) { $i++; // ファイル読込終了判定 if (feof($fp)) { break; } // ファイル読込エラー判定 if ($line === false) { echo "ファイル読込時に失敗したので処理終了します。".PHP_EOL; $is_error = true; break; } // カンマ分割 $work_field = explode(',', $line); // 日付分割 $work_date = explode('-', $work_field[0]); $target_ym = $work_date[0].$work_date[1]; //2019.01 から順に入っていく // 金額妥当性チェック $w_nyukin = trim($work_field[1]); $w_syukin = trim($work_field[2]); if(empty($w_nyukin) && empty($w_syukin)){ echo $i.'行目のデータがありませんのでデータをスキップします。'.PHP_EOL; continue; } if ($break_key_ym > $target_ym) { echo $i.'行目は無視'.PHP_EOL; continue; } else if ($break_key_ym < $target_ym) { //2019.01 < 2019.02 2月から出力? // echo '中間ワークの内容を出力'.PHP_EOL; echo substr($break_key_ym, 0, 4).'年'.substr($break_key_ym, 4, 2).'月'.'入金集計:'.$m_nyukin.'、出金合計:'.$m_syukin.PHP_EOL; $m_nyukin = 0; // 月次入金ワーク $m_syukin = 0; // 月次出金ワーク while ($break_key_ym != $target_ym) { //1月以外? if (substr($break_key_ym, -2) == 12) { // echo 'ブレイクキーが12月の場合、年出力を行う'.PHP_EOL; echo '---------------------------------------------------'.PHP_EOL; echo substr($break_key_ym, 0, 4).'年:'.'入金合計:'.$y_nyukin.'、出金合計:'.$y_syukin.PHP_EOL; $break_key_ym = substr($break_key_ym, 0, 4)+1 . "01"; //12月出力したら2020年へ $y_syukin = 0; // 年次入金ワーク $y_nyukin = 0; // 年次出金ワーク } else { $break_key_ym += 1; } if ($break_key_ym < $target_ym) { // echo $break_key_ym.'の入金、出金が0の旨を出力'.PHP_EOL; echo substr($break_key_ym, 0, 4).'年'.substr($break_key_ym, 4, 2).'月'.'入金集計:'.$m_nyukin.'、出金合計:'.$m_syukin.PHP_EOL; $m_nyukin = 0; // 月次入金ワーク $m_syukin = 0; // 月次出金ワーク } } $break_key_ym = $target_ym; } if ($break_key_ym > date("Ym")) { //今月越えたら終わり break; } // echo '中間ワークに加算'.PHP_EOL; if (empty($w_nyukin)) { $m_syukin += $w_syukin; $y_syukin += $w_syukin; $t_syukin += $w_syukin; } else { $m_nyukin += $w_nyukin; $y_nyukin += $w_nyukin; $t_nyukin += $w_nyukin; } } fclose($fp); if ($i == 0) { echo "指定されたファイルは空ファイルでした。".PHP_EOL; } else { if ($break_key_ym < date("Ym")) { while ($break_key_ym != $target_ym) { if (substr($break_key_ym, -2) == 12) { // echo 'ブレイクキーが12月の場合、年出力を行う'.PHP_EOL; echo '---------------------------------------------------'.PHP_EOL; echo substr($break_key_ym, 0, 4).'年:'.'入金合計:'.$y_nyukin.'、出金合計:'.$y_syukin.PHP_EOL; $break_key_ym = substr($break_key_ym, 0, 4)+1 . "01"; $y_syukin = 0; // 年次入金ワーク $y_nyukin = 0; // 年次出金ワーク } else { $break_key_ym += 1; } if ($break_key_ym < $target_ym) { // echo $break_key_ym.'の入金、出金が0の旨を出力'.PHP_EOL; echo substr($break_key_ym, 0, 4).'年'.substr($break_key_ym, 4, 2).'月'.'入金集計:'.$m_nyukin.'、出金合計:'.$m_syukin.PHP_EOL; $m_nyukin = 0; // 月次入金ワーク $m_syukin = 0; // 月次出金ワーク } } } else if ($break_key_ym == date("Ym")) { echo substr($break_key_ym, 0, 4).'年'.substr($break_key_ym, 4, 2).'月'.'入金集計:'.$m_nyukin.'、出金合計:'.$m_syukin.PHP_EOL; $m_nyukin = 0; // 月次入金ワーク $m_syukin = 0; // 月次出金ワーク } echo '---------------------------------------------------'.PHP_EOL; echo substr($break_key_ym, 0, 4).'年:'.'入金合計:'.$y_nyukin.'、出金合計:'.$y_syukin.PHP_EOL; echo '========================================='.PHP_EOL; echo 'トータル:'.'入金合計:'.$t_nyukin.'、出金合計:'.$t_syukin.PHP_EOL; }

投稿2020/07/01 21:28

yoheiiii

総合スコア91

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問