次回から明細を作成しますが、その前に伝票に明細を組み込みやすくするため、画面とプログラムを改良します。
伝票と明細は似たようなプログラムで動くので、フォーム上の部品や関数名に、伝票には「Slip」、明細には「Details」と付けることで区別します。
【1】以下のように slip.htmlとslip.js を更新します。slip.css、base.css、database.js は前回までと同じです。
slip.html
<html>
<head>
<script type="text/javascript" src="database.js"></script>
<script type="text/javascript" src="slip.js"></script>
<link href="base.css" rel="stylesheet" type="text/css">
<link href="slip.css" rel="stylesheet" type="text/css">
<title>slip</title>
</head>
<body>
販売伝票
<span id="slipDisplay"></span><a href="" name="linkNewSlip" id="linkNewSlip">伝票新規</a>
<form name="form1">
<p>
<input type="button" name="btnInsertSlip" id="btnInsertSlip" value="伝票追加">
<input type="button" name="btnUpdateSlip" id="btnUpdateSlip" value="伝票更新">
<input type="button" name="btnDeleteSlip" id="btnDeleteSlip" value="伝票削除">
</p>
SLIP_CD:<input type="text" name="txtSlipCd" id="txtSlipCd">
SLIP_DATE:<input type="text" name="txtSlipDate" id="txtSlipDate">
CST_CD:<span id="customerDisplay"></span>
</form>
<span id="addressDisplay"></span>
<br />
<br />
<br />
<br />
<br />
<div id="sqlDisplay"></div>
</body>
</html>
slip.js
var txtSlipCd;
var txtSlipDate;
var selectCst;
onload = init;
onunload = dbClose;
function init() {
//初期設定をする関数
txtSlipCd = document.getElementById("txtSlipCd");
txtSlipDate = document.getElementById("txtSlipDate");
txtSlipCd.onfocus = function (){focus(this);}
txtSlipCd.onblur = function (){blur(this);}
txtSlipDate.onfocus = function (){focus(this);}
txtSlipDate.onblur = function (){blur(this);}
document.getElementById("btnInsertSlip").onclick = function (){dataInsertSlip();}
document.getElementById("btnUpdateSlip").onclick = function (){dataUpdateSlip();}
document.getElementById("btnDeleteSlip").onclick = function (){dataDeleteSlip();}
document.getElementById("linkNewSlip").onclick = function (){return newSlip();}
dbConnect();
slipDisplay();
cstDisplay();
}
function focus(obj){
obj.style.backgroundColor = "#ffff00";
}
function blur(obj){
obj.style.backgroundColor = "#ffffff";
}
function slipDisplay() {
//伝票を表示する関数
var mySql = "select SLIP_CD,SLIP_DATE from T07Slip order by SLIP_CD";
var recordSet = database.Execute(mySql);
document.getElementById("slipDisplay").innerHTML = "";
var tempHtml = "<select name=\"selectSlip\" id=\"selectSlip\">\n";
tempHtml = tempHtml + "\t<option value=\"0\">選択してください。</option>\n";
while (!recordSet.EOF){
tempHtml = tempHtml + "\t<option value=\"" + recordSet(0) + "\">" + "伝票番号" + recordSet(0) + " 日付" + dateFormat(recordSet(1)) + "</option>\n";
recordSet.MoveNext();
}
tempHtml = tempHtml + "</select>";
//alert(tempHtml);
document.getElementById("slipDisplay").innerHTML = tempHtml;
document.getElementById("selectSlip").onchange = function (){slipChange(this);}
recordSet.Close();
recordSet = null;
}
function slipChange(obj) {
//伝票を選択した時の関数
if(obj.selectedIndex==0){
textClearSlip();
cstDisplay();
document.getElementById("addressDisplay").innerHTML = "";
document.getElementById("sqlDisplay").innerHTML = "";
alert("伝票を選択してください。");
}else{
var mySql = "select SLIP_CD,SLIP_DATE,T07Slip.CST_CD,TOWN_CD,ADDRESS ";
mySql = mySql +"from T07Slip,T04Customer ";
mySql = mySql +"where T07Slip.CST_CD = T04Customer.CST_CD ";
mySql = mySql +"and SLIP_CD = " + obj.value ;
var recordSet = database.Execute(mySql);
txtSlipCd.value = recordSet(0);
txtSlipDate.value = dateFormat(recordSet(1));
selectCst.selectedIndex = cstIndexSearch(recordSet(2));
document.getElementById("addressDisplay").innerHTML = addressRefer(recordSet(3),database) + recordSet(4);
recordSet.Close();
recordSet = null;
sqlDisplay("selectedIndex:" + obj.selectedIndex + " value:" + obj.value);
}
}
function cstDisplay() {
//顧客を表示する関数
var mySql = "select CST_CD,CST_NAME from T04Customer order by CST_CD";
var recordSet = database.Execute(mySql);
document.getElementById("customerDisplay").innerHTML = "";
var tempHtml = "<select name=\"selectCst\" id=\"selectCst\">\n";
tempHtml = tempHtml + "\t<option value=\"0\">選択してください。</option>\n";
while (!recordSet.EOF){
tempHtml = tempHtml + "\t<option value=\"" + recordSet(0) + "\">" + recordSet(1) + "</option>\n";
recordSet.MoveNext();
}
tempHtml = tempHtml + "</select>";
//alert(tempHtml);
document.getElementById("customerDisplay").innerHTML = tempHtml;
selectCst = document.getElementById("selectCst");
selectCst.onchange = function (){cstChange(this);}
recordSet.Close();
recordSet = null;
}
function cstChange(obj) {
//顧客を選択した時の関数
if(obj.selectedIndex==0){
document.getElementById("addressDisplay").innerHTML = "";
document.getElementById("sqlDisplay").innerHTML = "";
alert("顧客を選択してください。");
}else{
var mySql = "select TOWN_CD,ADDRESS from T04Customer where CST_CD = " + obj.value ;
var recordSet = database.Execute(mySql);
document.getElementById("addressDisplay").innerHTML = addressRefer(recordSet(0),database) + recordSet(1);
recordSet.Close();
recordSet = null;
sqlDisplay("selectedIndex:" + obj.selectedIndex + " value:" + obj.value);
}
}
function sqlDisplay(_mySql) {
//SQLを表示する関数
document.getElementById("sqlDisplay").innerHTML = "<p>" + _mySql + "</p>";
}
function newSlip(){
//伝票を新規作成する関数
textClearSlip();
document.getElementById("addressDisplay").innerHTML = "";
document.getElementById("sqlDisplay").innerHTML = "";
slipDisplay();
cstDisplay();
txtSlipCd.value = maxCdSlip() + 1;
txtSlipDate.focus();
return false;
}
function maxCdSlip(){
//SLIP_CDの最大値を取得する関数
var mySql = "select max(SLIP_CD) from T07Slip";
var recordSet = database.Execute(mySql);
var maxCd = recordSet(0);
return maxCd;
}
function textClearSlip() {
//テキストボックスをクリアする関数
txtSlipCd.value = "";
txtSlipDate.value = "";
}
function dataInsertSlip() {
//データを追加する関数
try{
if(dataCheckSlip(1)){
var mySql = "insert into T07Slip values(" ;
mySql = mySql + Number(txtSlipCd.value) + ", '";
mySql = mySql + txtSlipDate.value + "', ";
mySql = mySql + Number(selectCst.value);
mySql = mySql +")";
sqlDisplay(mySql);
database.Execute(mySql);
slipDisplay();
alert("追加しました。");
}
}catch(error){
alert(error.number + "\n" + error.description);
}
}
function dataUpdateSlip() {
//データを更新する関数
if(dataCheckSlip(1)){
var mySql = "update T07Slip set ";
mySql = mySql + "SLIP_DATE = '" + txtSlipDate.value + "', ";
mySql = mySql + "CST_CD = " + Number(selectCst.value);
mySql = mySql + " where SLIP_CD = " + Number(txtSlipCd.value);
sqlDisplay(mySql);
database.Execute(mySql);
slipDisplay();
alert("更新しました。");
}
}
function dataDeleteSlip() {
//データを削除する関数
if(!confirm("本当に削除しますか?")){
return ;
}
if(dataCheckSlip(0)){
var mySql = "delete from T07Slip where SLIP_CD = " + Number(txtSlipCd.value);
sqlDisplay(mySql);
database.Execute(mySql);
textClearSlip();
document.getElementById("addressDisplay").innerHTML = "";
slipDisplay();
cstDisplay();
alert("削除しました。");
}
}
function dataCheckSlip(flag){
//データをチェックする関数
var tempStr = "は必ず入力してください。";
if (txtSlipCd.value == "") {
alert("SLIP_CD" + tempStr);
return false;
}
if (txtSlipCd.value.match(/[^0-9]/)) {
alert("SLIP_CDには半角数字を入力してください!");
txtSlipCd.focus();
return false;
}
if (flag == 1 && txtSlipDate.value == "") {
alert("SLIP_DATE" + tempStr);
return false;
}
if (flag == 1 && !txtSlipDate.value.match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) {
alert("SLIP_DATEは「yyyy/mm/dd」形式で入力してください!");
return false;
}
if (flag == 1 && selectCst.value == 0) {
alert("CST_CD" + "は必ず選択してください。");
return false;
}
return true;
}
function cstIndexSearch(cstCd){
//顧客選択ボックスのIndexを検索する関数
var mySql = "select count(CST_CD) from (select CST_CD from T04Customer where CST_CD <= " + cstCd + " order by CST_CD)";
var recordSet = database.Execute(mySql);
var cstIndex = recordSet(0);
return cstIndex;
}
【2】保存したら slip.html をダブルクリックしてWebブラウザで開きます。
★slip.html、base.css、slip.css、database.js、slip.js は必ず同じフォルダ内に置いてください。
【3】前回までと動きは変わらないことを確認してください。
*「最大値」が「伝票新規」に変わりましたが働きは同じです。
【解説】
(1)大きな変更点はフォーム上の部品や関数名に「Slip」を付けたことです。
・html側
btnInsert → btnInsertSlip
btnUpdate → btnUpdateSlip
btnDelete → btnDeleteSlip
linkMaxCd → linkNewSlip
・JavaScript側
maxCd() → newSlip()とmaxCdSlip()に分離
textClear() → textClearSlip()
dataInsert() → textClearSlip()
dataUpdate() → dataUpdateSlip()
dataDelete() → dataDeleteSlip()
dataCheck() → dataCheckSlip()
(2)「最大値」を「伝票新規」に変えたことで関数も2つに分離しました。前回までの関数maxCd()はnewSlip()にあたり、この関数からmaxCdSlip()を呼び出して最大値を取得しています。分離したことでそれぞれの関数がシンプルになり、maxCdSlip()は他の用途にも使いやすくなりました。
function newSlip(){
省略
txtSlipCd.value = maxCdSlip() + 1;
省略
}
function maxCdSlip(){
省略
return maxCd;
}
(3)「div」を「span」に変更しました。<span> や <div> は特に意味を持たないタグです。タグで囲んだ部分にスタイルシートを適用したりするのに使われます。<span> はインライン要素で前後に改行は入りません。<div> はブロック要素で前後に改行が入ります。今回は配置するときに改行が邪魔だったので、<span> を使いました。
<div id="slipDisplay"></div>
↓
<span id="slipDisplay"></span>
<div id="customerDisplay"></div>
↓
<span id="customerDisplay"></span>
(4)sqlDisplayを下に配置しました。sqlDisplayはSQL文や選択ボックスの情報を表示するときに使っていますが、システムが完成して不要になったら、関数sqlDisplay()を呼び出している部分をコメントにすると表示されなくなります。
例
//sqlDisplay(mySql);
//sqlDisplay("selectedIndex:" + obj.selectedIndex + " value:" + obj.value);
【伝票のダウンロード】
今回までの改良を含むSlipです。
database.jsとbase.cssは他のマスターと共通です。
slip1.zip
データベースをまだ入手していない方は一緒にダウンロードしてください。
SampleDB010.zip
データベース「SampleDB010.mdb」はCドライブの直下に保存します。