三流君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.90 〜 No.94 バックナンバー

目次:
[No.90 ADO CSVで先頭行にフィールド名が無い時]
[No.91 ADO CSVでReadOnly=0と.AddNewを使いデータ追加]
[No.92 FORM SELECTタグのOPTION値を受け取って処理を行う]
[No.93 FORM CHECKBOXから受け取った値を使用してWHERE句の作成]
[No.94 2進数文字列と16進文字列の変換処理に挑戦]

No.90 2004/01/07
ADO CSVで先頭行にフィールド名が無い時
[ページTOPへ戻る]

<ADO CSVで先頭行にフィールド名が無い時>

こんにちは、三流プログラマーのKen3です。 今回は、 ADOのCSV接続で、先頭行に項目名(フィールド名)が無い時の接続、 そんなお話です。 http://www.ken3.org/cgi-bin/group/asp_ado_csv.asp に、 関連項目ASPでADO CSV接続の他のサンプルもあるので、合わせて見てください。

/* * 1.今回のキッカケ */

質問フォームより、下記の質問をもらいました。 ----- ASPからADO接続出来るなんて知りませんでした。 今回、CSVファイル内を検索してヒットした行をHTML表示する用件があったので、凄く 参考になりました。 1点質問があります。 今回のCSVファイルには1行目にヘッダ情報があるので、条件を指定できましたが、当方 のCSVファイルはヘッダ情報の無いデータのみになってますので、全件検索しか出来ま せんでした。 ヘッダ情報が無いCSVファイルに対して条件追加をした場合の項目名(列名)記述方法を ご存知であればご教示願います。 ----- ご教示かぁ・・・この言葉は嫌いなんだよねぇ〜 と いつもの関係ないことから入って、 自分でもわからなかったので探ってみました。

/* * 2.1行目にヘッダ情報が無いCSVファイル(先頭行にフィールド名無し) */

1行目にヘッダ情報が無いCSVファイルかぁ。 テストデータで下記のデータを作成しました。 test090.csv 9-99999999999,CSVのヘッダーを無くして見た,Ken3,100,2004/1/06 4-8399-0986-5,CPUの創りかた,毎コミ,2800,2003/9/30 4-8399-0997-0,速効!図解 ホームページ・ビルダー7,毎コミ,1280,2003/3/13 ・   ・ ・ 4-8222-0785-4,信頼されるSEの条件,日経BP出版センター,1700,2003/3/13 4-89311-450-6,よくわかる Microsoft Word2002ドリル,FOM出版,1000,2002/4/10 4-407-05082-9,30時間でマスター Word&Excel2002,実教出版,857,2002/3/28 普通に接続すると、勝手に 9-99999999999やCSVのヘッダーを無くして見たをフィールド名にしてくれる(笑) これだとイヤなので(イヤじゃなくて使えないので) Googleで、 Microsoft Text Driver csv ADO をキーワードにしてwebを検索する。 いろいろとでてくるのですが、 http://dbforums.com/arch/212/2003/7/855889 を見ると、 "Driver={{Microsoft Text Driver (*.txt; *.csv)}}; MaxBufferSize=2048; DBQ=C:\\Temp; DriverId=27; Format=TABDELIMITED" or "Driver={{Microsoft Text Driver (*.txt; *.csv)}}; MaxBufferSize=2048; DBQ=C:\\Temp; DriverId=27; Format=Delimited(:)" なんて書いてある。 これ予想だけど、Format=Delimited(:)で区切り記号も指定できそう。 ほかにパラメータないのかなぁ? http://dbforums.com/arch/43/2003/1/582349 には、 mConn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)}; DBQ=" & mFilePath & ";Extended Properties='text;HDR=NO';Extensions=asc,csv,tab,txt;Persist Security Info=False" HDR=NO ^^^^^^ おっ、これってヘッダーぽくない? 英語読めないので、続きの探索を打ち切る。 ※ヘッダーをHDR=NOにして、自分でフィールド名を指定したいけど、  そこまで探せなかった(打ち切るなんて書いてるけど、探せなかっただけ(笑)) よし、英語読めないなら、中国語でしょう?(オイオイ) http://www.csdn.net/Develop/article/16%5C16955.shtm oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _           "Data Source=c:\somepath\;" & _           "Extended Properties=""text;HDR=Yes;FMT=Delimited;"";" でも、可能みたいですね。 これを参考にして、下記の接続文字列を作成してみた。 '接続情報の作成 ドライバーの指定と、DBQには、パスのみを指定する Con = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & Server.MapPath(".") & ";" & _ "Extended Properties=""text;HDR=No;FMT=Delimited;"";" '↑MapPathに(".")を渡し、カレントディレクトリを渡す 最大のポイントは、 ^^^^^^^^^^^^^^^^^^ "Extended Properties=""text;HDR=No;FMT=Delimited;"";" のパラメータを接続情報に含めたことです。(HDR=Noとしてます) あとは、全てを読むテストのSQL文 'SQLのテーブル名には、ファイル名test090.csvを指定します。 strSQL = "select * from test090.csv" を作成して、 '接続文字列、SQLを渡して、レコードセットを開く rs.Open strSQL, Con, 0 '0=adOpenForwardOnly と、レコードセットを作り、 見出しとデータを下記のような感じで、画面に出してみました。 '見出しを(フィールド名を)そのまま書き込む Response.Write "<TR>" For Each fld_A In rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TH>" & fld_A.Name & "</TH>" '←.Nameでフィールド名 Next Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '内容を表示する For Each fld_A In rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '←.Valueでフィールドの値 Next Response.Write "</TR>" rs.MoveNext '次のレコードに移動する Loop 実際のテストは、 http://www.ken3.org/cgi-bin/test/test090-1.asp で、実行できます。(ソースの全ても見れます。) 実行すると、先頭行をデータとして扱い、 F1,F2と自動でフィールド名を付けてくれてます。

/* * 3.自動で付けられる予定のF1,F2のフィールド名を条件に出来るか? */

おっと、質問は、条件を指定して、検索したかっただよね。 接続文字列は、下記のように作って、 '接続情報の作成 ドライバーの指定と、DBQには、パスのみを指定する Con = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & Server.MapPath(".") & ";" & _ "Extended Properties=""text;HDR=No;FMT=Delimited;"";" '↑MapPathに(".")を渡し、カレントディレクトリを渡す SQL文でF1やF2を使用してみます。 データの並びは、 4-8222-0785-4,信頼されるSEの条件,日経BP出版センター,1700,2003/3/13 F1 F2 F3 F4 F5 なので、 F3の出版社=日経BP出版センターのデータを探す 'SQLのテーブル名には、ファイル名test090.csvを指定します。 strSQL = "select * from test090.csv" strSQL = strSQL & " Where F3 = '日経BP出版センター'" '↑F3の出版社の項目を条件にしてデータをWhereで絞り込む と、F3フィールドに対して、条件を付けてみました。 http://www.ken3.org/cgi-bin/test/test090-2.asp で、テスト実行できます(全てのソースもここで見れます)

/* * 4.終わりの挨拶 </HTML> */

今回は、 先頭行に項目名が無い、そんなCSVファイルに対して、 ADOを使用して、接続してみました。 いろいろと問題点や疑問点を残しつつ、脱線・寄り道の多いメルマガですが、 今後とも、よろしくお願いします。 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.91 2004/01/14
ADO CSVでReadOnly=0と.AddNewを使いデータ追加
[ページTOPへ戻る]

<ADO CSVでReadOnly=0と.AddNewを使いデータ追加>

こんにちは、三流プログラマーのKen3です。 今回は、 ADOのCSV接続で、 ReadOnly=0と.AddNewを使いデータを追加してみた そんなお話です。 http://www.ken3.org/cgi-bin/group/asp_ado_csv.asp に、 関連項目ASPでADO CSV接続の他のサンプルもあるので、合わせて見てください。

/* * 1.今回のキッカケ */

特に無いんだけど、 CSVの更新と削除は、 Microsoft OLE DB Provider for ODBC Drivers エラー '80004005' [Microsoft][ODBC Text Driver] この ISAM では、 リンク テーブル内のデータを削除することはできません。 と、怒られてました。 では、追加(ファイルの後ろにAppendの追記)はできるかなぁ〜 と あまり使わないかも的な処理を書いてみました。 ※普通に追加なら、FileSystemObjectで追加していけば通常はOKなのですが、  強引にネタとしてしまいました。

/* * 2.開き方のポイント ReadOnly=0なんてパラメータあったよ */

さてと、データを追加するのかぁ。 追加だから、 '接続文字列、SQLを渡して、レコードセットを開く rs.Open strSQL, Con, adOpenStatic, adLockOptimistic で、開こうとすると ADODB.Recordset エラー '800a0bb9' 引数が間違った型、または許容範囲外であるか、競合しています。 /cgi-bin/test/test091-1.asp, 行 44 あららダメかぁ・・・ Const adOpenStatic = 3 '---- CursorTypeEnum Values ---- で、開けないんですね・・・ そんなこんなで、失敗が続き、調べてみると、 http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B316475 ↑xlsの例みたいですが、 cn.Open "Driver={Microsoft Excel Driver (*.xls)};DBQ=C:\MyDoc.xls;ReadOnly=0;" とあって、 おっ? ReadOnly=0なんてパラメータあったよ ^^^^^^^^^^ こんどは、ReadOnly=0で調べると、 ReadOnly=0 (更新可能) ReadOnly=1 (更新不可、リードオンリー) となっている。(ReadOnly=True/Falseとは書けないのかなぁ?) 接続文字列を下記のように作成しました。 '※接続情報の作成 ドライバーの指定と、DBQには、パスのみを指定する Con = "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" _ & Server.MapPath(".") & ";" _ & "ReadOnly=0;" で、開く時は、レコードセットを作成して、 'ADO DB Recordset オブジェクトを作成する、英文そのままじゃん Set rs=Server.CreateObject("ADODB.Recordset") rs.CursorLocation = adUseServer 'カーソルはサーバーの指定 'SQLのテーブル名には、ファイル名を指定します(test091.csvを指定) strSQL = "select * from test091.csv" '接続文字列、SQLを渡して、レコードセットを開く rs.Open strSQL, Con, adOpenDynamic, adLockOptimistic と、SQLを渡して作成してみました。 ※rs.CursorLocation = adUseServer 'カーソルはサーバーの指定  は、無くてもOKでした(あとで気が付きました)

/* * 3..AddNewでデータを追加してみた */

接続が出来たら(レコードセットが作成できたら) 今度はレコードを追加してみたかったので、 .AddNewでデータを追加してみます。 ファイル名はtest091.csvで、データは,カンマで区切られてます。 FID,書き込み時刻,IP情報,Reffer の4つの項目をCSVで管理してみます。 このASP(test091-1.asp)が実行されたら、 test091.csvと接続後、 最終行にカーソルを移動(.Movelast)してFID+1の次の番号を計算。 .Addnew後、 IPアドレスの頭10桁とReferrer(どこからきたか)をフィールドにセットして、 .Updateで更新してみます。 実際のテストは、 http://www.ken3.org/cgi-bin/test/test091-1.asp で、実行できます。(ソースの全ても見れます。) まずは、 接続・レコードセットの作成です ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '※接続情報の作成 ドライバーの指定と、DBQには、パスのみを指定する Con = "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" _ & Server.MapPath(".") & ";" _ & "ReadOnly=0;" 'SQLのテーブル名には、ファイル名を指定します(test091.csvを指定) strSQL = "select * from test091.csv" 'ADO DB Recordset オブジェクトを作成する、英文そのままじゃん Set rs=Server.CreateObject("ADODB.Recordset") rs.CursorLocation = adUseServer 'カーソルはサーバーの指定 '接続文字列、SQLを渡して、レコードセットを開く rs.Open strSQL, Con, adOpenDynamic, adLockOptimistic ここまでで、なんとかCSVと接続しました。 ポイントは、接続文字列のReadOnly=0です。 最後の番号を取得したいので、 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '最終のデータを取得する rs.MoveLast 'レコードを最終行へ移動 NEXT_NO = Cint(rs.Fields("FID").Value) + 1 '次の番号を+1して計算する .MoveLastで最終行に移動後、.Fields("FID").Valueの値に+1して、 次の連番を作成しました。 データを.AddNewで追加する ^^^^^^^^^^^^^^^^ rs.AddNew rs.Fields("書き込み時刻").Value = Now() rs.Fields("FID").Value = NEXT_NO '次の番号をセットする '↓番号でフィールドにアクセスも出来るよ rs.Fields(2).Value = Left(Request.ServerVariables("REMOTE_ADDR"), 10) rs.Fields(3).Value = Request.ServerVariables("HTTP_REFERER") Response.Write ".Updateで更新(レコード確定)<br>" rs.Update rs.Close 'クローズして確定する ここも、ポイントは特に無いのですが、 rs.Fields("書き込み時刻")やrs.Fields("FID") と、フィールド名で指定する方法と rs.Fields(2)やrs.Fields(3)のように、フィールドの番号で指定する方法、 どちらも使えます。 データをセットしたら、 .Update で データを確定してます (忘れても、.Closeやカーソル移動で自動確定されるけど) http://www.ken3.org/cgi-bin/test/test091-1.asp で、テスト可能なので、遊んでみてください(ソースの全ても見れます。)

/* * 4.終わりの挨拶 </HTML> */

今回は、 ADOを使用して、CSVと接続、データを追加してみました。 ※ADOで接続が面倒、これなら、FileSystemObjectで追加したほうが楽。  と、判断材料に使ってもらえればうれしいです。 いろいろと問題点や疑問点を残しつつ、脱線・寄り道の多いメルマガですが、 今後とも、よろしくお願いします。 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.92 2004/01/22
FORM SELECTタグのOPTION値を受け取って処理を行う
[ページTOPへ戻る]

<FORM SELECTタグのOPTION値を受け取って処理を行う>

こんにちは、三流プログラマーのKen3です。 今回は、 処理を分解して考えましょう、事例を探したり、単体テストしましょう SELECTタグのOPTION値を受け取って処理を行う そんなお話です。

/* * 1.今回のキッカケ */

掲示板に下記の書き込みをいただきました。 ------------ >内容としまして、プルダウンメニューとチェックボックスのある >フォームでのデータ表示(テーブル)検索についてなのですが > >例えばデータはtest.mdbでmachineテーブル >フィールドはそれぞれ >ID:オートナンバー >M_name:A,B,C,D,E,F >M_number:1,2,3,4 >M_coments:コメント >です。 > >メインのフォームに >プルダウンメニュー(M_nameのA,B,C,D,E,F)と >チェックボックス4つ(M_numberの1,2,3,4)があります。 >※M_nameのアルファベットとM_numberの数字はそれぞれtest.mdb上 >に複数(重複)存在します。 > >そこで検索例としまして >「A」が"1"でそれぞれフォームで選択&チェックし、”表示” >ボタンでフォーム下にテーブルとしてデータを表示したいと >思い投稿させて頂きました。 >ちなみにチェックボックスは必須ではありません。 >チェックが無いときは、プルダウンメニューで選択したフィールド >(A,B,C,D,E,F)の全フィールドを表示させるみたいに・・・と >言う感じです。 --------------- 前回の質問の処理も中途半端の尻切れトンボだったのに、 この回答者(Ken3)はダメだ頼りにならないと思われてもしかたない状態で、 再度チャンスが来たので、汚名挽回したいですね。 ※なんて思いつつ、今回の回答もキレが無いんだけど

/* * 2.処理を分解して考える */

社内ツールや自分が使うツールだと、 設計書を書かないで、要求だけ聞いて(目的だけ自分で考えて) 作り始めると思います。 が、最低限、入力と出力のイメージを書いておきます。 >メインのフォームに >プルダウンメニュー(M_nameのA,B,C,D,E,F)と >チェックボックス4つ(M_numberの1,2,3,4)があります。 FORMで入力された SELECTタグの値 と CHECKBOXタグの値 を 受け取るのかぁ。 そして、SQL文を作成して、データの表示ですね。 SQL文の作成では、 チェック無しの時は、全てのデータを表示(全てにチェックと同様に扱う) が注意ポイントかなぁ。 プログラムは流用だぁ〜 と 言えるくらい自分の記憶やライブラリ、社内資産がまとまっていれば楽なんだけど、 分解した処理で、自分がやったことが無い、そんな箇所をチェックしたり、 似ている処理を探したり、社内事例を検索する(webで事例を集めたりする) ※裁判で弁護士が過去の判例を検索して、被告の状況と比べる感じと似てるかなぁ。

/* * 3.FORM SELECT タグのデータを受け取る */

自分のライブラリを見ると、チェックボックスの事例は、 No.45 HTML FORM INPUT TYPE="CHECKBOX" チェックボックスの入力 http://www.ken3.org/backno/backno_asp10.html#45 で簡単な解説、 http://www.ken3.org/cgi-bin/test/test045-1.asp で、実際にCHECKBOXを使用したテストを行ってます。 あれれ、SELECTのタグのサンプル無いよ(笑) ありそうで無かったんだなぁ。 だからSELECTタグってなんだよ。 ^^^^^^^^^^^^^^^^ あっ、HTMLのFORMでプルダウンの選択を書く時のタグです。 <br> あなたの好きなパリーグの球団は? <SELECT name="pl"> <option value="lions">西武</option> <option value="buffaloes">近鉄</option> <option value="hawks">ダイエー</option> <option value="marines">ロッテ</option> <option value="fighters">日本ハム</option> <option value="bluewave">オリックス</option> </SELECT><br> こんな感じで、SELECTとOPTIONのタグで構成されてます。 option value=""だとどうなるのか少し興味があったので、 あなたの好きなセリーグの球団は? <SELECT name="cl"> <option value="">特に無しorわからない</option> <option value="1">阪神</option> <option value="2">中日</option> <option value="3">ヤクルト</option> <option value="4">巨人</option> <option value="5">広島</option> <option value="6">横浜</option> </SELECT><br> で、""特に無しを設定してみました。 FORMの入力と受け取ったデータを表示するサンプルを http://www.ken3.org/cgi-bin/test/test092-1.asp で、書いてみます。(ソースの全ても見れます。) 実際にテストしてみてください。

/* * 4.値を受け取りSQLを発行する */

入力関係のテストが終了したので、 今度は、受け取った値を使用して、DBからデータを表示してみます。 <FORM ACTION="test092-2.asp" METHOD="POST"> <font color="blue">SELECT OPTION の 入力(選択) TEST</font><br> <SELECT name="KUBUN"> <option value="">全てのデータ</option> <option value="ASP">ASPのデータ</option> <option value="VBA">VBAのコメント</option> <option value="GUCHI">愚痴系</option> <option value="24H">24Hコンビニ</option> </SELECT> <INPUT TYPE="submit" VALUE="検索する"> </FORM> で、SELECT name="KUBUN"とデータを送り、 'KUBUNが送られてきたかチェックする strKUBUN = Request.Form("KUBUN") If Len(strKUBUN) <> 0 Then 'KUBUNが在りの時(0文字以上の時) 'KUBUNを条件にWHERE句を作る strWHERE = "Where F_KUBUN = '" & strKUBUN & "' " Else '条件無しの時は、空白にしておく srrWHERE = " " End If 手抜きで、””の場合と送られてこなかった場合を判断するために、 Len関数で文字数が0以外かをチェックして、 WHERE句を作ってみました。 あとは、普通に、 'SQL文を作成する strSQL = "Select * From KANSOU " '感想(KANSOU)テーブルから全項目(*) strSQL = strSQL & strWHERE strSQL = strSQL & "ORDER BY WriteTime DESC" '並べ替えは時間の降順 で、SQL文を組み立ててみました。 http://www.ken3.org/cgi-bin/test/test092-2.asp でテストできます。(ソースの全ても見れます。)

/* * 5.終わりの挨拶 </HTML> */

今回は、 SELECTタグで入力(選択)したデータを受け取るサンプルでした。 次回は、チェックボックスと組み合わせて使ってみたいと思います。 いろいろと問題点や疑問点を残しつつ、脱線・寄り道の多いメルマガですが、 今後とも、よろしくお願いします。 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.93 2004/01/22
FORM CHECKBOXから受け取った値を使用してWHERE句の作成
[ページTOPへ戻る]

<FORM CHECKBOXから受け取った値を使用してWHERE句の作成>

こんにちは、三流プログラマーのKen3です。 今回は、 FORM CHECKBOXから受け取ったデータ を使用して、WHERE句を作成してみます。 ※いろいろなパターンが考えられるのでお好きなやつで。  (みなさんの丸秘テクニックがあったら、教えてください)

/* * 1.今回のキッカケ */

入力フォームのチェックボックスでチェックされた値の使用方法を見直したいなぁ〜 と 思い、今回の発行となりました。 SQLのWHERE句を数パターン作ったので、参考になれば幸いです。

/* * 2.名前(name="xxx")が一緒のパターンと違うパターン */

自分のライブラリを見ると、チェックボックスの事例は、 No.45 HTML FORM INPUT TYPE="CHECKBOX" チェックボックスの入力 http://www.ken3.org/backno/backno_asp10.html#45 で簡単な解説をしてますが、 TYPE="CHECKBOX"で name="xxxx"が違うパターン <INPUT TYPE="CHECKBOX" NAME="c1">HTMLから詳しく丁寧に<BR> <INPUT TYPE="CHECKBOX" NAME="c2" VALUE="VBScript">VBScriptをもっと詳しく<BR> <INPUT TYPE="CHECKBOX" NAME="c3" VALUE="GAME">ゲーム作ろうよ<BR> name="xxxx"が同じパターン <INPUT TYPE="CHECKBOX" NAME="kibou" VALUE="HTML">HTMLから詳しく丁寧に<BR> <INPUT TYPE="CHECKBOX" NAME="kibou" VALUE="VBScript">VBScriptをもっと詳しく<BR> <INPUT TYPE="CHECKBOX" NAME="kibou" VALUE="GAME">ゲーム作ろうよ<BR> 実際に、 http://www.ken3.org/cgi-bin/test/test045-1.asp で、テストすると、 c1,c2,c3と違う場合はそれぞれ、 c1 on (Value=設定無し) c2 VBScript (Value="VBScript"と値を指定) など、 チェックした値をRequest.Form("c1")など項目別に取得することができます。 NAME="kibou"と各チェックボックスの名前が同じ場合は、 Request.Form("kibou")の共通の項目名で取得すると、 Valueで指定した値がVBScript, GAMEとカンマで区切られて取得できます。

/* * 3.TYPE="CHECKBOX"でname="xxxx"が違うパターン */

値の受け渡しがなんとなくわかったので、 TYPE="CHECKBOX"でname="xxxx"が違うパターン で Where句を作成してみます。 入力は、 □VBA,□ASP,□24H,□GUCHI と区分をチェックさせチェックありのデータをWhere句でor指定して取り出します。 <INPUT TYPE="CHECKBOX" NAME="ASP">ASP<br> <INPUT TYPE="CHECKBOX" NAME="VBA">VBA<br> <INPUT TYPE="CHECKBOX" NAME="24H">コンビニ系<br> <INPUT TYPE="CHECKBOX" NAME="GUCHI">愚痴系<br> と、NAME=の部分を4つ作成して、フォームを作りました。 ア.Ifの連続でWHERE句を作成してみた ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ オマエ何年プログラマーやってんの?  と  読者の心の声が聞こえる書き方で、WHERE句を作成すると、 'WHERE句を作成する strWHERE = "" '条件を初期化する '4つの区分をそれぞれ判断する If Request.Form("VBA") = "on" Then 'VBAの判断 If strWHERE = "" Then strWHERE = " Where KUBUN='VBA' " Else strWHERE = strWHERE & " Or KUBUN='VBA'" End If End If If Request.Form("ASP") = "on" Then 'ASPの判断 If strWHERE = "" Then strWHERE = " Where KUBUN='ASP' " Else strWHERE = strWHERE & " Or KUBUN='ASP'" End If End If If Request.Form("24H") = "on" Then '24Hの判断 If strWHERE = "" Then strWHERE = " Where KUBUN='24H' " Else strWHERE = strWHERE & " Or KUBUN='24H'" End If End If If Request.Form("GUCHI") = "on" Then 'GUCHIの判断 If strWHERE = "" Then strWHERE = " Where KUBUN='GUCHI' " Else strWHERE = strWHERE & " Or KUBUN='GUCHI'" End If End If 'SQL文を作成する (作成したWHERE句を組み合わせる) strSQL = "Select * From KANSOU " '感想(KANSOU)テーブルから全項目(*) strSQL = strSQL & strWHERE strSQL = strSQL & "ORDER BY WriteTime DESC" '並べ替えは時間の降順 こんな感じかな。  テストは、 http://www.ken3.org/cgi-bin/test/test093-1.asp で、実行できます。(カスイ 工夫無しのソースの全てもここで見れます。) ポイントは、If文でRequest.Form("xxxx")それぞれの区分がonかチッェクして、  さらに前の条件が無ければWHERE あれば or にしただけです。  なんの工夫も無い、よく見かけるプログラムですよね。 イ.同じ処理なんだからループで回そうよ さてと、みっともないプログラムを見せてしまいましたね。  お口直しのデザートじゃないのですが、 ArrayとUboundで項目名を管理して、同様のWhere句を作成してみました。 'WHERE句を作成する strKUBUN = Array("VBA", "ASP", "24H", "GUCHI") '区分を配列にする strWHERE = "" '条件を初期化する '区分の数だけループさせる For n = 0 To Ubound(strKUBUN) If Request.Form(strKUBUN(n)) = "on" Then '区分n番目の項目がonか? If strWHERE = "" Then '初めの項目か?チェックする strWHERE = " Where F_KUBUN='" & strKUBUN(n) & "' " Else '2番目以降はorでつなぐ strWHERE = strWHERE & " Or F_KUBUN='" & strKUBUN(n) & "' " End If End If Next 'SQL文を作成する (作成したWHERE句を組み合わせる) strSQL = "Select * From KANSOU " '感想(KANSOU)テーブルから全項目(*) strSQL = strSQL & strWHERE strSQL = strSQL & " ORDER BY WriteTime DESC" '並べ替えは時間の降順  テストは、 http://www.ken3.org/cgi-bin/test/test093-2.asp で、実行できます。(少し工夫したソースの全てもここで見れます。) ポイントは、Array("VBA", "ASP", "24H", "GUCHI") で項目名の配列作成 For n = 0 To Ubound(strKUBUN)で0番目からループを作成して、  あとは、Request.Form(strKUBUN(n))やstrKUBUN(n)と使用しただけです。  少しはまとまったし、項目増やすだけで変更対応も容易になりました。 まぁ、なんだかんだ言っても、 If Request.Form("ASP") = "on" If Request.Form(strKUBUN(n)) = "on" など、項目単位にチェックして、Where句を作る方法でした。

/* * 4.TYPE="CHECKBOX"でname="xxxx"を同じにしてVALUE=を区分とする */

個別にチェックする方法はどうでしたか? 次は、name="KUBUN"と同一にしてValueの値を使ってみます。 入力は、 □VBA,□ASP,□24H,□GUCHI と区分をチェックさせまでは一緒ですが(見た目は一緒) NAME="KUBUN"にしてVALUE="XXXX"を下記のように指定してみます。 <INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="ASP">ASP<br> <INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="VBA">VBA<br> <INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="24H">コンビニ系<br> <INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="GUCHI">愚痴系<br> と、VALUE=の部分を4つ作成して、フォームを作りました。 ウ.Replaceで途中のカンマを置き換え WHERE IN句を使用する Request.Form("KUBUN")とすると、 選択された項目がVBA, 24Hとカンマとスペースで区切られて渡ります。 これを利用して、 VBA, 24H を WHERE F_KUBUN IN ('VBA','24H') と、IN句で条件を作ってみます。 'WHERE句を作成する strKUBUN = Request.Form("KUBUN") 'フォームから区分を受け取る If strKUBUN = "" Then '区分が選択されていなかったら strWHERE = "" 'データ無しの時は条件をカラにする Else ',を変換してWHERE句を作成する ' ASP, 24Hの文字を", "(カンマとスペース1つ)を','に変換する strWORK = Replace(strKUBUN, ", ", "','") '置き換える strWHERE = " Where F_KUBUN IN ('" & strWORK & "') " End If http://www.ken3.org/cgi-bin/test/test093-3.asp でテストできます。(ソースの全ても見れます。) ポイントは特に無く、 ", "(カンマとスペース1つ)を','にReplace関数を使って変換してみました。 エ.Request.Form(xxx).Countで複数チェック  いろいろと探っていた副産物なのですが、 If Request.Form("KUBUN").Count > 0 Then '項目数をチェック  と、.Countで同じNAMEで送られて来たデータの個数を取得できます。  それと同時に、 項目名Name="KUBUN"と同一のデータが送られてきたときに、  Request.Form("KUBUN")(1) や Request.Form("KUBUN")(2) とすると、個別に値を取得することが出来ます。  ※(1)からデータが始まります。  ※※(0)にはVBA, 24Hとカンマ区切りの値が格納されています。  これを利用して、 'WHERE句を作成する If Request.Form("KUBUN").Count > 0 Then '項目数をチェック '複数の時、1番目(最初の条件をまず代入) strWHERE = " Where F_KUBUN = '" & Request.Form("KUBUN")(1) & "' " '次の条件((2)から)をループで追加する For n = 2 To Request.Form("KUBUN").Count 'Orで条件をつなげる strWHERE = strWHERE & " Or F_KUBUN = '" & Request.Form("KUBUN")(n) & "' " Next Else strWHERE = "" 'データ無しの時は条件をカラにする End If http://www.ken3.org/cgi-bin/test/test093-4.asp でテストできます。(ソースの全ても見れます。) ポイントは、Request.Form("KUBUN").Countで1以上の時はデータありと判断。  まず、一番目を代入して、 " Where F_KUBUN = '" & Request.Form("KUBUN")(1) & "' " 頭のWhereを付けて作成。  あとは、ループで2番目から数分ORを頭につけて作成してみました。 ※Orで条件をつなげたけど、Where INで書くなら、下記のようにしてください strWHERE = " Where F_KUBUN IN ('" & Request.Form("KUBUN")(1) & "'" '次の条件((2)から)をループで追加する For n = 2 To Request.Form("KUBUN").Count 'Orで条件をつなげる strWHERE = strWHERE & ",'" & Request.Form("KUBUN")(n) & "'" Next strWHERE = strWHERE & ")" '最後忘れずに)で閉じてね。

/* * 5.終わりの挨拶 </HTML> */

今回は、 CHECKBOXの値を使って、複数の条件を受け取り、 WHERE句を作成する方法を数パターン書いてみました。 自分にあった方法を使ってみてください。 次回は、 やっと質問の処理、プルダウンとチェックボックスの組み合わせをやってみます。 いろいろと問題点や疑問点を残しつつ、脱線・寄り道の多いメルマガですが、 今後とも、よろしくお願いします。 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.94 2004/06/05
2進数文字列と16進文字列の変換処理に挑戦
[ページTOPへ戻る]

<2進数文字列と16進文字列の変換処理に挑戦>

こんにちは、三流プログラマーのKen3です。 今回は、 2進数文字列と16進文字列の変換処理に挑戦してみます。

/* * 1.今回のキッカケ */

文字コードなどの変換で、16進数から2進文字列を作りたかったので、 自作してみました。 意外とハマりました。 16進数 F2 を 11110010 など、2進数の文字列に直したい。 逆に 10100011 を A3 にしたい、 と 質問をもらった。

/* * 2.16進数文字列を2進数文字列に直す */

いろいろとやり方があるのですが、8421で計算してみました。 0 --> 0000 1 --> 0001 2 --> 0010 3 --> 0011 ・   ・ 9 --> 1001 A --> 1010 B --> 1011 など、変換表を作成しておいて、置きかえる方法もあるし、 2で割っていったり計算で求めたりとイロイロとありますが、 三流君らしい、下記のサンプルを作ってみました。 処理のポイントは、 F3などの16進文字列から1文字取出します。 Fを取出します。でもこれは文字なので数値に変換したいです。 そこで a = CInt("&H" & "F") と、文字列から数値変換の標準関数Cintを使い、 変換します。 ここから、さらに一工夫して、ビットが8 4 2 1 となっているので、 まずF(15) で、8が立っているか調べるために and 演算しました。 If (nCHK And n8421) = 0 で判断してます。 次は4を調べるので/2で割って、4回、まわしてます(小細工) これで、ビットを調べて0と1の文字列を作成してます。 http://www.ken3.org/cgi-bin/test/test094-1.asp?DATA=F2 でテスト実行できます。 ソースは下記で、回しながら処理を行ってます。 <% 'HEX16進文字列を受け取り2進数文字列を返す
Function HEX16toSTR2(strHEX)

    Dim n       'ループカウンタ
    Dim i       'ループのカウンタ
    Dim n8421   '8 4 2 1の数値計算用
    Dim str2STR 

    Dim nCHK

    str2STR = ""  '結果のエリアを初期化する

    '文字数分ループする
    For n = 1 To Len(strHEX)
        nCHK = CInt("&h" & Mid(strHEX, n, 1)) 'n文字目を数値変換
        n8421 = 8  '初期値に8を代入する(上からチェックしたいので)
        For i = 1 To 4  '4回まわるよ
            If (nCHK And n8421) = 0 Then 'Andでビットをチェックする
                str2STR = str2STR & "0"  'ビットは立ってないよ
            Else
                str2STR = str2STR & "1"  'ビットは立ってるよ
            End If
            '次のビットをチェックしたいので2で割る
            n8421 = n8421 / 2
        Next 
    Next

    'リターン値をセットして終了
    HEX16toSTR2 = str2STR

End Function
%>
※G5など、16進数に無い表記だとエラーが発生してしまうが、  それなりに動作してます。エラーチェック入れねば・・・

/* * 3. 2進数文字列を16進数文字列に直す */

今度は、逆で、1010をAに変換する番です。 1010 これは、8+2です。 えっなんで? 8 4 2 1 と 4つをポイントにビットが立っていたら計算してます。 そんな感じのサンプルが下記のサンプルです。 ポイントは、 0と1を判断して、8 4 2 1の順で数値を+して行き、 4つ単位でHEX関数で、16進に変換してます <% '2進文字列を受け取り16進文字列を返す
Function STR2toHEX16(str2)

    Dim strHEX
    Dim n       'ループカウンタ
    Dim i       'ループのカウンタ
    Dim n8421   '8 4 2 1の数値計算用
    Dim nBYTE

    strHEX = ""   '結果のエリアを初期化する

    '文字数分ループする
    For n = 1 To Len(str2) Step 4  '4文字(1バイト)単位にループを作る
        n8421 = 8  '初期値に8を代入する(上から計算したいので)
        nBYTE = 0  '1バイト計算用変数を初期化
        For i = 0 To 3  '4回まわるよ(4ビット分)
            'ビットが立っているかチェックする
            If Mid(str2, n + i, 1) = "1" Then
                nBYTE = nBYTE + n8421   'ビットに対応した数値を+する
            End If
            '次のビットを計算したいので2で割る
            n8421 = n8421 / 2
        Next 
        '計算して、1倍との数値が完成したので16進文字にしてセットする
        strHEX = strHEX & Hex(nBYTE)
     Next 

     'リターン値をセットして関数を抜ける
     STR2toHEX16 = strHEX

End Function
%>
上から順番にビットをチェックしていき、8421の順で繰り返してます。

/* * 4.データが4ビット単位じゃないとバグるよ */

なんとか、出来たと思いつつ、バグを発見。 4つ単位でデータが作られればいいけど、 頭の0を省略します。 0111と書いてほしいんだけど、 111なんてデータがくると、 私の処理だと違う数値に変換してしまいます。 後ろからみる や 桁数のチェック なんてエラー処理、確認処理が必要です。 ア.初めに桁をチェックする 問題なのが、 111と3桁の2進数文字列が来ると、8+4+2をやってしまいます。 0111と送られてくれば、4+2+1で7と計算されるのに。 とするなら、強引に、3桁111を4桁0111にしてしまうそんな処置を足してみました。 '頭4文字単位かチェックする n = Len(str2) Mod 4 '足りない文字数を計算する If n <> 0 Then str2 = String(4 - n, "0") & str2 '頭に文字0を追加する End If 2進数文字列を受け取りHEX16進文字列を返す(頭0を+する) http://www.ken3.org/cgi-bin/test/test094-2.asp?DATA=111 で、テストできます。(無事7と表示されるか、、、) イ.後ろから計算してみる。 問題なのは、111を頭から4桁と決め付けて8+4+2を+してるからだろ だったら、後ろから、1+2+4+8+16+32+64...で計算しろよ、 と、考え方を変えたのが下記の変換プログラムです。 2進数文字列を受け取りHEX16進文字列を返す(頭0を+する) http://www.ken3.org/cgi-bin/test/test094-3.asp?DATA=111010 で、テストできます。(6桁の11 1010を変換すると3Aとなるはず?) <% '2進文字列を受け取り16進文字列を返す(後ろからチェック)
Function STR2toHEX16_B(str2)

    Dim strHEX
    Dim n       'ループカウンタ
    Dim i       'ループのカウンタ
    Dim n8421   '8 4 2 1の数値計算用
    Dim nBYTE

    strHEX = ""   '結果のエリアを初期化する
    n8421 = 1  '初期値に1を代入する(下から計算したいので)
    nBYTE = 0  '計算用変数を初期化

    '文字数分ループする
    For n = Len(str2) To 1 Step -1  '後ろからループを作る
        'ビットが立っているかチェックする
        If Mid(str2, n + i, 1) = "1" Then
            nBYTE = nBYTE + n8421   'ビットに対応した数値を+する
        End If
        '次のビットを計算したいので*2で計算 1.2.4.8.16.32...としたい
        n8421 = n8421 * 2
    Next

    '計算して、数値が完成したので16進文字にしてセットする
    strHEX = Hex(nBYTE)

    'リターン値をセットして関数を抜ける
    STR2toHEX16_B = strHEX

End Function
%>
処理のポイントは、 文字列を後ろから見るために、逆順のループを作ってみました。 For n = Len(str2) To 1 Step -1 '後ろからループを作る で、次のポイントが、 '次のビットを計算したいので*2で計算 n8421 = n8421 * 2 2進数は*2で次の位が求められるので、単純にカケテ次の位を計算してます。 If Mid(str2, n + i, 1) = "1" Then nBYTE = nBYTE + n8421 'ビットに対応した数値を+する End If あとは、ビットが立っていたら+しているだけです。 最後はHEX関数で、変換しただけです。 こんな感じで、プログラムを一から見直して、作成してみました。

/* * 5.終わりの挨拶 </HTML> */

今回は、 2進数文字列と16進数文字列の変換処理を少しやってみました。 もっと効率の良いやり方があると思いますが、 1つの参考例になれば幸いです。 いろいろと問題点や疑問点を残しつつ、脱線・寄り道の多いメルマガですが、 今後とも、よろしくお願いします。 何かの参考となれば幸いです。 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:[三流君の作業日記]/ [サンプルコードのゴミ箱]/ 広告-[通販人気商品の足跡]



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