【近況報告】
    2022春イベ ~ 2022梅雨イベ 甲完走。
    2022夏イベ ~ 2022初秋イベ 甲完走。
    艦娘コンプ継続中。




チェックボックスカウンタ

ある検索画面に検索条件のチェックボックスが並んでいます。
そのページのユーザから『どのチェックボックスの使用頻度が多いか調べたい』と言われました。

そこで、検索ボタンが押される都度、それぞれのチェックボックスのチェックの有無を調べて累積カウントするプログラムを作りました。

JavascrpitやPerlのプログラムは不慣れだったので、あちこちのHPを参考にして、なんとか動くものが出来ました。

今回の案件は、テスト用サーバがIIS5.0で、本番サーバがIIS6.0でした。
テスト用サーバで動いたカウンタが、本番サーバに持っていったらうまく動作しませんでした。
具体的には、CGIとしては動くのだけれど一番肝心のカウント値を記録するテキストファイルが、出来て欲しい所に見当たりません。
書き込み権限とか、IISCGI設定とかをあちこち見比べてみたのだけれど判らず、結局、IIS5.0とIIS6.0ではCGIの動作するカレントディレクトリが違うらしい事が判りました。

カウンタ用のテキストファイルは、ファイル名だけ指定していました。

  • IIS5.0では、CGIの置いてあるフォルダにテキストファイルができる。
  • IIS6.0では(CGIの置いてあるところとはかけ離れた)cgi-binフォルダにテキストファイルができる。


元々の計画では、ユーザのHTMLファイルを置いてあるフォルダの下にCGI用フォルダを作って、そこでカウンタを動作させるつもりだったけれど、本番のIIS6.0では、CGIプログラムの中に『絶対パス』でカウンタ用テキストファイルの位置を指定しないと上手く動作しないことが判ったので、カウンタ類はcgi-binの下にユーザ用フォルダを用意して、『相対パス』を書いて置くことにしました。

この違いが、ウチのサーバだけの問題なのかどうかはよく判らないけど、何かの役に立つかもしれないので、自分用にメモ。

以下の2ファイルをcgi-binの下に「cnttest」フォルダを作って置く。

カウンタ動作テスト用HTML(cbcount.htm)

<HTML>
<HEAD>
<title>カウントテスト</title>
</HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!--
function count_chk(form) {
  var max = form.chk_box.length;
  var param = '';
  for (var index = 0; index < max; index++) {
    if (eval("document.area_chk.chk_box[" + index + "].checked") ) {
      param = param + "1,";
    } else {
      param = param + "0,";
    }
  }
  param = param + "END";	//引数の終わりを示す

  location.href = 'cbcount.cgi?' + param;	//引数をつけてCGI起動
}
//-->
</SCRIPT>
<BODY>
<hr>
◎チェックボックスのチェックの有無を、ボタンが押される都度、累積カウントするテストプログラム。<br>
<hr>
◎使い方と動作<br>
<ol>
<li>項目A〜Dのチェックボックスを任意にOn/Offしてください。(*1)</li>
<li>検索ボタンに見立てた「(仮)ボタン」を押します。</li>
<ul>
<li>Javascript「count_chk」起動。</li>
<li>チェックの有無に応じてCGIに渡す引数を組み立て、CGI「cbcount.cgi」を起動。</li>
</ul>
<li>引数とカウンタ値の変化を表示して1.に戻る。</li>
<ul>
<li>CGIは引数の内容に応じて「cbcount.txt」を加算&更新。(*2)</li>
</ul>
<br>
(*1)チェックボックスの数は任意に変更可能です。<br>
(*2)「cbcount.txt」が存在しなければ自動的に作成します。<br>
</ol>
<br>
<ul>
<li><a href="cbcount.cgi?END">カウンタリセット</a></li>
<li><a href="cbcount.txt" target="_blank">cbcount.txtの内容</a><br>項目Aの累積カウント数,項目Bの累積カウント数,…,END(終端記号)</li>
</ul>
<br>
<center>
<form method="post" name=area_chk>
<input type=checkbox name=chk_box>項目A<br>
<input type=checkbox name=chk_box>項目B<br>
<input type=checkbox name=chk_box>項目C<br>
<input type=checkbox name=chk_box>項目D<br>
<br>
<input type=button value="(仮)ボタン" onClick="count_chk(this.form)"><br>
</center>
<hr>
</form>
<hr>
</BODY>
</HTML>


カウンタCGI(cbcount.cgi

#! /usr/local/bin/perl

$ParamData = $ENV{'QUERY_STRING'};		#CGIに渡された引数
$FileName = "./cnttest/cbcount.txt";

open( FILE, $FileName );			#カウンタ保管用テキストファイルを読み込みモードで開く
$LineOldData=<FILE>;				#旧カウンタ値を読み込む
close( FILE );

@ArrayOldData = split(/,/, $LineOldData );	#保管していたカウンタ値を「,」毎に分解して配列に保管 
@ArrayAddData = split(/,/, $ParamData );	#加算する引数も同様に「,」毎に分解して配列に保管
$LineNewData = '';				#加算後の文字列保管用エリア

for($i=0;$i<=@ArrayAddData;$i++){
	if ($ArrayAddData[$i] eq "END") { last; }	#引数の末尾でFor Loopを抜ける
	$LineNewData = $LineNewData .( $ArrayOldData[$i] + $ArrayAddData[$i] ). ',';	#加算しつつ文字列組み立て
}
$LineNewData = $LineNewData . 'END';

open( FILE, ">".$FileName );			#更新したカウンタ値を1行の文字列として保存
print FILE $LineNewData;			
close( FILE );

	#以下は動作確認用。

print "Content-type: text/html\n\n";
print <<"HTML";
<center>
カウンタ更新CGI<br>
<HTML><BODY><table border=1>
<tr><th>旧 cbcount.txt</th><td>$LineOldData</td></tr>
<tr><th>+引数</th><td>$ParamData</td></tr>
<tr><th>=新 cbcount.txt</th><td>$LineNewData</td></tr>
</table>
<br><br>
<a href="cbcount.htm">カウントテスト</a>に戻る。<br>
<br>
<hr>
<br>
</center>
</BODY></HTML>
HTML

◎以下のページを参考に作りました。ノウハウ提供に感謝します。
CGI



JavaScript