LAPP/LAMP の基本 (SQL + cgi)
放送大学 岡部 洋一
2013 年 12 月 9 日

会計ソフトなどの OA ソフト、名簿管理ソフト、E-Learning など、ありとあらゆる大量のデータを扱うソフトウェアは、現在、データベースソフトの手前に Web などのユーザインターフェースを用意するのが標準的手法となっている。特に、最近は LAMP (Linux + Apache + MySQL + PHP or

Perl)、LAPP (Linux + Apache + PostgreSQL + PHP or Perl) と呼ばれる無償ソフトを使ったものが極めてよく使われる。言うまでもなく、Linux をOS とし、そこに Web として Apache を、MySQL または PostgreSQL を
データベースソフトとして載せ、さらに、Web cgi-bin して PHP または Perlを使う。
ここでは、FreeBSD + Apache + PostgreSQL + Perl を用いて、複式簿記用のデータベース balance を実現した結果を示す。Linux の場合についても述べる。
起草: 2003 年 2 月 4 日

1

目次
0.1
0.2

PostgreSQL の設定 . . . . . . . . . . . . . . . . . . . . . . . .
PostgreSQL の通信設定 . . . . . . . . . . . . . . . . . . . . .

2
5

0.3
0.4

ODBC の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . .
Perl による cgi-bin の作成 . . . . . . . . . . . . . . . . . . . .

5
6

0.5

上記データベースから仕訳帳や決算報告などを見るユーザー
インタフェース: show.pl . . . . . . . . . . . . . . . . . . . . .

0.6

0.1

7
上記データベースに追加/修正/削除を行なうプログラム: input.pl 16

PostgreSQL の設定• /sbin/sysinstall で postgresql, p5 Pg をインストールする。tcl/tk を使うなら postgresql-tcltk も入れる。
• pgsql (Linux ならば postgres) という user が出来ているので、vipw とpasswd でパスワードを設定する。
• su -l pgsql (Linux ならば postgres)として login する。setenv で自分の $HOME を確認しておくとよい。

• % mkdir dataとし、% initdb を実行。

% pg ctl start
で postgreSQL を起動。終了は% pg ctl stop。
• % createuser okabe
okabe には、database 作成権と user 管理権を付ける。削除はdropuser ...
以後は自分の ID で login できる。
• > createdb balance
でデータベースを作成。削除はdropdb ...

2• > psql balanceで db に入る (psql -l で query)。

• =# create table titles (key char(2), title text, type char(2));
で勘定科目テーブル作成。key は科目コード、title は科目、type は実
在/名目 (r/i)、左借方/右貸方 (d/c) の二文字。

=# create table i2003 (credit char(2), amount int, debit char(2), remarks text);
で期首貸借対照表を作成。credit と debit は科目コード=# create table f2003 (credit char(2), amount int, debit char(2), cashchar, date date, remarks text);
で仕訳帳を作成。
credit と debit は科目コード、cash は左右のいずれかに現金、普通預金があるかないかでキャッシュ/非キャッシュ取引 (c/n)。
予定通り動かないときとか、応答がないときは 最後の ; を忘れていな
いか疑う。

• => insert into i2003 values (10,52000,10,);などでデータを入れてもよいが、多量の場合には TAB 区切のファイルを作って、=> copy i2003 from ’/usr/home/okabe/i2003.txt’などでまとめて入れる方が早い。逆はcopy i2003 to ...;• アクセス権の設定=> grant all on i1997,f1997,. . . to okabe;
逆はrevoke ... on ... from ...;• select の使い方に習熟するのがよい。
select field[,...] from table [where 条件];が基本形。

select field[,...] from (select ...) table alias 名;
によって from の後に別の select で作った出力テーブルを入れ、多重に定義することができる。

select sum(amount) as c sum from ... group by credit;などによって、科目ごとの金額の合計などができる。c sum は別名で、この結果を上位の select で使うときに、field 名として使える。

3• テーブルの結合を覚える。
select table1 from table2 union;
で、同じ形のテーブルのレコードを縦に積上げる。
select table1 full outer join table2 using(key);
で、key をキーとして横に繋げる。同じ amount などがあっても、別のフィールドとする。したがって同じ名前のフィールドには別名を付けると後の処理がしやすい。

• select table1 join titles using(key);
によって、科目コードを科目そのものに置き換えることができる。
例えば、残高試算表の作成は、# 科目コードを科目に変更
select * from (# 科目ごとに左借方と右貸方の合計を並べる
select * from (# 左借方の科目別合計
select debit as key,sum(amount) as d_sum from (# 期首とselect debit,amount from $tbl_i union# 期中を組み合わせる
select debit,amount from $tbl_f) d group by debit) ds full outer join (# 右貸方の科目別合計
select credit as key,sum(amount) as c_sum from (# 期首とselect credit,amount from $tbl_i union# 期中を組み合わせる
select credit,amount from $tbl_f) c group by credit) cs using(key))t join titles using(key);• database のバックアップは
pg dump > tempで行なう。temp は psql の script file になっているので、復元は% dropdb balance
を実行後、

4

psql -e balance < tempでできる。この手法に習熟したら、temp のような script file を直接作成し、データベースを一挙に立ち上げることも可能となる。これが最も楽な方法である。

0.2

PostgreSQL の通信設定• /data にある pg hba.conf を編集する。最後の行の付近にすべてを記述する。例えば以下のようにする。crypt は、暗号化パスワードを使用
する
local all trust
host all 127.0.0.1 255.255.255.255 crypt
host balance 公開したい IP 255.255.255.192 crypt• % pg ctl -o ”-i” restart(pg ctl stop; postmaster -i & と同じ意味) で起動。-i は IP access を可能にする• telnet localhost postgresql (または 5432)が通れば、postmaster は正常動作• psql の中で
alter user okabe with password ”xxx”;
で password を設定する• psql -h localhost balance
が通れば、ここの設定はすべて OK• 外部の client から
psql -h server name balance
が通るはず

0.3

ODBC の設定• 現在の ODBC では、host の pg hba.conf が crypt に設定されているとうまく動かない。password か trust でないと駄目。ネットワークにパスワードを流したくない場合には local の計算機でアクセスするしかない。

• /stand/sysinstall で postgresql-odbc をインストールする5• postmaster の再起動
• Google で ”odbc postgreSQL windows” (日本語) で ODBC driver を
download する。書かれた設定にしたがって、windows にインストール
する• XL の場合、「コントロールパネル/パーフォーマンスとメンテナンス/
管理ツール/データソース (ODBC)/システム DSN」で PostgreSQL を選ぶ。データソースで ReadOnly をクリック• Excel を起動し、「データ/外部データの取り込み/新しいデータベースのクエリ」でアクセスできれば正解• Access を起動し、何らかのファイルを新規作成し、そこで「ファイル/外部データの取り込み/テーブルのリンク/」でファイルの種類で ODBCを選択。コンピュータデータソースで PostgreSQL を選ぶ

0.4

Perl による cgi-bin の作成• % createuser www (cgi によるアクセス用)。www には database 作成
権も user 管理権も付けない。

• =¿ grant select,insert,update,delete on i2003,f2003 to www;• perl で Web 画面を出す部分と、そこで選んだ条件で作業する部分を二つに分けるのが標準であるが、一つの cgi-bin にすることを試みた• 何かの param を利用して、仕事を分ける。例えば入力 cgi では、追加、変更、削除の言葉を name(’op’) に割り当て、前半では param(’op’) が存在すると、データベースとのやりとり処理を行なうようにした• プログラム作成に当っては、 param(’op’) があれば、処理をし、どのような画面を出すか、なければ、どのような画面を出す (処理はほとん
どない) かを考えながら行なえばよい

どのページへ行きたい:• 岡部のホームページ
岡部 洋一 / 放送大学

okabe(at)u-air. ac. jp

6上記データベースから仕訳帳や決算報告などを0.5

見るユーザーインタフェース: show.pl#! /usr/bin/perl -w
use CGI;use Pg;use CGI::Carp qw(fatalsToBrowser);use CGI qw/:standard/;
use strict;
my $db = ’balance’;# get key table
my ($tbl_i, $tbl_f, %titles, $qstr, $res, $n);
my $conn = Pg::connectdb("user=www dbname = $db");
if ($conn->status ne PGRES_CONNECTION_OK) {print "Cannot connect to database $db: $conn->errorMessage";
exit;}$tbl_i = ’titles’;$qstr = "select * from $tbl_i;";if (&submit_sql()) {for (my $i = 0; $i < $n; $i++) {my $key = $res->getvalue($i, 0);$titles{$key} = $res->getvalue($i, 1);}}
print header;
print start_html(-title=>"Settlement",-meta=>{’Content-Type’=>’text/html; charset=x-euc-jp’}),"\n";
print h2(’ 財務諸表’),"\n";# select year and output-sheet
my @years = (’1997’,’1998’,’1999’,’2000’,’2001’,’2002’,’2003’);
my $year;
my @sheets = (’ 仕訳帳’,’ 期首貸借対照表・フロー計算書’,’ 貸借対照表・損益計算書’);

7

my $sheet;print
start_form(),’ 年と表を選んでください ’,popup_menu(-name=>’year’,-values=>\@years,-defaults=>$years[$#years]),
popup_menu(-name=>’sheet’,-values=>\@sheets,-defaults=>$sheets[$#sheets]),
submit(’ 実行’),br(),end_form(),"\n";if (!($year = param(’year’))) {$year = $years[$#years];}$tbl_i = ’i’.$year;$tbl_f = ’f’.$year;
if (!($sheet = param(’sheet’))) {$sheet = $sheets[$#sheets];}my ($i, $amount, $debit, $credit, $profit);# print journal
if ($sheet eq ’ 仕訳帳’) {print h3(’ 仕訳帳’),"\n";print "<table border>\n";print "<tr><td colspan=3>&nbsp;</td><td colspan=4 align=center>仕訳帳</td><td>&nbsp</td></tr>\n";printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",’No.’,’ 年月日’,’ 摘要’,
’ 左借方’,’ 金額’,’ 右貸方’,’ 金額’,’cash’);$qstr = "select oid,* from $tbl_f;";if (&submit_sql()) {$debit = 0;
for ($i = 0; $i < $n; $i++) {$amount = $res->getvalue($i,2);$debit += $amount;
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td><td>%s</td></tr>\n",$res->getvalue($i,0),$res->getvalue($i,5),&chksp($res->getvalue($i,6)),&chksp($titles{$res->getvalue($i,1)}),$amount,&chksp($titles{$res->getvalue($i,3)}),$amount,8

$res->getvalue($i,4));}
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td><td>%s</td></tr>\n",’&nbsp;’,’&nbsp;’,’&nbsp;’,’【To】’,$debit,’【From】’,$debit,’&nbsp;’);}print "</table>\n";}#print flow statement (F/S)
if ($sheet eq ’ 期首貸借対照表・フロー計算書’) {print h3(’ 期首貸借対照表・フロー計算書’),"\n";print "<table border>\n";print "<tr><td></td><td colspan=4 align=center>期首貸借対照表</td><td></td></tr>\n";printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td><td>%s</td></tr>\n",’No.’,’ 左借方’,’ 金額’,’ 右貸方’,’ 金額’,’ 摘要’);$qstr =
"select oid,* from $tbl_i;";if (&submit_sql()) {my ($d_key, $c_key);$debit = 0;
for (my $i = 0; $i < $n; $i++) {$amount = $res->getvalue($i,2);$d_key = $res->getvalue($i,1);$c_key = $res->getvalue($i,3);
if ($d_key !~ /^0/ && $amount) {printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td><td>%s</td>\n",$res->getvalue($i,0),$titles{$d_key},$amount,’&nbsp;’,’&nbsp;’,&chksp($res->getvalue($i,4)));$debit += $amount;}
if ($c_key !~ /^0/ && $amount) {printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td><td>%s</td>\n",9$res->getvalue($i,0),’&nbsp;’,’&nbsp;’,$titles{$c_key},$amount,&chksp($res->getvalue($i,4)));$credit += $amount;}}
if ($debit != $credit) {print "<p>Unbalanced!</p>\n";}$profit = $debit - $credit;
if ($profit) {$credit += $profit;
printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’&nbsp;’,’&nbsp;’,’*当期利益’,&chksp($profit));}if ($debit != $credit) {print "<p>Unbalanced!</p>\n";}printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td><td>%s</td></tr>\n",’&nbsp;’,’【資産】’,$debit,’【負債資本】’,$debit,’&nbsp;’);}print "<tr><td></td></tr>\n";print "<tr><td></td><td colspan=4 align=center>キャッシュフロー (cash)</td></tr>\n";printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’ 左借方’,’ 金額’,’ 右貸方’,’ 金額’);$qstr =
"select * from (select * from (select debit as key, sum(amount) as dsum from (select * from $tbl_f where cash != ’n’)dc group by debit)d full outer join (select credit as key, sum(amount) as csum from (select * from $tbl_f where cash != ’n’)cc group by credit)c using(key))t join titles using(key);";if (&submit_sql()) {$debit = $credit = 0;10

for ($i = 0; $i < $n; $i++) {if ($res->getvalue($i,4) eq ’rd’) {$amount = $res->getvalue($i,1)-$res->getvalue($i,2);
if ($amount) {$debit += $amount;
printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td>%s</td></tr>\n",’’,$res->getvalue($i,3),&chksp($amount),’&nbsp;’,’&nbsp;’);}} elsif ($res->getvalue($i,4) eq ’rc’) {$amount = $res->getvalue($i,2)-$res->getvalue($i,1);
if ($amount) {$credit += $amount;
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’&nbsp;’,’&nbsp;’,$res->getvalue($i,3),&chksp($amount));}} elsif ($res->getvalue($i,4) eq ’ic’) {$amount = $res->getvalue($i,2)-$res->getvalue($i,1);
if ($amount) {$credit += $amount;
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’&nbsp;’,’&nbsp;’,$res->getvalue($i,3),&chksp($amount));}} elsif ($res->getvalue($i,4) eq ’id’) {$amount = $res->getvalue($i,1)-$res->getvalue($i,2);
if ($amount) {$debit += $amount;
printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td>%s</td></tr>\n",’’,$res->getvalue($i,3),&chksp($amount),’&nbsp;’,’&nbsp;’);
}
}
}

11

if ($debit != $credit) {print "<p>Unbalanced!</p>\n";}printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’【To】’,&chksp($debit),’【From】’,&chksp($credit));}print "<tr></tr>\n";print "<tr><td></td><td colspan=4 align=center>非キャッシュフロー (non-cash)</td></tr>\n";printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’ 左借方’,’ 金額’,’ 右貸方’,’ 金額’);$qstr =
"select * from (select * from (select debit as key, sum(amount) as dsum from (select * from $tbl_f where cash = ’n’)dc group by debit)d full outer join (select credit as key, sum(amount) as csum from (select * from $tbl_f where cash = ’n’)cc group by credit)c using(key))t join titles using(key);";if (&submit_sql()) {$debit = $credit = 0;
for ($i = 0; $i < $n; $i++) {if ($res->getvalue($i,4) eq ’rd’) {$amount = $res->getvalue($i,1)-$res->getvalue($i,2);
if ($amount) {$debit += $amount;
printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td>%s</td></tr>\n",’’,$res->getvalue($i,3),&chksp($amount),’&nbsp;’,’&nbsp;’);}} elsif ($res->getvalue($i,4) eq ’rc’) {$amount = $res->getvalue($i,2)-$res->getvalue($i,1);
if ($amount) {$credit += $amount;12

printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’&nbsp;’,’&nbsp;’,$res->getvalue($i,3),&chksp($amount));}} elsif ($res->getvalue($i,4) eq ’ic’) {$amount = $res->getvalue($i,2)-$res->getvalue($i,1);
if ($amount) {$credit += $amount;
printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’&nbsp;’,’&nbsp;’,$res->getvalue($i,3),&chksp($amount));}} elsif ($res->getvalue($i,4) eq ’id’) {$amount = $res->getvalue($i,1)-$res->getvalue($i,2);
if ($amount) {$debit += $amount;
printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td>%s</td></tr>\n",’’,$res->getvalue($i,3),&chksp($amount),’&nbsp;’,’&nbsp;’);}}}printf("<tr><td>%s</td><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’’,’【To】’,&chksp($debit),’【From】’,&chksp($credit));if ($debit != $credit) {print "<p>Unbalanced!</p>\n";}}print "</table>\n";}# print B/S and P/L
if ($sheet eq ’ 貸借対照表・損益計算書’) {print h3(’ 貸借対照表・損益計算書’),"\n";print "<table border>\n";$qstr =
"select * from (13select * from (select debit as key,sum(amount) as d_sum from (select debit,amount from $tbl_i union all
select debit,amount from $tbl_f) d group by debit) ds full outer join (select credit as key,sum(amount) as c_sum from (select credit,amount from $tbl_i union all
select credit,amount from $tbl_f) c group by credit) cs using(key))t join titles using(key);";if (&submit_sql()) {print "<tr><td colspan=4 align=center>貸借対照表</td></tr>\n";printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",’ 左借方’,’ 金額’,’ 右貸方’,’ 金額’);$debit = $credit = 0;
for ($i = 0; $i < $n; $i++) {if ($res->getvalue($i,4) eq ’rd’) {$amount = $res->getvalue($i,1)-$res->getvalue($i,2);
if ($amount) {$debit += $amount;
printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",$res->getvalue($i,3),&chksp($amount),’&nbsp;’,’&nbsp;’);}} elsif ($res->getvalue($i,4) eq ’rc’) {$amount = $res->getvalue($i,2)-$res->getvalue($i,1);
if ($amount) {$credit += $amount;
printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’&nbsp;’,’&nbsp;’,$res->getvalue($i,3),&chksp($amount));}}}$profit = $debit - $credit;14if ($profit) {$credit += $profit;
printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’&nbsp;’,’&nbsp;’,’*当期利益’,&chksp($profit));}printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’【資産】’,$debit,’【負債資本】’,$credit);
if ($debit != $credit) {print "<p>Unbalanced!</p>\n";}print "<tr></tr>";print "<tr><td colspan=4 align=center>損益計算書</td></tr>\n";printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",’ 左借方’,’ 金額’,’ 右貸方’,’ 金額’);$debit = $credit = 0;
for ($i = 0; $i < $n; $i++) {if ($res->getvalue($i,4) eq ’ic’) {$amount = $res->getvalue($i,2)-$res->getvalue($i,1);
if ($amount) {$credit += $amount;
printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’&nbsp;’,’&nbsp;’,$res->getvalue($i,3),&chksp($amount));}} elsif ($res->getvalue($i,4) eq ’id’) {$amount = $res->getvalue($i,1)-$res->getvalue($i,2);
if ($amount) {$debit += $amount;
printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",$res->getvalue($i,3),&chksp($amount),’&nbsp;’,’&nbsp;’);}}}$profit = $credit - $debit;
if ($profit) {$debit += $profit;

15

printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’*!当期利益’,$profit,’&nbsp;’,’&nbsp;’);}printf("<tr><td>%s</td><td align=right>%s</td><td>%s</td><td align=right>%s</td></tr>\n",’【費用】’,&chksp($debit),’【収益】’,&chksp($credit));if ($debit != $credit) {print "<p>Unbalanced!</p>\n";}}print "</table>\n";}print end_html;
sub submit_sql {$res = $conn->exec($qstr);
if ($res->resultStatus ne PGRES_TUPLES_OK) {print "Query failed: $conn->errorMessage\n";return 0;}$n = $res->ntuples;if ($n == 0) {print ’<p>No record in DB</p>’,"\n";return 0;}
return 1;}
sub chksp {if ($_[0] eq ’’) {return ’&nbsp;’;}return $_[0];}0.6上記データベースに追加/修正/削除を行なうプ
ログラム: input.pl#! /usr/bin/perl -w
use CGI;use Pg;use CGI::Carp qw(fatalsToBrowser);16

use CGI qw/:standard/;
use strict;
my $db = ’balance’;my $conn = Pg::connectdb("dbname = $db");
if ($conn->status ne PGRES_CONNECTION_OK) {print "Cannot connect to database $db: $conn->errorMessage";exit;}
my ($res, $n, $qstr);
print header, start_html(-title=>’Input for Journal’,-meta=>{’Content-Type’=>’text/html; charset=x-euc-jp’}),"\n";
print h2(’ 仕訳帳: 入力/修正/削除’),"\n";# get key table from DB: titles
my ($key, $title, $type, $tbl);
my (%keys, %titles, @d_titles, @c_titles);$tbl = ’titles’;$qstr = "select * from $tbl;";&submit_sql;
for (my $i = 1; $i < $n; $i++) {$key = $res->getvalue($i, 0);$title = $res->getvalue($i, 1);$type = $res->getvalue($i, 2);$titles{$key} = $title;$keys{$title} = $key;
if ($type =~ /^r/ || $type eq ’id’) {@d_titles = (@d_titles, $title);}
if ($type =~ /^r/ || $type eq ’ic’) {@c_titles = (@c_titles, $title);}}my ($err_i, $err_u, $err_d);# process after accepting param’s17my ($op, $year);my ($oid, $debit, $amount, $credit, $cash, $date, $remarks);
if (param(’op’)) {$op = param(’op’);$year = param(’year’);$tbl = ’f’.$year;# insert
if ($op eq ’ 追加’) {$debit = $keys{param(’d_title’)};$amount = param(’amount’);$credit = $keys{param(’c_title’)};if ($debit =~ /^[12]/ || $credit =~ /^[12]/) {$cash = ’c’;}else {$cash = ’n’;}$date = param(’date’);$remarks = param(’remarks’);if ($date && $amount) {$err_i = ’’;$qstr = "insert into $tbl values(’$debit’,’$amount’,’$credit’,’$cash’,’$date’,’$remar&submit_sql;} else {$err_i = ’ 再入力’;}}# update
elsif ($op eq ’ 変更’) {$oid = param(’oid’);$debit = $keys{param(’d_title’)};$amount = param(’amount’);$credit = $keys{param(’c_title’)};if ($debit =~ /^[12]/ || $credit =~ /^[12]/) {$cash = ’c’;}else {$cash = ’n’;}$date = param(’date’);$remarks = param(’remarks’);$qstr = "select oid from $tbl where oid=$oid;";&submit_sql;
if ($n > 0 && $date && $amount) {$err_u = ’’;$qstr = "update $tbl set debit=’\$debit’, amount=’\$amount’,credit=’$credit’,cash=’$c&submit_sql;

18} else {$err_u = ’ 再入力’;}}# delete
elsif ($op eq ’ 削除’) {$oid = param(’oid’);$qstr = "select oid from $tbl where oid=$oid;";&submit_sql;
if ($res->ntuples > 0) {$err_d = ’’;$qstr = "delete from $tbl where oid=$oid;";&submit_sql;} else {$err_d = ’ 再入力’;}}}# process making param’s
my @years = (’1997’,’1998’,’2003’);print
start_form(),p(’ 年を選んでください’,
popup_menu(-name=>’year’, -values=>\@years, -defaults=>$years[$#years])),hr, "\n",h4(’ 新規データ (年月日, 金額は必須)’),"\n",p(’ 年月日 (例 20030401) ’,textfield(-name=>’date’, -size=>8, -maxlength=>8),’’,’ 摘要 ’,textfield(’remarks’)),"\n",p(’ 左借方 (To) ’,popup_menu(-name=>’d_title’, -values=>\@d_titles),’’,’ 右貸方 (From) ’,popup_menu(-name=>’c_title’, -values=>\@c_titles),’’,’ 金額 ’,textfield(’amount’)), "\n",p(submit(-name=>’op’, -value=>’ 追加’), " $err_i"),hr, "\n",h4(’ 修正データ (No. は仕訳帳で確認. 年月日, 金額は必須)’), "\n",p(’No. ’,textfield(-name=>’oid’, -size=>5),’ ’,’ 年月日 (例 20030401) ’,textfield(-name=>’date’, -size=>8, -maxlength=>8),’19

’,’ 摘要 ’,textfield(’remarks’)), "\n",p(’ 左借方 (To) ’,popup_menu(-name=>’d_title’, -values=>\@d_titles),’’,’ 右貸方 (From) ’,popup_menu(-name=>’c_title’, -values=>\@c_titles),’’,’ 金額 ’,textfield(’amount’)), "\n",p(submit(-name=>’op’, -value=>’ 変更’), " $err_u"),hr, "\n",h4(’ 削除データ (No. は仕訳帳で確認)’), "\n",p(’No. ’,textfield(-name=>’oid’, -size=>5)), "\n",p(submit(-name=>’op’, -value=>’ 削除’), " $err_d"),hr, "\n",end_form, "\n",end_html, "\n";sub submit_sql() {$res = $conn->exec($qstr);$n = $res->ntuples;
print br(strong("実行されたコマンド [$qstr]
数 [$n]")), "\n";}20

対象レコード