販売伝票 顧客名表示

前回までの販売伝票ではCST_CDが数字だったため、顧客が誰なのかわかりにくいところがありました。

javascript-173.gif

そこで今回は顧客名を選択ボックスで表示したり、入力できるように工夫してみましょう。


【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>
    販売伝票
    <div id="slipDisplay"></div>
    <div id="sqlDisplay"></div>
    <form name="form1">
      <p>
        <input type="button" name="btnInsert" id="btnInsert" value="追加">
        <input type="button" name="btnUpdate" id="btnUpdate" value="更新">
        <input type="button" name="btnDelete" id="btnDelete" value="削除">
      </p>
      SLIP_CD:<input type="text" name="txtSlipCd" id="txtSlipCd">
      <a href="" name="linkMaxCd" id="linkMaxCd">最大値</a> 
      SLIP_DATE:<input type="text" name="txtSlipDate" id="txtSlipDate"><br />
      CST_CD:<div id="customerDisplay"></div>
    </form>
    <div id="addressDisplay"></div>
  </body>
</html>



slip.js

var slipCd;

var txtSlipCd;
var txtSlipDate;
var txtCstCd;

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("btnInsert").onclick = function (){dataInsert();}
  document.getElementById("btnUpdate").onclick = function (){dataUpdate();}
  document.getElementById("btnDelete").onclick = function (){dataDelete();}
  document.getElementById("linkMaxCd").onclick = function (){return maxCd();}

  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){
    textClear();
    cstDisplay();
    document.getElementById("addressDisplay").innerHTML = "";
    document.getElementById("sqlDisplay").innerHTML = "";
    alert("伝票を選択してください。");
  }else{
    slipCd = Number(obj.value);
    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));
    document.getElementById("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;
  selectCstCd = document.getElementById("selectCst");
  document.getElementById("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 maxCd(){
  //最大値を取得する関数
  var mySql = "select max(SLIP_CD) from T07Slip";
  var recordSet = database.Execute(mySql);
  textClear();
  document.getElementById("addressDisplay").innerHTML = "";
  document.getElementById("sqlDisplay").innerHTML = "";
  slipDisplay();
  cstDisplay();
  txtSlipCd.value = recordSet(0) + 1;
  txtSlipDate.focus();
  return false;
}


function textClear() {
  //テキストボックスをクリアする関数
  txtSlipCd.value = "";
  txtSlipDate.value = "";
}


function dataInsert() {
  //データを追加する関数
  try{
    if(dataCheck(1)){
      var mySql = "insert into T07Slip values(" ;
      mySql = mySql + Number(txtSlipCd.value) + ", '";
      mySql = mySql + txtSlipDate.value + "', ";
      mySql = mySql + Number(selectCstCd.value);
      mySql = mySql +")";

      sqlDisplay(mySql);
      database.Execute(mySql);
      slipDisplay();
      alert("追加しました。");

    }
  }catch(error){
    alert(error.number + "\n" + error.description);
  }
}


function dataUpdate() {
  //データを更新する関数
  if(dataCheck(1)){
    var mySql = "update T07Slip set ";
    mySql = mySql + "SLIP_DATE = '" + txtSlipDate.value + "', ";
    mySql = mySql + "CST_CD = " + Number(selectCstCd.value);
    mySql = mySql + " where SLIP_CD = " + Number(txtSlipCd.value);
    sqlDisplay(mySql);
    database.Execute(mySql);
    slipDisplay();
    alert("更新しました。");
  }
}


function dataDelete() {
  //データを削除する関数
  if(!confirm("本当に削除しますか?")){
    return ;
  }

  if(dataCheck(0)){
    var mySql = "delete from T07Slip where SLIP_CD = " + Number(txtSlipCd.value);
    sqlDisplay(mySql);
    database.Execute(mySql);
    textClear();
    document.getElementById("addressDisplay").innerHTML = "";
    slipDisplay();
    cstDisplay();
    alert("削除しました。");
  }
}


function dataCheck(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 && selectCstCd.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】販売伝票が表示されました。CST_CDが選択ボックスに変わっています。

javascript-174.gif

見やすいようにフォーム上の部品の位置は少し変えています。


【4】伝票選択ボックスから適当に選択してください。

javascript-175.gif


【5】顧客名が選択ボックスで表示されました。この時選択ボックスのvalueにはCST_CDが入っています。追加、更新、削除ではvalueの値が使われます。

javascript-176.gif


【6】顧客選択ボックスを適当に切り替えてください。

javascript-177.gif


【7】住所が変わることを確認してください。

javascript-178.gif


【8】顧客選択ボックスを使っても追加、更新、削除ができることを確認してください。


以上で選択ボックスを使って顧客名を表示することができました。


【解説】

(1)html側の変更
CST_CDをテキストボックスから選択ボックスに変えるため、プログラムで選択ボックスを出力する場所を「div」でマークしました。

CST_CD:<input type="text" name="txtCstCd" id="txtCstCd">

CST_CD:<div id="customerDisplay"></div>


(2)関数cstDisplay()について
顧客選択ボックスを作成して表示し、イベントハンドラの設定をしています。選択ボックスを切り替えたときには関数cstChange()が呼び出されます。thisは選択ボックス自身の参照です。

document.getElementById("selectCst").onchange = function (){cstChange(this);}


(3)関数cstChange()について
CST_CDをもとにテーブルT04CustomerからTOWN_CDとADDRESSを調べています。
var mySql = "select TOWN_CD,ADDRESS from T04Customer where CST_CD = " + obj.value ;

次に調べたTOWN_CDとADDRESSを使って、関数addressReferで住所を表示しています。
document.getElementById("addressDisplay").innerHTML = addressRefer(recordSet(0),database) + recordSet(1);

テーブルT07SlipにはCST_CDしかないため、住所を表示するにはこのような手順が必要です。


(4)関数slipChange()について
プログラムで作成した顧客選択ボックスに対して、どの顧客を選択した状態にするか指定しているところです。

document.getElementById("selectCst").selectedIndex = cstIndexSearch(recordSet(2));

選択ボックスのIndexは0からはじまりますが、0は「顧客を選択してください。」という文字を指定していますので、顧客は1からの連番になります。ここでのポイントは選択ボックスのvalue(CST_CD)とIndexが必ずしも一致しないことです。そのため今選択しているIndexを調べる関数cstIndexSearch()を作りました。


(5)関数cstIndexSearch()について
この関数はCST_CDをもとに、顧客選択ボックスで今選択しているIndexを調べて値を返します。

まず顧客選択ボックスを作成している関数cstDisplay()のSQL文を見ると、CST_CDの昇順になっています。つまり選択ボックスの表示順は必ずCST_CDの小さい順です。
var mySql = "select CST_CD,CST_NAME from T04Customer order by CST_CD";

ではCST_CDが「7」の場合を例に詳しく見ていきましょう。関数cstIndexSearch()のSQL文は少し複雑です。

var mySql = "select count(CST_CD) from (select CST_CD from T04Customer where CST_CD <= " + cstCd + " order by CST_CD)";

これまで from の後ろにはテーブル名を書いていましたが、以下のように別のSQL文を含めることができます。これをサブクエリー(副問い合わせ)といいます。

このような場合は分解して考えてみましょう。まずfromの後ろのSQLです。CST_CDが「7」の場合はこのようなSQL文になります。
select CST_CD from T04Customer where CST_CD <= 7 order by CST_CD

このSQLを実行した結果です。抽出条件の「7」が一番最後になっていることに注意してください。抽出条件は必ず最後になります。この結果が from のテーブルの代わりになることをイメージしてください。
javascript-179.gif

次はSQL全体を考えると、さきほどの結果をカウントしているだけです。
select count(CST_CD) from (select CST_CD from T04Customer where CST_CD <= " + cstCd + " order by CST_CD)

このSQL文を実行すると以下のようになります。
javascript-180.gif

まとめるとCST_CDが「7」以下のレコードは7件です。抽出条件のCST_CDが必ず最後のレコードになりますから、最後のレコードが何番目か(何件あるか)を調べれば選択ボックスの表示順がわかりますので、それがIndexになります。

今回は顧客選択ボックスの表示順は7番目ということになり、Indexは「7」を返します。

今回はたまたまCST_CDとIndexが一致していますが、CST_CDが連番だとは限らないこともありますので、このような処理が必要になります。

例えばCST_CDが以下の順番だった場合、107はIndexでは「3」になります。
101、103、107、110、120


(6)関数dataCheck()について
CST_CDを顧客選択ボックスに変えたことで、データチェックの方法が少し変わりました。
未入力かとうかは "" ではなく 0 を使います。
selectCstCd.value == 0

また選択ボックスではvalueが使われるため値は必ず数値になるので、数値かどうかのチェックは不要になりました。


スポンサードリンク

スポンサードリンク






JavaScript初心者入門講座TOPへ