三流君ASPで遊ぶ、失敗する

[三流君] Top ken3.orgへ
[ASP解説] ASPの解説TOP
[ASP記事 バックナンバー] 番号順のバックナンバー
[SOHO/在宅プログラマー/派遣] 派遣のお話ほか
[...サイトマップ(総合案内へ)]




分類別ガイド
ADOで[ADO Mdb接続] ,[ADO Excel接続] ,[ADO CSV接続]

[ASP Form データのやりとりPOSTとGET]
[ASPでTextFile操作]
[ASPでVBScriptを使う]
[その他サンプル]

バックナンバー No.20 〜 No.24


No.20 2002/12/18
インクルード ファイルを使ってまとめてみた
[ページTOPへ戻る]
<インクルード ファイルを使ってまとめてみた>

こんにちは、Ken3です。

今回は、
インクルード ファイルを使って
処理をまとめてみたいと思います。

たいした話じゃないので、あまり期待しないでね。

/*
 * 1.同じ処理が入ってるのは、なんかなぁ。。。
*/

In message "感想",
*****8さん wrote...
 >広告見せるならソース見せろ

に反応して、ソースファイルを表示する処理を最近追加しました。

http://www.ken3.org/cgi-bin/test/test017-2.asp
でServer.HTMLEncodeを使用して変換表示、

次に、
http://www.ken3.org/cgi-bin/test/test017-3.asp
では、
Request.ServerVariables("SCRIPT_NAME")を使用して、
関数にまとめてみました。

今後のASPのサンプルの後ろに付けたので、
http://www.ken3.org/cgi-bin/test/test018-1.asp
を実行すると、無事にASPのソースファイルも表示されます。

でも、なんかバカっぽいよね。
      ^^^^^^^^^^^^^^^^^^^^^
えっ、どこが?
広告表示からソース表示に変えたよ。結果とプログラムも見れるし。

そのソースの表示関数が
いつも最後に、それも含めてASPの中身が表示されるジャン。
^^^^^^
なんかまぎらわしいんだよね。

それに、いつも最後に入れてるのって、変だしね。

言われて見れば、、、何か共通で使う方法ってあるはずだから探してみるか。

/*
 * 2.ファイルをインクルードする
*/
ファイルをインクルードって、
聞きなれない言葉かもしれないけど、
好きな位置に指定したファイルを入れた状態にできます。

書き方は簡単で、
<!-- #include file ="header1.inc" -->
これを、ASPのファイルの中に入れておくと、
自動的にheader1.incファイルを読みとって、
中身を挿入してくれます。

簡単に2つのファイルにわけた例を書くと、

-- test020-1.asp  普通のASPファイル
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>インクルードファイルの使用</title>
</head>
<body>
<h2>インクルードファイルの使用</h2>
test020-1.asp<br>
動作仕様:<br>
out_src.incを読み込み、よく使う処理をまとめてみます<br>
さてさて、どうなることやら、、、<br>
<hr>

<% Call OUT_SRC() 'ソースの表示関数を呼ぶ %>

</body>
</html>

<!--  #include file="out_src.inc" -->

---ここまで、

-- ここから、out_src.inc
<% 'ソースの表示関数  SUB OUT_SRC() out_src.incに移しただけ

Sub OUT_SRC() 

  Dim strSCR_NAME

  strSCR_NAME = Request.ServerVariables("SCRIPT_NAME")  '名前を代入

  '見出しの表示
  Response.Write "<HR><b>" & strSCR_NAME & "</b><HR>"
  Response.Write "<PRE>"  'スペースを有効にするため

  ' FileSystemObjectを生成します、、って英文、そのままジャン。
  Set objFS = Server.CreateObject("Scripting.FileSystemObject")

  '*5 スクリプト(strSCR_NAME)を読取専用モードで開きデータを読む
  Set ts = objFS.OpenTextFile(Server.MapPath(strSCR_NAME), 1, True)

  Do While ts.AtEndOfStream = False  'ファイルの終端になってない間ループ
    strDATA = ts.ReadLine   'ファイルからデータを一行を読む
    '*1読み込んだデータをServer.HTMLEncodeで変換表示
    Response.Write Server.HTMLEncode(strDATA)
    Response.Write chr(13) & chr(10)   '改行する
  Loop

  '使ったファイルは閉じようよ
  ts.close

  Response.Write "</PRE>"  'ここまで
  Response.Write "<HR>"    '<HR>で区切る

End Sub  '関数はここまでですよ。

%>
----

と、2つのファイルにわけてあります。

test020-1.asp内の最後、
<!--  #include file="out_src.inc" -->
の記述で、out_src.incが挿入されるので、
同じように処理でき、
処理もまとまってます。

http://www.ken3.org/cgi-bin/test/test020-1.asp
を実行すると少し感覚がわかると思います。



/*
 * 3.別にインクルードファイルは2つでも、途中でも、関数じゃなくても
*/

<!--  #include file="ファイル名" -->
で
別ファイルに記述した関数(命令)
がそのまま簡単に入る感じです。

えっ、関数しか?書いたらダメなの?
なんだぁ、いつも変わるリンク情報やお知らせを書いて共通化したかったのになぁ。

あっ、私の言葉が足りなかったですね、
そのままファイルの内容を読みこむので、
中身はなんでもいいんですよ。
^^^^^^^^^^^^^^^^^^^^^^^^^^^
あと、インクルードの場所は、どこでもいいし、何個でも
*あまりやり過ぎると、逆に見にくくなるので注意かなぁ。

簡単な例を書くと、
頭にお知らせがあるページを作りたい場合、

まず、お知らせ用の共通な.incファイルを作成します
ここでは、名前を、info_g.incとして、中身を書きます。

-- info.inc
<HR>
今週の目標:<b>アンケート処理をまとめて、説明する予定</b><br>
<a Href="http://www.ken3.org/asp/">
[ASP系メニューへ]</a>
<a href="http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi">
[質問・感想掲示板]</A>
<a href="http://www.ken3.org/backno/backno_asp_mokuji.html">
[バックナンバー目次]</a>
<HR>
-- ここまで

と、お知らせのコメントとページのリンクを書きました。

-- test020-2.asp で、下記のように使ってます
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>普通の内容をインクルードしてみた</title>
</head>
<body>
<h2>普通の内容をインクルードしてみた</h2>
↓ここから下にテストでinfo_g.incをインクルードしてみる<br>

<!--  #include file="info_g.inc" -->

↑上に挿入されてますか?<br>
test020-2.asp<br>
<hr>

<% Call OUT_SRC() 'ソースの表示関数を呼ぶ %>

</body>
</html>

<!--  #include file="out_src.inc" -->

-- ここまで


ポイントは、
↓ここから下にテストでinfo_g.incをインクルードしてみる<br>

<!--  #include file="info_g.inc" -->

↑上に挿入されてますか?<br>

の場所で、普通にHTMLタグの記述だけでも入るので、
ヘッダーをまとめたりねフッターをまとめたり、
変更があっても、元ファイルを修正しないで、
インクルードのファイルを修正するだけで
と
活用すれば、管理の幅も広がると思います。

http://www.ken3.org/cgi-bin/test/test020-2.asp
でテストできます。

-- 余談
.inc と 書いてるけど、別に拡張子も何でもOKです。
でもわかり易い名前にして下さい。

/*
 * 4.問題点は?無いの?
*/

へぇ〜、
<!--  #include file="ファイル名" -->
って、使えそうジャン、
でも、問題点はないの?

拡張子.inc、
何も設定してないと、
丸見えなんですよ。

http://www.ken3.org/cgi-bin/test/info_g.inc
http://www.ken3.org/cgi-bin/test/out_src.inc

をブラウザで見てみると(メールからクリックの自動起動でも)

ねっ、IEでは中身が表示されたでしょ
(か、ダウンロード・保存になると思います)

out_src.inc 今は見られてもいい処理しか入っていないけど、
パスワード管理のASP関係を共通化しようとして、
pas_src.inc なんかにまとめて、
使っていたりする、無頓着な人が居たら、マズイよ。

レンタルサーバーだと、
個々のファイルのセキュリティの設定できないけど、
見られたくないファイルは、
外から見えない場所に置いておかないと
(外から見えない設定しないとね)

今は、気にしなくてもいい話ですが、
頭のスミにでも入れといて下さいね。

/*
 * 5.終わりの挨拶
*/

今回は、
・ファイルをインクルードしてみた
でした。

素朴な疑問あったら、気軽に、
メール、掲示板に書き込んでくださいね。

ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.21 2002/12/19
文字列の置き換え、Replace関数を使用
[ページTOPへ戻る]
<文字列の置き換え、Replace関数を使用>

こんにちは、Ken3です。

今回は、
文字列を置換える関数、
Replace関数を使ってみます。

たいした話じゃないので、あまり期待しないでね。

/*
 * 1.Replace関数のテスト
*/

文字列を置換する関数で、
Replace関数
ってのがあるらしい。

へぇ〜、そうなんだ。
チョット試してみよう。

-- test021-1.asp
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>文字列の置き換え、Replace関数を使用</title>
</head>
<body>
<h2>文字列の置き換え、Replace関数を使用</h2>
test021-1.asp<br>
動作仕様:<br>
よくある文字列の置き換え処理です<br>
書き方は簡単で、<br>
変換後 = Replace(元の文字列, 変換したい単語, 置換える単語)<br>
です。<br>
  moji = "こんな三流プログラム見たこと無いよ"<br>
  moji = Replace(moji, "三流", "キタナイ")  '三流をキタナイに置換え<br>
↓結果は、<br>
<%
  dim moji
  moji = "こんな三流プログラム見たこと無いよ"
  moji = Replace(moji, "三流", "キタナイ")  '三流をキタナイに置換え
  Response.Write moji & "<BR>"
%>
↑うまくいったかなぁ?<br>
<hr>

<% Call OUT_SRC() 'ソースの表示関数を呼ぶ %>

</body>
</html>
---

使い方は簡単で、
  moji = "こんな三流プログラム見たこと無いよ"
  moji = Replace(moji, "三流", "キタナイ")  '三流をキタナイに置換え
  Response.Write moji & "<BR>"
みたいに、
変換後 = Replace(元の文字列, 変換したい単語, 置換える単語)
です。

オイオイ、サンプルならウケ狙って、
moji = Replace(moji, "三流", "一流") 
にしてよ(笑)

結果は、わかるよね(笑)

/*
 * 2.Replace関数を使って、タグの追加を考える
*/

この前作成した、ASPソースを表示するサブルーチン覚えてますか?
表示は出来てるんだけど、なんか見にくくて。

htmlって、必要なタグで囲むといろいろな表現ができますよね。
<b>キーワード</b>とやると、キーワードが強調表示されます。

そんなの知ってるよ、だから何?

えっと、
  moji = "こんな三流プログラム見たこと無いよ"
  moji = Replace(moji, "三流", "<b>三流</b>")  '<b>〜</b>で囲う
  Response.Write moji & "<BR>"
とやると、三流の文字が<b>三流</b>に置換わり、
強調表示されます。

これを使用して、講座のテーマ、サンプルのキーワードを指定して、
強調表示させてみたいなぁとフト思いました。

あと、VBScriptの部分、
<% 〜  %>で囲まれているので、
色を変えてみようかなぁ。

/*
 * 3.ソース表示の関数を変更する
*/

インクルードファイルに書いた、
ソースの表示関数を修正してみました。

-- out_src.inc 
<% 'ソースの表示関数  SUB OUT_SRC(strB) 強調表示する単語をもらう

Sub OUT_SRC(strB) 

  Dim strSCR_NAME

  strSCR_NAME = Request.ServerVariables("SCRIPT_NAME")  '名前を代入

  '見出しの表示
  Response.Write "<HR><b>" & strSCR_NAME & "</b><HR>"
  Response.Write "<PRE>"  'スペースを有効にするため

  ' FileSystemObjectを生成します
  Set objFS = Server.CreateObject("Scripting.FileSystemObject")

  ' スクリプト(strSCR_NAME)を読取専用モードで開きデータを読む
  Set ts = objFS.OpenTextFile(Server.MapPath(strSCR_NAME), 1, True)

  Do While ts.AtEndOfStream = False  'ファイルの終端になってない間ループ
    strDATA = ts.ReadLine   'ファイルからデータを一行を読む
    '読み込んだデータをServer.HTMLEncodeで変換表示
    strDATA = Server.HTMLEncode(strDATA)
    '次に、強調文字、<%、%>の置換え処理を行う
    strDATA = Replace(strDATA, strB, "<b>" & strB & "</b>") '強調
    strDATA = Replace(strDATA, "<%", "<font color='blue'><%") '青にする
    strDATA = Replace(strDATA, "%>", "%></font>")     'カラー終了
    '表示を行う
    Response.Write strDATA
    Response.Write chr(13) & chr(10)   '改行する
  Loop

  '使ったファイルは閉じようよ
  ts.close

  Response.Write "</PRE>"  'ここまで
  Response.Write "<HR>"    '<HR>で区切る

End Sub  '関数はここまでですよ。

%>
----

ポイントは、
Sub OUT_SRC(strB) 
引数で強調したいキーワードをもらいます。

あとは、変換関数を並べただけ

まず、読んだデータをエンコードする
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    '読み込んだデータをServer.HTMLEncodeで変換表示
    strDATA = Server.HTMLEncode(strDATA)
なんて言ってるけど、Server.HTMLEncode関数頼り(笑)

タグを挿入(置換える)
^^^^^^^^^^^^^^^^^^^^^
    '次に、強調文字、<%、%>の置換え処理を行う
    strDATA = Replace(strDATA, strB, "<b>" & strB & "</b>") '強調
    strDATA = Replace(strDATA, "<%", "<font color='blue'><%") '青にする
    strDATA = Replace(strDATA, "%>", "%></font>")     'カラー終了
ここでのポイントは、
私がしくじったのは失敗を先に書くと、
strDATA = Replace(strDATA, "<%", "<font color='blue'><%") '青にする
とやってしまい、
上のServer.HTMLEncode関数で<%は&lt;%に置換わってたんですね。
なので、正解は変換された文字をさらに置換えて<Font>を足す、
strDATA = Replace(strDATA, "<%", "<font color='blue'><%") '青にする
だったんですね。
う〜ん深い。

えっ、テメエがデータの変化に付いて行けなかったダケ?だって?
お恥ずかしい。。。(マジであせりました、できなくって(笑))

http://www.ken3.org/cgi-bin/test/out_src.inc
が修正したソース表示の共通ファイルで、

http://www.ken3.org/cgi-bin/test/test021-1.asp
で無事強調表示とスクリプト部分が青色になってます。
*見て下さいね。

/*
 * 4.終わりの挨拶
*/

今回は、
・Replace関数で置換え処理
でした。

素朴な疑問あったら、気軽に、
メール、掲示板に書き込んでくださいね。

ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.22 2002/12/22
隠し項目type="hidden"を使ってみた
[ページTOPへ戻る]
<隠し項目type="hidden"を使ってみた>

こんにちは、Ken3です。

今回は、
感想メッセージを受け取って、
ファイルに貯めてみたいと思います。
ついでにフォームの隠し項目を使ってみたいと思います。

たいした話じゃないので、あまり期待しないでね。

/*
 * 1.やりたいことを仕様に落す
*/

おっちゃんは何?やりたいの?
(まず、要望をヒアリングかな)

HPに来てくれた人が感想を軽く書けるようにしたいんだ。

感想って?何?、名前と感想だけ聞ければいいの?
(データはどんなの貯めとくか聞く)

そうだなぁ、名前と感想、あとどのページで書かれたかが知りたいなぁ。

はいはい、データは、名前、感想、記入場所がわかればいいのね。

簡単にまとめると、
入力部は、Htmlのフォームに
名前
感想
記入場所
の項目を設置して、

書込みのボタンが押されたら
ASP側で、これを受け取って、
いつものテキストファイルに書き込むか。
(いつになったらDBやるんだよ(催促?))

出力部は、
書き込み時刻
記入場所
名前
感想
の順番に書き込みますか。

あれ?勝手に時刻が追加されてるけど。
あっ、これ?Ken3の趣味だから気にしないでね。

/*
 * 2.入力側の作成 type="hidden" を使ってみた
*/
テストで感想入力のフォーム付きを作成するか。

-- test022.html --
<html>
<head>
<title>感想記入のサンプル 隠し項目type="hidden"を使ってみた</title>
</head>
<body>
<h2>感想記入のサンプル 隠し項目type="hidden"を使ってみた</h2>
<br>
下記の項目の感想を記入していただけるとうれしいです。<br>
<hr>
<FORM ACTION="test022-1.asp" METHOD="POST">
<b>メルマガ文章のレベルについての何かあれば?</b><br>
例)簡単でつまらない、難しいので詳しく...など<br>
名前:<INPUT TYPE="text" NAME="t-name" SIZE="20 "VALUE="匿名希望"><br>
感想:<TEXTAREA ROWS=5 COLS=30 NAME="t-kanso">
ここにご意見、感想を記入して下さい
</TEXTAREA><br>
<INPUT type="hidden" NAME="kakushi" VALUE="レベル">
<br>
<INPUT TYPE="submit" VALUE="書き込み">
<INPUT TYPE="reset"  VALUE="入力クリア">
</FORM>
<hr>
<FORM ACTION="test022-1.asp" METHOD="POST">
<b>素朴な疑問/質問、今後取り上げてほしい話などあれば</b><br>
例)DB関係ハヤクやってよ、パスワード画面の作り方...など<br>
名前:<INPUT TYPE="text" NAME="t-name" SIZE="20 "VALUE="匿名希望"><br>
感想:<TEXTAREA ROWS=5 COLS=30 NAME="t-kanso">
ここにご意見、感想を記入して下さい
</TEXTAREA><br>
<INPUT type="hidden" NAME="kakushi" VALUE="質問">
<br>
<INPUT TYPE="submit" VALUE="書き込み">
<INPUT TYPE="reset"  VALUE="入力クリア">
</FORM>
<hr>
<FORM ACTION="test022-1.asp" METHOD="POST">
<b>作者に言いたいこと(全体的に)</b><br>
例)マジメに解説して下さい、HPの更新をハヤク...など<br>
名前:<INPUT TYPE="text" NAME="t-name" SIZE="20 "VALUE="匿名希望"><br>
感想:<TEXTAREA ROWS=5 COLS=30 NAME="t-kanso">
ここにご意見、感想を記入して下さい
</TEXTAREA><br>
<INPUT type="hidden" NAME="kakushi" VALUE="作者へ">
<br>
<INPUT TYPE="submit" VALUE="書き込み">
<INPUT TYPE="reset"  VALUE="入力クリア">
</FORM>
<hr>

</body>
</html>
---

こんな感じで、3種類のアンケート入力フォームを作りました。
( http://www.ken3.org/cgi-bin/test/test022.html )

ポイントは、
^^^^^^^^^^
画面に表示されない隠し項目の
<INPUT type="hidden" NAME="kakushi" VALUE="レベル">
<INPUT type="hidden" NAME="kakushi" VALUE="質問">
<INPUT type="hidden" NAME="kakushi" VALUE="作者へ">
の書き方です。

この項目は、存在していて、送信時は、データとして送られるのですが、
画面上は表示されないので、隠しパラメータみたいに使用することができます。

バックナンバー1、2、、、99の感想を取りたい時は、
<INPUT type="hidden" NAME="NO" VALUE="1">
とやっとけば、1の感想、
<INPUT type="hidden" NAME="NO" VALUE="7">
だったら、7が送られるので、ユーザーに内緒でいろいろな判断に使えます。

/*
 * 3.送られてきた項目を書き込む
*/

POSTでtest022-1.aspへ
t-name
t-kanso
kakushi
が送られてくるので、書き込みます。

-- test022-1.asp 
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>感想をテキストファイルに書き込む</title>
</head>
<body>
<h2>感想をテキストファイルに書き込む</h2>
test022-1.asp<br>
<hr>
<% Call DATA_WRITE() %>
<hr>
<h3>感想記入どうもです</h3>
test022.txtへ書き込み終了です。<br>
<A HREF="test022.txt" TARGET="_blank">test022.txtを見る</A><br>

</body>
</html>

<% '気分で関数化して、外側に出してみた

Sub DATA_WRITE()

  '未記入でデータが送られて来たかチェックする
  If IsEmpty(Request.Form("t-kanso")) = True Then
      Exit Sub '関数を抜ける
  End If

  '感想そのままでボタンが押されたか?を左6文字が"ここにご意見"で判断
  If Left(Request.Form("t-kanso"),6) = "ここにご意見" Then
      Exit Sub   '関数を抜ける
  End If

  'FileSystemObjectを生成します
  Set objFS = Server.CreateObject("Scripting.FileSystemObject")

  'test022.txt を追加モードで開く
  Set ts = objFS.OpenTextFile(Server.MapPath("test022.txt"), 8, True)

  'ファイルにデータを書き込む
  ts.write Now & ","              '時刻
  ts.write Request.Form("kakushi") & ","  '隠し項目の入力場所を書く
  ts.write Request.Form("t-name") & ","   '名前を書く

  '感想の改行を<BR>に置換える
  Dim strKANSO
  '受け取ったt-kanso内の改行を<br>に置換える
  strKANSO = Replace(Request.Form("t-kanso"), chr(13) & chr(10), "<br>") 
  ts.write strKANSO  '変換した感想を書く

  ts.write chr(13) & chr(10)      '改行する

  '使ったファイルは閉じようよ
  ts.close

End Sub
%>
---

送られて来たパラメータをテキストファイルに書き込む、
もう楽勝だよね。
*なんて言ってる私は、前のソースをコピーしながら使ってます。
 なかなか、コマンド覚えられなくってね。
 Ifとか短かったらいいんだけど、
  Scripting.FileSystemObjectとか長いしね(これはまだわかり易い単語かな)


関数はSubからEnd Subまで
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sub DATA_WRITE()
と、書きこみ関数を外側に作ってみました。
呼ぶほうはHTMLの中、
<% Call DATA_WRITE() %>
でCallを使って呼びます。

先にデータをチェックする
^^^^^^^^^^^^^^^^^^^^^^^^
  '未記入でデータが送られて来たかチェックする
  If IsEmpty(Request.Form("t-kanso")) = True Then
      Exit Sub '関数を抜ける
  End If
と、IsEmptyを使って項目が存在するかチェックしました。
次に、
  '感想そのままでボタンが押されたか?を左6文字が"ここにご意見"で判断
  If Left(Request.Form("t-kanso"),6) = "ここにご意見" Then
      Exit Sub   '関数を抜ける
  End If
で、単純なんだけど、
Left関数を使用して、左から6文字がデフォルトデータの
"ここにご意見"かチェックしてます。

ファイルを開けて、書き込む
^^^^^^^^^^^^^^^^^^^^^^^^^^
  'FileSystemObjectを生成します
  Set objFS = Server.CreateObject("Scripting.FileSystemObject")

  'test022.txt を追加モードで開く
  Set ts = objFS.OpenTextFile(Server.MapPath("test022.txt"), 8, True)

  'ファイルにデータを書き込む
  ts.write Now & ","              '時刻
  ts.write Request.Form("kakushi") & ","  '隠し項目の入力場所を書く
  ts.write Request.Form("t-name") & ","   '名前を書く

まぁ、ここまでは、自然な流れで書きこんでます。
ポイントの隠し項目もすんなり
Request.Form("kakushi")
で普通に取出せます。

テキストエリアの改行を処理
^^^^^^^^^^^^^^^^^^^^^^^^^^
  '感想の改行を<BR>に置換える
  Dim strKANSO
  '受け取ったt-kanso内の改行を<br>に置換える
  strKANSO = Replace(Request.Form("t-kanso"), chr(13) & chr(10), "<br>") 
  ts.write strKANSO  '変換した感想を書く

私が失敗したのがここで、
ts.write Request.Form("t-kanso")
とそのままデータを書くと、
テキストエリアの改行が生きていて、改行されてしまいます。
*エラー画像は、



そこで、前回使ったReplace関数を使用して、
strKANSO = Replace(Request.Form("t-kanso"), chr(13) & chr(10), "<br>") 
と、chr(13) & chr(10) を "<br>"に変換してみました。

無事、なんとか書き込めたみたいだけど。。。



/*
 * 4.終わりの挨拶
*/

今回は、
・隠し項目を使ってみた
・テキストエリアのデータには、改行が付いてるよ
でした。

素朴な疑問あったら、気軽に、
メール、掲示板に書き込んでくださいね。

ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.23 2002/12/23
苦肉の策、配列をリングみたく使ってみた
[ページTOPへ戻る]
<苦肉の策、配列をリングみたく使ってみた>

こんにちは、Ken3です。

今回は、
テキストファイルのデータを逆順に読んでみたくって、
チャレンジしたけど、うまく行かなかった話です。

おい三流プログラマー、うまく行かない話をメルマガにするの?
ええ、笑ってもらおうと思って。
(ホンネは、途中まで書いてて、出来ないことに気が付いて方向転換です(笑))

たいした話じゃないので、あまり期待しないでね。

/*
 * 1.やりたいこと
*/

キミは今日、何?やりたいの?
(まず、要望をヒアリングかな)

test008.txt ( http://www.ken3.org/cgi-bin/test/test008.txt )
に時刻と評価が下記のように書かれています。
2002/12/05 8:11:04 , 満足
2002/12/05 8:14:12 , 普通
2002/12/05 15:53:28 , 満足
 ・
 ・
 ・
2002/12/07 15:36:54 , 満足
2002/12/07 15:56:49 , 満足
2002/12/07 15:57:22 , 不正なパラメーターです

とテキストファイルがあって、
これを表示するプログラム、をいろいろと作ってました。

そのまま表示
http://www.ken3.org/cgi-bin/test/test010-2.asp

5個単位で区切る
http://www.ken3.org/cgi-bin/test/test018-1.asp

行番号を付ける
http://www.ken3.org/cgi-bin/test/test019-1.asp

この処理で共通しているのが、
頭からファイルを1行読んで、
行番号を付けたり、5個単位を判断して線を引いたりと、
登録順(ファイルの上から順)の処理でした。

よくある話で、最近の10件を知りたい、、、
なんて話がありますよね。

今回の要望は、最近の(最新の)10件を表示してみたい。

そんなの後ろから1行単位で読んで戻ればいいんだろ、簡単ジャン。

ほんと、サスガ三流と言ってもプログラマーさんだね、よろしくです。

/*
 * 2.ウソだろ?テキストファイルにランダムアクセスできない?(戻れないの?)
*/

一般的な考え方として、
ファイルポインタを一行戻しながら読み、
(一行戻してから読み、2行戻すと1つ前に行くのかなぁ)
を
繰り返せばいいのかなぁと安易に考える。

ファイルポインタを移動させるような命令を探してみる。
えっ、無いのもしかして?

SkipLineメソッドってのあるから、
.SkipLine -2とかできないのかなぁ。
残念、できないみたいだ。

ファイルへランダムにアクセス可能か、調べないと。
もしかして、テキストストリームじゃダメだけど、
ほかの方法があるかもしれない。

今回は、プログラムでかわす方法を考えるか、、、

/*
 * 3.配列をリング的に使う
*/

リングって映画、怖いらしいねぇ。
私も知ってればいろいろと例を出せるけど知らないからなぁ、
じゃなくって、配列にデータをリング上に入れるイメージで処理してみます。

ソースを見る前に、イメージはリング(円)です。
円だったらサークルじゃないの?
って思うけど、どうなんだろう。
まぁイイヤ。

で、下記が小手先技で最新10件を表示したソースです。

-- test023-1.asp
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>配列をリング状に使う</title>
</head>
<body>
<h2>配列をリング状に使う</h2>
test023-1.asp<br>
配列をリング状に使って、最新の10件を表示した<br>
<hr>
<% Call DATA_READ() '読みこみ表示関数をコール%>
<hr>
終了です。<br>
<A HREF="test008.txt" TARGET="_blank">元データtest008.txtを見る</A><br>

</body>
</html>

<% '気分で関数化して、外側に出してみた

Sub DATA_READ()

  'FileSystemObjectを生成します
  Set objFS = Server.CreateObject("Scripting.FileSystemObject")

  'test008.txt を読取専用モードで開く
  Set ts = objFS.OpenTextFile(Server.MapPath("test008.txt"), 1, True)

  Dim strBOX(10) '*1文字列のバッファを10個取る

  Dim nSETIndex  '*2セット位置
  nSETIndex = 0  'セット位置を初期化

  'ファイルからデータを読む
  Do While ts.AtEndOfStream = False  'ファイルの終端になってない間ループ
    '*3ファイルからデータを一行を読みバッファにセット
    strBOX(nSETIndex) = ts.ReadLine
    '*4バッファのセット位置を調整する
    nSETIndex = nSETIndex + 1   'セット位置を+1する(次に移動)
    If nSETIndex = 10 Then      '10になったら0に戻す
        nSetIndex = 0
    End If
  Loop

  ts.close  '使ったファイルは閉じようよ(もうファイルは使わないので)

  'データの表示
  For i = 1 To 10  '10回まわるよ
    '表示位置の調整
    nSETIndex = nSETIndex - 1  'ポインタを1つ前にする
    If nSETIndex < 0 Then '0以下になったら9にする
        nSETIndex = 9
    End If
    'データの表示
    Response.Write strBOX(nSETIndex)  '配列のデータを表示
    Response.Write "<BR>"   '改行のタグを入れる
  Next

End Sub
%>
----

なんか複雑なことやってるよね。
そんなこと無いですよ。

ファイルアクセスの準備
^^^^^^^^^^^^^^^^^^^^^^
  'FileSystemObjectを生成します
  Set objFS = Server.CreateObject("Scripting.FileSystemObject")
  'test008.txt を読取専用モードで開く
  Set ts = objFS.OpenTextFile(Server.MapPath("test008.txt"), 1, True)
いつもの、
FileSystemObjectを生成とテキストストリームをオープンしてます。
私は前回のソースをコピーで作成してます。

バッファを10個用意した
^^^^^^^^^^^^^^^^^^^^^^^^
  Dim strBOX(10) '*1文字列のバッファを10個取る
読みこんだデータを入れるバッファを10個用意しました。
0123456789
って感じですかねぇ。

セットする位置を記憶する変数を用意する
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Dim nSETIndex  '*2セット位置
  nSETIndex = 0  'セット位置を初期化
配列へのセット位置を変数で管理したいので、1つ変数を用意。
初めは0で初期化してます。

ファイルからデータを読み、用意した10個のバッファにセット
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  'ファイルからデータを読む
  Do While ts.AtEndOfStream = False  'ファイルの終端になってない間ループ
    '*3ファイルからデータを一行を読みバッファにセット
    strBOX(nSETIndex) = ts.ReadLine
    '*4バッファのセット位置を調整する
    nSETIndex = nSETIndex + 1   'セット位置を+1する(次に移動)
    If nSETIndex = 10 Then      '10になったら0に戻す
        nSetIndex = 0
    End If
  Loop
ここが1つのポイントで、
    '*3ファイルからデータを一行を読みバッファにセット
    strBOX(nSETIndex) = ts.ReadLine
何をしてるか?
命令見るとnSETIndex番目の配列にデータをセット。
初めは0だから0番目にセットされてます。
で、セット後に、
    '*4バッファのセット位置を調整する
    nSETIndex = nSETIndex + 1   'セット位置を+1する(次に移動)
次の位置に移動してます。
    If nSETIndex = 10 Then      '10になったら0に戻す
        nSetIndex = 0
    End If
ここがポイントで、10になったら0にセット位置を戻してます。
0123456789012....
とセットする位置が循環します。
13個データがある場合はループで、
0に1行目
1に2行目
 ・
 ・
8に9行目
9に10行目のデータが入る、
カウンタnSETIndexが10になったら、0に戻る
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0に11行目
1に12行目
2に13行目 カウンターnSETIndexは次の3になっている
でデータが終わる(3にセットする前でデータEnd)
データが連続で、10個の配列を使いまわして代入されてるイメージ、
なんとなくわかりましたか?

ファイルは用済み
^^^^^^^^^^^^^^^^
  ts.close  '使ったファイルは閉じようよ(もうファイルは使わないので)
データは読み終わったので、閉めます。

データの表示
^^^^^^^^^^^^
  'データの表示
  For i = 1 To 10  '10回まわるよ
    '表示位置の調整
    nSETIndex = nSETIndex - 1  'ポインタを1つ前にする
    If nSETIndex < 0 Then '0以下になったら9にする
        nSETIndex = 9
    End If
    'データの表示
    Response.Write strBOX(nSETIndex)  '配列のデータを表示
    Response.Write "<BR>"   '改行のタグを入れる
  Next
表示は10個なので、10回のループを作ってます。
配列の0から表示すると?ダメですよね、(11,12,13の並びになってしまう)
配列のカウンターを戻しながら表示したいので
    nSETIndex = nSETIndex - 1  'ポインタを1つ前にする
で、3だったカウンターが2に戻ります。
0に11行目
1に12行目
2に13行目 カウンターnSETIndexは次の3になっている
でセットは、終わってましたね。
無事13行目のデータが表示され、
次はカウンターが1となり12行目、
次は0で11行目、
−1となったところで、
    If nSETIndex < 0 Then '0以下になったら9にする
        nSETIndex = 9
    End If
のIf文が活躍して、
nSETIndex = 9
10行目のデータ表示になり、
また1つ減ってnSETIndex = 8で9行目のデータ。
こんな簡単な仕掛けだったんですね
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

なんて、強がって言ってる割には、苦労したけど。

テストの表示は、↓で試してください。
http://www.ken3.org/cgi-bin/test/test023-1.asp
元データTEST008.TXTと確認すると、なんとか逆順で表示されてます。

今思えば、1から10までセットのほうが説明わかりやすかったかも、
循環でバッファ使ってるのは、
1、11、21...は(1)
2、12、22...は(2)
 ・
 ・
 ・
10、20、30...は(10)にセット
が、わかりやすかったかなぁ。まぁいいや。

*書き直せよな、読者がわかりやすいように。

/*
 * 4.終わりの挨拶
*/

今回は、
・テキストストリームのポインタ前の行に戻せないの?(勘違いかも)
・配列をリング的に使う
でした。

テキストストリームのポインタ前の行に戻せない
と
思いこんで、深みにハマッタかもしれないし、
ホントに戻れないので、
今回みたいな小細工必要だったり、、、

そろそろDBかなぁやはり。

素朴な疑問あったら、気軽に、
メール、掲示板に書き込んでくださいね。

ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.24 2002/12/24
Split関数で配列作成、UBoundで個数の判断
[ページTOPへ戻る]
<Split関数で配列作成、UBoundで個数の判断>
こんにちは、Ken3です。

今回は、
Split関数で配列作成、
UBoundで個数の判断
をやってみたいと思います。

/*
 * 1.便利な関数あるんだね
*/
田舎者プログラマーKen3は、都会に在る便利な関数を知らなかった。
その1つがSplit関数かな。

英語得意じゃないので単語の本当の意味はわからないけど、
トランプのブラックジャックでSplitってルールがあって、
プレーヤーが、最初に賭けたチップと同額のチップを追加して賭け、
最初に配られた2枚のカードを2つの手に分けることができる

今回解説するのは、
文字列を区切り文字で分けて配列を作成する
Split関数だけど、頭の中でトランプ遊びとつながったのは不思議だった。
~~~~~~~~~

そんな話は、置いといて、

/*
 * 2.Split関数のサンプル
*/

簡単にサンプル書くと、

-- test024-1.asp
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>Split関数のサンプル</title>
</head>
<body>
<h2>Split関数のサンプル</h2>
test024-1.asp<br>
簡単にカンマで分けられたデータから配列を作ってみます<br>
<hr>
strBOX = Split("Ken3,ASP不得意,VBA少しできる", ",")<br>
と分解元文字列と区切り文字を渡すと、結果がstrBOXに配列で返ります。<br>
結果<br>
<%
    strBOX = Split("Ken3,ASP不得意,VBA少しできる", ",")  '配列データを作成
    Response.Write "strBOX(0) -- " & strBOX(0) & "<BR>"  '中身を表示
    Response.Write "strBOX(1) -- " & strBOX(1) & "<BR>"  '中身を表示
    Response.Write "strBOX(2) -- " & strBOX(2) & "<BR>"  '中身を表示
%>
<hr>
終了です。<br>

</body>
</html>
----

関数の使い方は、
^^^^^^^^^^^^^^
    strBOX = Split("Ken3,ASP不得意,VBA少しできる", ",")  '配列データを作成
と
分解元の文字列と区切り文字を渡すと、
    Response.Write "strBOX(0) -- " & strBOX(0) & "<BR>"  '中身を表示
    Response.Write "strBOX(1) -- " & strBOX(1) & "<BR>"  '中身を表示
みたいに、配列のデータとして値が返ります。

だから何?って感じだと思いますが、、、、

http://www.ken3.org/cgi-bin/test/test024-1.asp
で、サンプル実行できます。

/*
 * 3.UBoundで個数の判断
*/

strBOX = Split("Ken3,ASP不得意,VBA少しできる", ",")  '配列データを作成
と、
固定の文字列をバラしてました
が、
世の中、そんなに甘くないですよね、
ユーザーが入力した検索条件をバラして使用してる人達は、
どうしてるんだろうね?
入れられてから、はじめて区切り文字の個数がわかる場合は?

そんな時、便利なのが、
UBound(配列変数)
とやると、
配列のインデックス最大値(数)を返してくれるので、
組み合わせて使うと便利です。

フォームでスペースで区切られた条件を入力させ、
バラした結果を表示してみます。

-- test024-2.asp
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>SplitとUBoundのサンプル</title>
</head>
<body>
<h2>SplitとUBoundのサンプル</h2>
test024-2.asp<br>
<br>
<%  '頭で、入力パラメーターDATAがあるかチェックする
  If IsEmpty(Request.Form("DATA")) = True Then
        'そのまま下のHTMLフォームを実行
%>
    スペースで区切って好きな言葉を入れてください<br>
    <FORM ACTION="test024-2.asp" METHOD="POST">
      <INPUT TYPE="text" SIZE="40" NAME="DATA" VALUE="好き 嫌い 普通"><BR>
      <INPUT TYPE="submit" VALUE="分割実行">
      <INPUT TYPE="reset"  VALUE="クリア">
    </FORM>

<%
  Else 'データが入力されていたら、バラして表示する
      Dim strMOTO
      strMOTO = Request.Form("DATA")
      Response.Write "元のデータは、[" & strMOTO & "]です<br>"
      'スペースでデータをバラす
      strBOX = Split(strMOTO, " ")  '区切り文字にスペース指定
      'ループでデータを表示させる
      For i = 0 To UBound(strBOX)   'UBound使用インデックス最大値までループ
        Response.Write "<BR>"
        Response.Write "strBOX(" & i & ") -- "  '変数名表示
        Response.Write strBOX(i)                '中身を表示
      Next
  End If
%>
<hr>
終了です。<br>

</body>
</html>
----

軽く解説すると、

フォームからデータが来てるかチェックする
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<%  '頭で、入力パラメーターDATAがあるかチェックする
  If IsEmpty(Request.Form("DATA")) = True Then
        'そのまま下のHTMLフォームを実行
%>
いつのまにか好きになった関数IsEmptyでパラメータのチェックを行い、
無い時は(True)
下記のフォームで入力させる
    スペースで区切って好きな言葉を入れてください<br>
    <FORM ACTION="test024-2.asp" METHOD="POST">
      <INPUT TYPE="text" SIZE="40" NAME="DATA" VALUE="好き 嫌い 普通"><BR>
      <INPUT TYPE="submit" VALUE="分割実行">
      <INPUT TYPE="reset"  VALUE="クリア">
    </FORM>
ここのポイントは、
ACTION="test024-2.asp"
で、自分自身を呼んでるとこです
*自分の心の中でも意見が分かれるところで、
 HTMLの入力部とASPの処理部に分けたほうが派
 と
 今回みたいに、処理を1つにするか、、、

受け取ったデータを処理する
^^^^^^^^^^^^^^^^^^^^^^^^^^
<%
  Else 'データが入力されていたら、バラして表示する
      Dim strMOTO
      strMOTO = Request.Form("DATA")
      Response.Write "元のデータは、[" & strMOTO & "]です<br>"
で、まずパラメーターで受け取った元データを表示してます。

次に
      'スペースでデータをバラす
      strBOX = Split(strMOTO, " ")  '区切り文字にスペース指定
で、配列を作成してます。

ここがサンプルのポイント、
      'ループでデータを表示させる
      For i = 0 To UBound(strBOX)   'UBound使用インデックス最大値までループ
Forでループを作る時、
0からUBound(strBOX)までのループにしてます。
UBound(配列)が配列の最大インデックスなので、
0〜最後までのループが完成します。

あとは、
        Response.Write "<BR>"
        Response.Write "strBOX(" & i & ") -- "  '変数名表示
        Response.Write strBOX(i)                '中身を表示
      Next
こんな感じで、芸無く表示しました。

http://www.ken3.org/cgi-bin/test/test024-2.asp
でテストできます。
いろいろスペースで区切った文字を入れて、チェックしてください。

/*
 * 4.終わりの挨拶
*/

今回は、
・Splitで文字列を分解して配列作成
  ~~~~~
・UBoundで作成された配列の数を求めてループを作成
  ~~~~~~
でした。

そろそろDBかなぁやはり。
イヤ、まだまだ違うネタで、、、、

素朴な疑問あったら、気軽に、
メール、掲示板に書き込んでくださいね。

ASP、VBScript勉強中の三流プログラマーのKen3でした。



ページフッター リンクや広告、質問送信など

三流解説を読んでいただき、どうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。

まぁ、基本はデータの受け取りかなぁ。
・[Form等を使用したデータのやり取り]・・・ASPと言っても、HTMLの入力フォームからデータを受け取ります。POSTやGETでやりとりを押さえますか。

次は、データの入出力 で ADOを使った(ADOで接続) と SQLの解説を少々
・[ADOでMdbファイルを使う]・・・MDBと接続して、簡単な追加・更新・削除を行った。
・[ADOでExcelと接続してみた]・・・.xlsと接続してSQLを使ってみた。
・[ADOでCSVと接続してみた]・・・.CSV テキストを読み出した。※更新・削除はできません

DBが使えるので、あまり使用しないけど、普通のテキストファイル処理
・[テキストファイル処理]・・・ファイルを開いて、書き込む。1行読み込みなどを軽く

VBScriptでFormat関数が無いなど、微妙にVBAと違うけど
[VBScript関数関係の説明]・・・少し、処理を書いてみた。
[その他処理サンプル]・・・あまり良いサンプル作れなかったけど。。。
何かの参考となれば幸いです。

ニガテな環境設定系など
[Win2003 Server に IIS を Setup]・・・ポイントの無い、ほぼ一本道解説だけど。
[IIS 仮想ディレクトの作成とASP動作TEST]・・・Web拡張でASPを有効にしただけです。

Blog:[三流君の作業日記]/ [サンプルコードのゴミ箱]/ 広告-[通販人気商品の足跡]

質問や要望など メッセージを送る(三流君に連絡する)

質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。

あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



(感想や質問・要望 メッセージはHPで記事に載せることがあります。)


急ぎで連絡がほしい、そんな時は:[三流君連絡先アドレス]を見て連絡してください。



[三流君(TOP ken3.org へ戻る)] / [ASPで遊ぶ、失敗する] / [ASP記事 バックナンバー目次]