javascriptで表計算 2004.4.12.Mon No.3219
javascript 超初心者です。宜しくお願いします。
javascript を使用して簡単な表計算をしたいのですが、出来ますでしょうか?
内容は Table
タグで作った表に 1.0 や 5.0 などの文字列が入っていて、その行や列の合計を一番端に表示さたいだけなのです。input
タグは使用しません。純粋に <td>1.0</td>
の値を数値として計算したいのです。
計算する値は残業時間の計算なので 5.0 の様な形になります。
どうかご指導お願いします。
Re: javascriptで表計算 ぴろあき 2004.4.14.Wed No.3220
※ここの部分のソースは■横計算バージョンに書いてあります。
教科書的に作るとこんな感じかな?
処理のステップとしては
<td>
の内容を取得する計算する
<td>
へ表示すると、たったこれだけです。
問題は JavaScript からHTMLへアクセスする方法なんですが、前時代の方法ではそれができず、<input type="text">
などで代用するしかありません。古いブラウザでも動くのはメリットですが、もはやそれだけがメリットです。
そこで、新しい方法として JavaScript とHTMLを橋渡しする「DOMインターフェイス」というのがあります。身近なメジャーブラウザではIE5以降・Netscape6以降・Opera7以降(Opera6は中途半端)・Safariなどが実装してます。
このサンプルでは、いくつかのノードインターフェイスを使ってますが、個々の詳細は検索とかで調べてみてください。(解説サイトも無数にあります)
http://jt.mozilla.gr.jp/docs/dom/technote/tn-dom-table/
http://www.parkcity.ne.jp/~chaichan/src/javascdom01.htm
DOMを使うことで JavaScript からHTMLへ自由にアクセスでき、document.write()
さえも過去の遺産にすることができます。また、DOMには仕様書があるので、ブラウザごとに処理を振り分けなくていいのも大きな魅力でしょう。(すべてのブラウザが完全に同じ動作をする…ともいかないのが現状ですけど)
Re: javascriptで表計算 2004.4.20.Tue No.3229
いろいろご丁寧に有り難うございます<(__)>
ご説明の内容で実施してみたいと思います。
また何かありましたら宜しくお力添えください。
有り難うございました。
Re: javascriptで表計算 2004.4.20.Tue No.3231
先日は大変助かりました。有り難うございました。
たびたび申し訳ありません。。。もう1点教えてください。
ご教授いただいた方法の応用で、たての合計をするにはどのように記述したら宜しいのでしょうか?
計算としては複数列のうち特定の列のみ計算する方法が知りたいのですが。
また空白のセルも混在していた場合についても教えて頂きたいのですが。(空白の場合は0を代入したい)
宜しくお願い致します。
Re: javascriptで表計算 ぴろあき 2004.4.22.Thu No.3234
横に計算するのは簡単なんですが、縦はちょっと難しくなります。(なのでサンプルは横で作ったのですけど)
<table>
<tr> <td1><td2><td3> </tr>
<tr> <td1><td2><td3> </tr>
<tr> <td1><td2><td3> </tr>
</table>
要するに、<tr>
ごとに <td1> <td2> <td3>
と個別に足していけばいいわけです。
まぁこれで充分なヒントになると思いますが、より高度なサンプルを作ってみたので興味があったら見てみてください。
http://faq.creasus.net/04/0422/
Re: javascriptで表計算 2004.4.23.Fri No.3237
ぴろあき様
ご回答、本当に本当に有り難うございます<(__)>
初心者故いろいろ質問させて頂く機会が多い中、ここまで親切丁寧にご回答頂いたことはありません。感謝感激しております。
自分の無知度合いをとても恥ずかしく思う一方、もっと勉強して行かねばと自分に活を入れ直しました。
作成して頂いたサンプルを参考に活用し、大切に保管致します。
次回質問させて頂く機会がありましたら、もう少しまともな内容で書けるよう頑張りますので、今後とも宜しくお願い致します。
ありがとうございました。
Re: javascriptで表計算 ぴろあき 2004.4.24.Sat No.3238
知りたいという興味を忘れずにいれば、人は成長するようにできてるものです。
JavaScript は簡単といっても、始めたてのうちは憶えることが山ほどありますから、ぷちぷちやってくのが良いですよ。
JavaScript に限らず、プログラムなんて一通りの構文さえマスターすれば、後は想像力と応用の世界ですしね。
頑張ってください。
メイン関数である tatecalc()
には、2種類の動作モードがあります。
動作モードは渡す引数の数で自動で切り替わります。(引数を2つ以上渡すと 2. になる)
非対応ブラウザでは実行されません。
window.onload
で実行され、結果をテーブルへ挿入します。出力にはDOMを使っています。
このサンプルでは、ついでにHTMLを作って表の下に列の個別結果を表示しています。
tr[0] | td[0] | td[1] | td[2] | td[3] | td[4] |
---|---|---|---|---|---|
tr[1] | 1.00 | 5.5 | 文字は無視 | 0000.4 | |
tr[2] | 3.0 | 5.4 | 100. | ||
tr[3] | 4.134 | 3.3 | 0.2 | 9.1 | |
tr[4] | 0.00 | 0.1 | 9.25 | 3混じっても無視 |
取得したい列を引数で渡すと、結果を返します。表への結果挿入はしません。
出力には document.write()
を使っています。
<td>
に数字以外が入ってる時・中身がない時は0として扱います。<th>
に対応してます。HTMLの文法的に見ても、見出しは <th>
で作るべきです。ただし、このサンプルには以下の制限があります。
<td>
の数が合わなくなる)<th>
を使うと即エラー。
function loadComplete() {
//引数をID名だけにすると結果をセルへ挿入する
//tdsum = 各列ごとの合計値(配列)
var tdsum = tatecalc("table1"); //<table id="table1">を対象にする
//表示するHTMLを作る
//数値は *1000 されたままなので小数に戻す
var allsum = 0; //すべての<td>の合計値
var text = "";
var d = document; //記述の省略用
var p = d.createElement("p"); //<p>を作る
for (var i = 0; i < tdsum.length; i++) {
allsum += tdsum[i];
text = "td[" + i + "] の合計は " + (tdsum[i] /1000)+ "。";
p.appendChild(d.createTextNode(text)); //text をノードに変換して<p>の最後に挿入
p.appendChild(d.createElement("br")); //<br>を作って<p>の最後に挿入
}
text = d.createTextNode("全部のセルの合計は " + (allsum /1000) + "。")
var strong = d.createElement("strong"); //<strong>を作る
strong.appendChild(text); //<strong>の最後に text を入れる
p.appendChild(strong); //<p>の最後に<strong>を入れる
var table = d.getElementById("table1"); //<table id="table1">を取得する
table.parentNode.insertBefore(p, table.nextSibling); //</table>の直後に<p>を挿入する
}
window.onload = loadComplete; //オンロードで loadComplete() が実行されるようにする
var sum = tatecalc("table1", 0, 1, 4); //td[0], td[1], td[4] の合計値が配列で返ってくる
if (sum) { //非対応ブラウザの時は false が返ってくるので確認
var s = "<p><strong>";
//数値は *1000 されたままなので元に戻す
s += "<code>td[0]<\/code> の合計は " + (sum[0] /1000) + "。<br>";
s += "<code>td[1]<\/code> の合計は " + (sum[1] /1000) + "。<br>";
s += "<code>td[4]<\/code> の合計は " + (sum[2] /1000) + "。<br>";
s += "<code>td[0,1,4]<\/code> の合計は " + ((sum[0] + sum[1] + sum[2]) /1000) + "。<br>";
s += "<\/strong><\/p>";
document.write(s);
}
セルを横に計算するバージョン。
横に計算する時は <tr>
ごとに <td>
を計算すればいいだけなので簡単です。
function yokocalc(tableID) {
if (!document.getElementById || !document.getElementsByTagName || (window.opera && !document.createEvent))
return; //非対応ブラウザはなにもしない
var table = document.getElementById(tableID); //<table id="ID名">を取得:DOM
var tr = table.getElementsByTagName("tr"); //<table>内の<tr>を全部取得(配列):DOM
var td, sum, num;
for (var i = 1; i < tr.length; i++) { //<tr>の数だけ繰り返し(最初の1列目はスキップ)
td = tr[i].getElementsByTagName("td"); //i番目の<tr>内にある<td>を全部取得(配列):DOM
sum = 0; //<td>の合計値
num = 0; //計算用の一時変数
for (var j = 0; j < td.length -1; j++) { //<td>の数-1 だけ繰り返し(最後の<td>は結果表示用)
if (td[j].firstChild) { //<td>内に文字が入ってるか
num = td[j].firstChild.data; //<td>内の文字を取得:DOM
num = parseFloat(num); //数値に変換
num = num *1000; //小数点問題を回避するために適当な整数にする
} else {
num = 0; //セルの中身がない時は0として扱う
}
sum = sum + num;
}
sum = sum /1000; //整数を小数に戻す
sum = document.createTextNode(sum); //sumをテキストノードに変換する:DOM
td[j].appendChild(sum); //sumを最後の<td>に挿入:DOM
}
}
<th>
の存在を無視してたり汎用性がなかったりで、とてもレガシー。1 | 2 | 3 | 計 |
1.0 | 2.29 | 3.4 | |
3.0 | 4.2 | 5.8 | |
2.0 | 5.1 |
勘違いされることが多いのですが、DOMはインターフェイス(橋渡し)であり、JavaScript ではないです。JavaScript にDOMとアクセスする機能が備わってるだけです。
DOMはプログラム言語とファイルの中間に立ち、相互間の橋渡しをしたりジェットストリームアタックをかけたりします。アタックがきたら上手くよけるなり踏み台にするなりしないといけません。
もちろん「プログラム」は JavaScript だけではないし、「ファイル」はHTMLだけではないです。VBScript でも使えるし、XHTMLやXMLも扱えます。(ただ、HTMLはすでに「終わった言語」なので、XHTMLやXMLの方に主眼が置かれてます)
そして、DOMを使い始めるとこれまでのようにルーズなHTMLは通用しなくなります。従来はHTMLと JavaScript が分離してたので、HTMLにミスがあってもたいした問題にはなりませんでしたが、これからはスクリプトエラーに直結します。
納得のいかないエラーが起きる場合は W3C Validation Service や Another HTML lint といったHTMLチェックサービスを活用してみるといいかも。
今は過渡期でAからZまでDOM…というわけにもいかないですが、これまでみたいなブラウザ独自拡張機能とは違うので、近い将来に大きな地位を占めるようになるんじゃないかと思います。(個人的にはXHTMLの普及が鍵だと思ってるんですが)
とりあえず、憶えて得することはあっても、損することはありません。欠点としては…難しいとこでしょうか。
…と、こんな感じになります。多少の汎用性は考えたけど、その分だけ小難しくなってます。その気になれば縦横を同時に計算することもできますが、ちょっと複雑になりすぎるのでやめました。
JavaScript を始めたてだと気が遠くなると思いますが、頑張って解析してみてください。
足りない部分はあるものの、その辺はサンプルスクリプトごときがサポートできる範囲ではないので、ご自由に編集したりHDの肥やしにしたりすると良いでしょう。
あと、セルに colspan
や rowspan
が入ると難度ランクが跳ね上がるのでご注意を。(こんな一朝一夕スクリプトでは無理)
このページは、質疑応答掲示板で使用した回答の残骸です。検索エンジンに捕まったりリサイクルしたりすることもあろうので、なんとなく残してあります。広く公開しているページではありませんが、第3者の閲覧を禁止するものでもありません。
恒久的なURIは保証できないものの、よほどのことがない限り削除されることはないでしょう。心配性な人はページの保存をおすすめします。(IEは mht 形式でないと保存できないかも)