忍者ブログ
[600] [599] [598] [597] [596] [595] [594] [593] [592] [591] [590
カレンダー
06 2024/07 08
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
カテゴリー
最新コメント
最新トラックバック
バーコード
ブログ内検索
アクセス解析
まずは勤務表にサインをされる方からPHPでCSVファイルを読み込むようにと言われたので、私はPHPでCSVファイルを読み込む方法が分からないと言うと、勤務表にサインをされる方はインターネットで調べるようにとおっしゃりました。
私はインターネットで調べ、PHPでCSVファイルを読み込んでみたら上手く行きました。
勤務表にサインをされる方が実際に使っているCSVファイルを見せられ、データがいくつか重複しているので、重複しないように読み込むように、重複しないデータを表示させて、左側にラジオボタンを付けて、選択したデータをもとに更にデータを絞り込んで、絞り込んだデータも重複させないようにと言われましたが、私はしばらくしてデータを重複させないようにという意味が分からなくなったので、勤務表にサインをされる方に聞くと、勤務表にサインをされる方はCSVファイルをExcelで開かれ、データが重複している列を選択され、ツールバーのデータ→フィルタ→フィルタオプションの設定→フィルタオプションの設定で重複するレコードは無視するをチェック→OKでデータの重複がなくなりました。
元に戻す場合はツールバーのデータ→フィルタ→フィルタオプションの設定→フィルタオプションの設定で重複するレコードは無視するはチェックしない→OKで元に戻ります。
私は意味が分かったので、PHPでどう処理するか考えました。
まず、CSVファイルのデータの量はいつも同じではないので、PHPで要素数の決まっていない配列が使えるかどうか調べました。
まず、九九を表示させるプログラムを作る事にしました。
普通の2次元配列と要素数の決まっていない2次元配列を定義して、普通の2次元配列に九九の値を代入して普通の2次元配列を表示させ、次に要素数の決まっていない2次元配列に九九の値を代入して要素数の決まっていないを表示させたら上手く行きました。
foreachで2次元配列が使えるかどうかも調べたら上手く行きました。

<html>
<head>
<meta http-equiv="Content-type"
content="text/html; charset=utf-8">
<title>九九を表示</title>
</head>
<body>
<?php
//普通の2次元配列
$test[9][9];
//要素数の決まっていない配列
$test2 = NULL;
for ($i= 1; $i <=9; $i++){
for ($j= 1; $j <=9; $j++){
$test[$i-1][$j-1] = $i * $j;
}
}

for ($i= 1; $i <=9; $i++){
for ($j= 1; $j <=9; $j++){
echo $test[$i-1][$j-1] . " ";
}
echo "<br>";
}

echo "<br>";

for ($i= 1; $i <=9; $i++){
for ($j= 1; $j <=9; $j++){
$test2[$i-1][] = $i * $j;
}
}

for ($i= 1; $i <=9; $i++){
for ($j= 1; $j <=9; $j++){
echo $test2[$i-1][$j-1] . " ";
}
echo "<br>";
}


echo "<br>";

//foreachで表示
foreach ($test2 as $key=>$value){
foreach ($value as $key2=>$value2){
echo $value2 . " ";
}
echo "<br>";
}

?>
</body>
</html>

CSVのデータを1行読み込み、データが重複しているか確認する変数($nflag)を0にして、データを1列ずつ読み込み、データを重複させない列になったら、データが重複しているかどうか調べるために、CSVの値が、重複していないデータ(ラジオボタンと一緒に表示させるデータ、要素数が決まっていない配列)に存在するか調べます。(要素数が決まっていない配列の数まで繰り返します)
存在したら$nflagを1にしてbreakでループを抜け出します。
CSVの値が重複していなければ($nflagが0ならば)CSVの値を要素数の決まっていない配列に追加し、またCSVのデータを1行読み込みます。
ラジオボタンと要素数の決まっていない配列を表示させ、ラジオボタンでデータを選択し、「次へ」ボタンをクリックし、1つ目のページでラジオボタンが選択されているか判断し、選択されていなければ、exitで処理を中断します。
選択されていれば選択した値をもとにしたデータを表示させるページ(2つ目のページ)にジャンプし、また同じ処理を行うのですが、今度は最初に1つ目のページで選択した値とCSVファイルの値が一致しているものを2次元配列に入れる為に2次元配列の1次元目の配列の添字が必要なので、添字($j)を0にします。
次に、CSVのデータを1行読み込む処理でデータを1列ずつ読み込み、1つ目のページと同じデータを重複させない列になったら1つ目のページで選択した値と一致していれば2次元配列にCSVの1行の全てのデータを入れ、$jの値を1つ増やし、またCSVのデータを1行読み込みます。
次に、セッションに2次元配列をセットし、2次元配列をもとにforeach文を使い、データが重複しているかどうか調べるために、データが重複しているか確認する変数($nflag)を0にして、データを1列ずつ読み込み、1つ目のページと同じように2次元配列でデータを重複させない列になったら、データが重複しているかどうか調べるために、2次元配列の値が、重複していないデータ(ラジオボタンと一緒に表示させるデータ、要素数が決まっていない配列)に存在するか調べます。(要素数が決まっていない配列の数まで繰り返します)
存在したら$nflagを1にしてbreakでループを抜け出します。
2次元配列の値が重複していなければ($nflagが0ならば)2次元配列の値を要素数の決まっていない配列に追加します。
ラジオボタンと要素数の決まっていない配列を表示させ、ラジオボタンでデータを選択し、「次へ」ボタンをクリックし、選択した値をもとにしたデータを表示させるページ(3つ目のページ)にジャンプし、2つ目のページで設定したセッションを取り出して2次元配列にセットし、2つ目のページと同じように2つ目のページで選択した値とセッションをセットした2次元配列の値が一致しているものを別の2次元配列に入れる為に別の2次元配列の1次元目の配列の添字が必要なので、添字($k)を0にします。
次に、セッションをセットした2次元配列のデータを読み込む処理で2つ目のページと同じデータを重複させない列になったら2つ目のページで選択した値と一致していれば別の2次元配列にセッションをセットした2次元配列の1次元目の配列の全てのデータを入れ、$kの値を1つ増やし、またセッションをセットした2次元配列のデータを1行読み込みます。
次に、チェックボックスと別の2次元配列を表示させます。
この作業を行っていると勤務表にサインをされる方が来られて、大分進んだようなので、選択した値をもとにCSVファイルを書き換えるように言われました。
今までの作業は私のPCで行っていたので、今までの作業のプログラムを7月からの仕事のプログラムと同じサーバーにアップロードしましたが、文字化けが発生してしまいました…。
インターネットで調べ、文字化けを解決する事が出来ました。
私はPHPでCSVファイルを出力出来るかどうか本で調べてみたら上手く行きました。

<html>
<head>
<meta http-equiv="Content-type"
content="text/html; charset=utf-8">
<title>CSV</title>
</head>
<body>
<?php
$csvFile = "test.csv";
$csvData = "";
for ($i = 0;$i < 5; $i++){
$csvData .= $i. ','
. "サンプル$i-1,"
. "サンプル$i-2,"
. "サンプル$i-3\n";
}
$fp = fopen($csvFile, 'wb');
flock($fp, LOCK_EX);
ftruncate($fp, 0);
fwrite($fp, mb_convert_encoding($csvData, "sjis-win", "utf-8"));
fclose($fp);
echo "csvファイルが作成されました。";

//作成されたcsvファイルを読み込む
$csv = "test.csv" ;
$buf = mb_convert_encoding(file_get_contents($csv), "utf-8", "sjis-win") ;
$fp = tmpfile();
fwrite($fp, $buf);
rewind($fp);
echo '<table border=1>';
while( ( $lines = fgetcsv( $fp ) ) !== FALSE ){
echo '<tr>';
for( $i = 0; $i < count( $lines ); $i ++ ){
echo '<td>' . $lines[$i] . '</td>';
}
echo '</tr>';
}
echo '</table>';
?>
</body>
</html>

今度はPHPで出力されたCSVファイルを変更出来るかどうか試してみたら上手く行きました。
また、7月からの仕事のプログラムではmysqli関数を使っていたので前にmysqli関数を勉強していました。
<html>
<head>
<meta http-equiv="Content-type"
content="text/html; charset=utf-8">
<title>CSV</title>
</head>
<body>
<?php
$csvFile = "test.csv";
$csvData = "";
for ($i = 0;$i < 5; $i++){
$csvData .= $i. ','
. "変更$i-1,"
. "変更$i-2,"
. "変更$i-3\n";
}
$fp = fopen($csvFile, 'wb');
flock($fp, LOCK_EX);
ftruncate($fp, 0);
fwrite($fp, mb_convert_encoding($csvData, "sjis-win", "utf-8"));
fclose($fp);
echo "csvファイルが変更されました。";

//変更されたcsvファイルを読み込む
$csv = "test.csv" ;
$buf = mb_convert_encoding(file_get_contents($csv), "utf-8", "sjis-win") ;
$fp = tmpfile();
fwrite($fp, $buf);
rewind($fp);
echo '<table border=1>';
while( ( $lines = fgetcsv( $fp ) ) !== FALSE ){
echo '<tr>';
for( $i = 0; $i < count( $lines ); $i ++ ){
echo '<td>' . $lines[$i] . '</td>';
}
echo '</tr>';
}
echo '</table>';
?>
</body>
</html>

ファイルを書き換えるページにジャンプしたら

今度はforecahを使い、選択した値を表示させ、選択した値をセッションに設定して、選択した値をもとにファイルを書き換える処理をするページにジャンプするようにしました。

(例)//値が選択された場合
$i = 1;
if (count($_POST["sample"]) > 0){
foreach($_POST["sample"] as $key=>$value){
echo "サンプル:" .$_POST["sample"][$key] . " サンプルA:" .$_POST["samplea"][$key] . " サンプルB:" .$_POST["sampleb"][$key] . "<br>";
$_SESSION["sample". $i] = $_POST["sample"][$key];
$_SESSION["samplea". $i] = $_POST["samplea"][$key];
$_SESSION["sampleb". $i] = $_POST["sampleb"][$key];
$i++;
}
}

header("Location:ファイルを書き換える処理.php");

ファイルを書き換える処理のページでファイルを書き換えようとしたらFatal error: Allowed memory size ofとかいうメッセージが表示されてファイルを上手く書き換える事が出来なかったのでインターネットで調べてini_set("memory_limit","32M");を追加したら上手く行きましたが、今度はパーミッションの設定でファイルを上手く書き換える事が出来なかったので、勤務表にサインをされる方にファイルのパーミッションの設定をしてもらったら上手く行きました。
まずは、ファイルを書き換えるデータを2次元配列に入れる為に2次元配列の1次元目の配列の添字が必要なので、添字($j)を0にします。
次に、CSVのデータを1行読み込んだらセッションに設定した値とCSV値が一致しているというフラグ($sflag)を0にし、データを1列ずつ読み込み、ファイルを書き換えるデータを入れる2次元配列にCSVファイルの値を入れ、CSVの比較したい列になったらセッションに設定した値とCSVの値を比較し、一致したら$sflagを1にして、CSVの書き換えたい列になったら、$sflagが1の場合はファイルを書き換えるデータを入れる2次元配列に書き換えたい値を入れ、$sflagが0の場合はファイルを書き換えるデータを入れる2次元配列にCSVファイルの値を入れ、$kの値を1つ増やし、またCSVのデータを1行読み込みます。
次に、ファイルを書き換えるデータを入れる2次元配列をもとに、ファイルを書き換えるデータをCSVで出力出来るようにし、CSVで出力出来る変数にセットしCSVで出力出来る変数をもとにCSVを出力します。
ファイルの書き換えが上手く行ったと勤務表にサインをされる方に言うと、今度は3つ目のページでファイルが書き換わった事が分かるようにして欲しいと言われたので、チェックボックスと別の2次元配列を表示させるしょりで、foreachを使っていたのをforに変更し、ファイルが書き換わった箇所の色を変え、が書き換わった箇所のhtmlをdisabledにしてチェックボックスをクリック出来ないようにして勤務表にサインをされる方に見せると、勤務表にサインをされる方はチェックボックスをクリック出来るようにして欲しいとおっしゃったので、私はファイルが書き換わった箇所のチェックボックスをクリック出来るようにして、ファイルが書き換わった箇所のチェックボックスをクリックしたらメッセージが表示されるようにして、勤務表にサインをされる方に見せると、勤務表にサインをされる方は、チェックボックスをオフにしてもメッセージが表示されるとおっしゃったので私はチェックボックスにチェックを付けた時だけだけチェックボックスをクリックしたらメッセージが表示されるようにしました。
統合したポータルサイトのトップページの上のフレームのプルダウンメニューを切り替えた時の下のフレームの左側のフレームをJavaScriptで実現したプルダウンを参考にしました。

3つ目のページ
JavaScriptの箇所
function checkMessage(checkID){
if(document.getElementById(checkID).checked){
alert('test');
}
}

htmlの箇所
echo "<td><input type=\"checkbox\" name=\"sample". "[". $i(2次元配列の1次元目の配列の添字) ."]" ."\" value=\"".mb_convert_encoding($value2, "UTF-8", "SJIS")."\" id=\"$i
(2次元配列の1次元目の配列の添字)\" onClick=\"checkMessage($i(2次元配列の1次元目の配列の添字))\" disabled/></td>". '<td>' .mb_convert_encoding($value3, "UTF-8", "SJIS"). '</td>';

その時には勤務表にサインをされる方は8/16迄夏休みだったのですが、勤務表にサインをされる方におっしゃられた事、7月からの仕事のプログラムに今まで作ったプログラムのリンクを貼り、CSVで使えるようにしましたが、CSVで追加したデータが7月からの仕事のプログラムに反映されなかったので、7月からの仕事のプログラムを見てみると
session_name(セッション名);
session_start();
session_name();
とあったので、インターネットで調べてみると、session_name()関数という、セッション名を取得、設定する関数が使われていたので、7月からの仕事のプログラムと同じようにセッションを設定したら上手く行きました。
7月からの仕事のプログラムではmysqli関数を使っていたので、前にmysqli関数の勉強をしていました。
7月からの仕事のプログラムではmysqli関数をトップページにデータベースのデータを表示させたり、セッションの値を引数にしてデータベースからデータを表示させる関数や、入力したデータをデータベースに追加する時や、伝票をExcelで表示させる時に使っていたりしていました。
私はそれらもCSVで使えるようにしました。
セッションの値を引数にしてデータベースからデータを表示させる関数を使っているページで入力したデータを削除したい場合はセッションをNULLにしていました。
セッションの値を引数にしてデータベースからデータを表示させる関数では入力データがデータベースのデータ(従来の方法)の引数は数字なので、is_numeric関数という変数が数字または数字文字列かをチェックする関数を使い、is_numecirがtrueの場合(入力データがデータベースのデータ(従来の方法))はデータベースからデータを表示させ、is_numecirがfalseの場合(入力データがCSV)は引数をそのまま表示させます。
勤務表にサインをされる方が入力したデータをデータベースに追加する時にCSVにも対応出来るように入力したデータを追加するテーブルに列を追加されました。
伝票をExcelで表示させる作業ではデータベースのデータを配列に入れて、配列の値を引数にしてデータベースからデータを表示させる関数を使いましたが、伝票をExcelで表示させるプログラムの1番上に
require_once("データベースからデータを表示させる関数.php(セッションの値を引数にしてデータベースからデータを表示させる関数を使っているプログラムで使用)");
と書いて、セッションの値を引数にしてデータベースからデータを表示させる関数とは少し違う処理をするのでをデータベースからデータを表示させる関数.phpに新たに関数(同じファイルなので違う名前の関数)を追加しようとしましたが、上手く行かなかったの(データベースからデータを表示させる関数.phpに似たようなほかの関数が入っていましたが、それらの関数では上手く行っていました)で、新たにデータベースからデータを表示させる関数2.phpを作成し、そこにデータを表示させる関数.phpと同じ名前の関数を書き、伝票をExcelで表示させるプログラムの1番上にrequire_once("データベースからデータを表示させる関数2.php");
と書いたら上手く行きました。
追加したデータの一部を編集するページでもデータベースのデータを配列に入れて、配列の値を引数にしてデータベースからデータを表示させる関数を使っており、このページでデータを削除する場合のリンク先は同じページで、
(例)データを削除する場合のリンク先
<a href="./データの一部を編集するページ.php?delete=<?php echo $id; ?>&id=<?php echo $dash_id; ?>">削除</a>

データを削除する場合のリンク先をクリックしたかどうかを判断するには$_GET["delete"]に値がセットされているかどうか判断して、CSVファイルを書き換え、データベースからデータを削除します。
また、入力したデータを追加する時に、mysqli->insert_idという直近のクエリで使用した自動生成の ID を返すものを使っていました。(SQL文ではIDを追加する箇所ではNULLが使われていました)
mysqli->insert_idは別のデータベースにもデータを追加する時に使います。
伝票をExcelで表示させる作業ではPHPExcelを使っていて、PHPExcelの修正作業は伝票に追加するデータを増やす作業なのですが、6/4に買ったPHPでExcelを使う本にもPHPExcelの事は載っていましたが、6/4に買ったPHPでExcelを使う本を読まなくても修正作業は上手く行きました。
その後、今まで作ったプログラムのデザインを7月からの仕事のプログラムに合わせる為にCSSファイルを使いました。

htmlの箇所
<LINK href="./css/style.css" rel="stylesheet" type="text/css">

CSVの入力データが変わるとまたFatal error: Allowed memory size ofとかいうメッセージが表示されたのでini_set("memory_limit","64M");にしたら上手く行きました。
追加したデータの一部を編集するページが開かれた時にCSVファイルが書き換わってしまい、いつもページが開くのが遅くなってしまうのでCSVでデータを追加した時だけCSVファイルを書き換えるようにしました。
しばらくして、CSVの入力データの列の数が変わってしまったのでそれに合わせて勤務表にサインをされる方がプログラムを修正して下さり、私もそれとは別に勤務表にサインをされる方からプログラムの修正を頼まれたのでプログラムの修正をしました。
CSVファイルを読み込んで表示させるプログラムで1つ目のページから3つ目のページにジャンプ、つまり、1つ目のページで選択した値をもとにしたデータを表示させるようにしました。
勤務表にサインをされる方は3つ目のページ(追加したデータの一部を編集するページにもあります)にデータベースからデータを取り出して、セレクトボックスにデータを追加して、JavaScriptでセレクトボックスで選択された値だけが表示されるようにしていました。


CSVの読み書き
http://kumicyou.sakura.ne.jp/php/csv.html

制御構造 - foreach
http://www.phppro.jp/phpmanual/php/control-structures.foreach.html

Webにまつわるエトセトラ
http://m-nak.jp/?tag=php

PHPで「Fatal error: Allowed memory size of 8388608 bytes exhausted」エラーが出た
http://colorsk.exblog.jp/13208026/

session_name
http://php.net/manual/ja/function.session-name.php

mysqli->insert_id - 直近のクエリで使用した自動生成の ID を返す
http://phpspot.net/php/man/php/mysqli.insert-id.html

PHPExcelのちょっとつかえる小技
http://blog.asial.co.jp/595

PHP/PHPExcel
http://yakinikunotare.boo.jp/orebase/index.php?PHP%2FPHPExcel#m8ab08d8

PHPExcel の使い方
http://blog.syuhari.jp/archives/1621
PR
この記事にコメントする
name
title
color
mail
URL
comment
pass   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
secret (チェックを入れると管理人だけに表示できます)
この記事へのトラックバック
この記事にトラックバックする:
Powered by Ninja Blog    template by Temp* factory    icon by MiniaureType

忍者ブログ [PR]