人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

フォームからデータベースへのデータの受け渡しについて

下記URLのページを参考に
http://konnokiyotaka.txt-nifty.com/pgblog/2008/02/sql_04a0.html

日々の仕訳をMYSQLに入れたいのですが、伝票番号を自動で与えたり、
複数行のデータを一度にDBへ格納するなど、わたしには難しいことが多いと感じています。

フォームのサンプルを考えて頂けないでしょうか?

ちなみに参考URLでは、仕訳番号、伝票番号、行番号、貸借区分、科目、金額となっていますが、これにタイトルも加えたいと思っております。

[MYSQL5.1 PHP5.2]

●質問者: dekapurio
●カテゴリ:ビジネス・経営 ウェブ制作
✍キーワード:dB MySQL URL タイトル データ
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● km1967
●3ポイント

どういうフォームから入力したいのだがよく分からないが

ご質問のようなグリッドを作りたいならFlexigridを使うといいだろう

詳細は下記

http://journal.mycom.co.jp/articles/2008/06/25/flexigrid/menu.ht...

◎質問者からの返答

入力フォームのサンプルを紹介頂きたかったのですが・・。

でもこれいいですね。今度試してみます。


2 ● kn1967
●2000ポイント ベストアンサー

最終的には本1冊で足りるだろうかという分量になりそうですが、以下、とりあえず・・・。

(コードは今回用にフルスクラッチでゼロから作成したオリジナルです。)


(1)タイトルも加えたい

同じタイトルを何行も繰り返して書くのは効率悪いので、

テーブルを分けたほうが良いですね。(こういった作業を正規化と言います。

データベース構築では、真っ先に行わなければならない作業です。)


とりあえずですが、下記のようにしてみました。

伝票見出テーブル:伝票番号、タイトル

伝票詳細テーブル:伝票番号、行番号、貸借区分、科目、金額

伝票一枚につき、見出テーブル1レコード、詳細テーブルは行数分のレコードとなります。


(2)伝票番号を自動で与える

テーブルを作成する際に AUTO_INCREMENT にしておくだけで自動的に付きます。

http://dev.mysql.com/doc/refman/4.1/ja/example-auto-increment.ht...

番号はデータを追加する際に自動的に増えていき、

最新の番号のついたレコードを削除したとしても、戻るようには出来ていません。

これを防ぐのは並大抵の事ではなく、欠番が出来てしまう事には目をつぶるのが、

自動的に番号を付与する場合の通例(MySQLだけでなく他でも同様)となっています。


下記プログラムでは、伝票見出テーブルの伝票番号をAUTO_INCREMENTにしています。

伝票見出テーブル に一行加える毎に新しい番号が付与され、

それを取得して、伝票詳細テーブルのほうにも書き加えています。


(3)複数行のデータを一度にDBへ格納する

INSERT には一度に複数のレコードを書き込む機能があります。

http://dev.mysql.com/doc/refman/4.1/ja/insert.html

簡単に書くと以下のような感じになります。

INSERT INTO テーブル名 VALUES (1行目),(2行目),(3行目)・・・


(4)伝票入力からSQL生成までの一連の流れを作ってみました。

・a.php b.php c.php の3本です。 a.php が基点となりb.php、c.phpと流れていきます。

・文字エンコードは指定しておりませんのでサーバのphp設定にあわせてください。

・デザインは軽く装飾しただけです。

・動作を学ぶ事を主眼においているため、機能毎にファイルを分けています。

・生成されたSQLの表示までは動作確認していますが、

データベースに書き込む部分は動作確認しておりません。

そもそも完全動作を保証するものでもないので、適宜確認しながら作業してください。

・入力されたデータのチェックは行っていません。

・トランザクションは施していません。

(まだ言い忘れがありそうだけど・・・とりあえず以上)


a.php

<html>
<head>
 <title>伝票入力フォーム</title>
 <style>
 caption { border-bottom:1px solid; text-align:left; }
 td { border:none; padding:0px; margin:0px; text-align:right; }
 input { border-style:none solid solid none; border-color:#AAAAAA; padding:0px; margin:0px; }
 input.accountHeadings { width:20em; }
 input.debit { width:12em; }
 input.credit { width:12em; }
 </style>
</head>
<body>
 <form method="post" action="b.php">
 <table>
 <caption>タイトル<input type="text" name="entrySubTitle"/></caption>
 <thead>
 <tr><th></th><th>借方科目</th><th>金額</th><th>貸方科目</th><th>金額</th></tr>
 </thead>
 <tbody>
 <?php
 for($i = 1; $i <= 10; $i++) { // 伝票の行数は10行
 $row = sprintf('%02d', $i);
 echo '<tr>' . "\n";
 echo '<td>' . $i . '</td>' . "\n";
 echo '<td><input type="input" class="accountHeadings" name="accountHeading1' . $row . '" /></td>' . "\n";
 echo '<td><input type="input" class="debit" name="debit' . $row . '"/></td>' . "\n";
 echo '<td><input type="input" class="accountHeadings" name="accountHeading2' . $row . '" /></td>' . "\n";
 echo '<td><input type="input" class="credit" name="credit' . $row . '"/></td>' . "\n";
 echo '</tr>' . "\n";
 }
 ?>
 </tbody>
 </table>
 <input type="submit" value="確認フォームへ"/>
 </form>
 ※伝票番号はデータベースに書き込む時点で自動的に連番で付与されますので、この時点ではまだ未定です。
</body>
</html>

b.php

<?php
// セッション(データ受け渡し)準備
 session_start();
 if (!isset($_SESSION['sqlStr1'])) {
 session_register('sqlStr1');
 $_SESSION['sqlStr1'] = '';
 }
 if (!isset($_SESSION['sqlStr2'])) {
 session_register('sqlStr2');
 $_SESSION['sqlStr2'] = '';
 }
?>
<html>
<head>
 <title>伝票入力確認フォーム</title>
 <style>
 table { border:1px solid; padding:0px; margin:0px; }
 th { border:1px solid; padding:0px; margin:0px; }
 td { border:1px solid; padding:0px; margin:0px; text-align:right; }
 </style>
</head>
<body>
 <form method="post" action="c.php">
 <table>
<?php
//
// データ受け取りとSQL生成
 if (isset($_POST['entrySubTitle'])) {
 $sqlStr1 = "INSERT INTO 伝票見出テーブル(タイトル) VALUES ('" . $_POST['entrySubTitle'] . '")';
 echo '<caption>' . $_POST['entrySubTitle'] . '</caption>' . "\n";
 } else {
 $sqlStr1 = "INSERT INTO 伝票見出テーブル(タイトル) VALUES ('')";
 echo '<caption>ノータイトル</caption>' . "\n";
 }
 echo '<thead>' . "\n";
 echo '<tr><th>行</th><th>借方科目</th><th>金額</th><th>貸方科目</th><th>金額</th></tr>' . "\n";
 echo '</thead>' . "\n";
 echo '<tbody>';
 $sqlStr2 = 'INSERT INTO 伝票詳細テーブル(伝票番号, 行番号, 貸借区分, 科目, 金額) VALUES ';
 for($i = 1; $i <= 10; $i++) { // 伝票の行数は10行
 $row = sprintf('%02d', $i);
 echo '<tr>' . "\n";
 echo '<td>' . $i . '</td>' . "\n";
 if (isset($_POST['accountHeading1' . $row]) && isset($_POST['debit' . $row])) {
 $sqlStr2a = $_POST['accountHeading1' . $row] . "'," . $_POST['debit' . $row];
 if ($sqlStr2a != "',") {
 $sqlStr2 .= "(" . $i . ",1,'" . $sqlStr2a . '),';
 }
 echo '<td>' . $_POST['accountHeading1' . $row] . '</td>' . "\n";
 echo '<td>' . $_POST['debit' . $row] . '</td>' . "\n";
 } elseif (isset($_POST['accountHeading1' . $row])) {
 echo '<td>' . $_POST['accountHeading1' . $row] . '</td>' . "\n";
 echo '<td> </td>' . "\n";
 } elseif (isset($_POST['debit' . $row])) {
 echo '<td> </td>' . "\n";
 echo '<td>' . $_POST['debit' . $row] . '</td>' . "\n";
 } else {
 echo '<td> </td><td> </td>' . "\n";
 }
 if (isset($_POST['accountHeading2' . $row]) && isset($_POST['credit' . $row])) {
 $sqlStr2b = $_POST['accountHeading2' . $row] . "'," . $_POST['credit' . $row];
 if ($sqlStr2b != "',") {
 $sqlStr2 .= "(" . $i . ",2,'" . $sqlStr2b . '),';
 }
 echo '<td>' . $_POST['accountHeading2' . $row] . '</td>' . "\n";
 echo '<td>' . $_POST['credit' . $row] . '</td>' . "\n";
 } elseif (isset($_POST['accountHeading2' . $row])) {
 echo '<td>' . $_POST['accountHeading2' . $row] . '</td>' . "\n";
 echo '<td> </td>' . "\n";
 } elseif (isset($_POST['credit' . $row])) {
 echo '<td> </td>' . "\n";
 echo '<td>' . $_POST['credit' . $row] . '</td>' . "\n";
 } else {
 echo '<td> </td><td> </td>' . "\n";
 }
 echo '</tr>' . "\n";
 }
 $_SESSION['sqlStr1'] = $sqlStr1;
 $_SESSION['sqlStr2'] = preg_replace('/,$/', '', $sqlStr2);
?>
 </tbody>
 </table>
 <input type="submit" value="上記を書き込み"/>
 </form>
</body>
</html>

c.php

<?php
// データ受け取り
 session_start();
?>
<html>
<head>
 <title>データベース書き込みと結果表示フォーム</title>
</head>
<body>
<pre>
 <?php
 // 確認用にSQLを画面出力
 echo "\n";
 echo preg_replace("/\)/", ")\n", $_SESSION['sqlStr1']) . "\n";
 echo preg_replace("/\)/", ")\n", $_SESSION['sqlStr2']) . "\n";
 //
 // ********** ここから下は動作未確認 **********
 //
 // エラー出力用変数準備
 $err = '';
 // MySQL接続 開く
 if (!$con = mysql_connect("ここにはデータベース接続文字列を入れる")) {
 $err .= 'データベース接続失敗';
 } else {
 if (!(mysql_select_db("ここにデータベース名を入れる"))) {
 $err .= 'データベースオープンに失敗';
 }
 // 伝票見出テーブルへの書き込み
 if ($err != '') { // 既にエラーがあった場合はこの処理は飛ばす。
 } elseif (!$result = mysql_query($_SESSION['sqlStr1'])) {
 $err .= '伝票見出テーブルへの書き込みで失敗';
 }
 // 書き込んだ際に自動的に生成された伝票番号を取得
 if ($err != '') { // 既にエラーがあった場合はこの処理は飛ばす。
 } elseif(!$number = mysql_insert_id()) {
 $err .= '伝票番号取得失敗';
 }
 // 伝票詳細テーブルへの書き込み
 if ($err != '') { // 既にエラーがあった場合はこの処理は飛ばす。
 } elseif (!$result = mysql_query(mpeg_replace('/(,/', "($number,", $_SESSION['sqlStr2']))) {
 $err .= '伝票詳細テーブルへの書き込みで失敗';
 }
 //
 // MySQL接続 閉じる
 mysql_close($con);
 }
 //
 // ********** ここから上は動作未確認 **********
 //
 // セッション破棄
 session_destroy();
 // 結果報告
 echo ($err != '' ? $err : '書き込み作業完了');
 ?>
</pre>
</body>
</html>

(5)この先の展望をどのようにお考えか判りませんが、

まずは上記にてMySQLに正しく書き込まれるかの確認。

MySQL管理ツールをお使いかどうか判りませんが phpMyAdminなどで確認なさると良いでしょう。

それが済んでからSQLインジェクション対策を学んで施してください。

機能の追加は、それから先の話になりますが、

・伝票見出テーブルからタイトルの一覧を表示するphpプログラムの作成とテスト

・上記一覧で選択した伝票の詳細を表示するphpプログラムの作成とテスト

・詳細を訂正登録する機能の追加とテスト

といったような具合で徐々に機能を増やしていかれると良いでしょう。

・仕訳項目の自動表示

などは設計段階から組み込んでおくべきことなのですが、そうなると基本設計からして、

かなり込み入ってきますので、現状では夢のようなものです。


※php+MySQL習得用の習作だとすれば、難易度が高すぎるような気がします。

掲示板等の比較的簡単なものからはじめるほうがよろしいかもしれません。

※本格的利用が目的であるならばAccess等のクライアント向けアプリのほうが、

桁違いに敷居は低く、お勧めしたいですし、予算が許せば専用のソフトを買うほうが、

時間というコストの節約になると思います。


一式そろったものがあれば、それをそのまま使うほうが楽なのだけど・・・

適していそうなものが見つからないから学習用に作ってみたというのが今回の回答。

あまりフォローする時間も取れないので、他に、適した回答があれば、

この回答は無視で結構です。


何はともあれ、じっくり腰をすえてがんばってください。

◎質問者からの返答

kn1967様 お世話になっております。

返信有難うございます。

わかりやすく丁寧なコード解説でとても参考になります。

掲示板やブログは使わないので、どうせやるなら少しでも利用できるものを作ったほうがやる気もわくんじゃないかと思ったのですが、仰るとおり敷居が高いですよね・・。

仕訳を入力していって、集計してから決算書くらい出せればいいかなとふんわり考えてはいますが・・。

コピペじゃなく打ち込んでみたいので少し時間がかかりそうですが、これからじっくりやってみようと思います。

とりいそぎお礼まで。

関係ないですが、km1967さんと勘違いしてました^^;

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ