三流君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.55 〜 No.59


No.55 2003/05/22
And演算子を使う
[ページTOPへ戻る]

<And演算子を使う>

こんにちは、三流プログラマーのKen3です。 今回は、 読者から軽くメールもらったので、 ネタにしてみます。 拾い読みして、何かの参考となれば幸いです。

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

In message "re:[ASPで遊ぶ No.052] - キャラクタコード....", > 二年目プログラマーの西 ***です。 >> nCODE = Asc(Mid(strMOJI, n, 1)) 'n番目の文字コードを求める >> If nCODE >= 0 And nCODE <= 255 Then 'コードが1バイト文字内か? > > 三流だとAnd演算子も知らない?ありえねぇ〜 --- なんて、いつものクレーム?メールをいただきました。 本名でクレーム書いて来るって、潔いよね。 (実は本名じゃなかったりして、、、  西多摩雄とかニシタマオだったら相手にしないんだけど) そんな関係ない話は置いといて、

/* * 2.問題のコードとAnd演算子の使い方 */

'文字列を受け取り、バイト数を返す
Function Byte_Count(strMOJI)
  bcnt = 0
  '文字数分ループして、コードを表示
  For n = 1 To Len(strMOJI)
    nCODE = Asc(Mid(strMOJI, n, 1))  'n番目の文字コードを求める
    If nCODE >= 0 And nCODE <= 255 Then  'コードが1バイト文字内か?
      bcnt = bcnt + 1
    Else
      bcnt = bcnt + 2
    End If
  Next
  'リターン値をセットする
  Byte_Count = bcnt
End Function
指摘場所は、バイト数を計算している関数内の nCODE = Asc(Mid(strMOJI, n, 1)) 'n番目の文字コードを求める If nCODE >= 0 And nCODE <= 255 Then 'コードが1バイト文字内か? bcnt = bcnt + 1 Else bcnt = bcnt + 2 End If の場所ですね。 まぁ、 If nCODE >= 0 And nCODE <= 255 Then 'コードが1バイト文字内か? でも、動いているのですが、たぶん美的意識、美観的に良くない、 nCODE And &HFF00 とAnd演算子を使用してマスクしろって感じなんだろうなぁ。 えっ、Andって演算子だったの? そうですよ?知らなかった? nCODE >= 0 And nCODE <= 255 をわかり易くするために、まず()を付けます、 (nCODE >= 0) And (nCODE <= 255) (True) And (True) みたいに、演算してるんですね(論理演算だけど) And &hFF00とすることで、 上のビットを残し、下のビットを消すなんてことが出来るんですね。 If nCODE >= 0 And nCODE <= 255 Then 'コードが1バイト文字内か? を If (nCODE And &HFF00) = 0 Then 'コードは1バイトか? *asp055 みたいに書くことができます。 0以上で255(含む)より下か?とIf文を作成して、 1バイトか?判断するのもありだし、 FF00でAndして、判断するのもひとつの手なんですよ。 今回は、好みの問題ってことであまり実害は無いけど、 And演算子、頭のスミに入れて置いてください。 http://www.ken3.org/cgi-bin/test/test055-1.asp?DATA=Ken3%82%CD%8EO%97%AC で、And &HFF00バージョンの確認ができます。 ※同じく動作することを確認してみてください。

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

今回は、 And演算子の簡単な説明でした。 最近、ビット演算、、する機会、、、無いなぁとフト思いました。 素朴な疑問やリクエスト、今回みたいなクレームなどがあったら、 メール : qaqaqa@ken3.org 掲示板 : http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に気軽に書き込んでください。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.56 2003/05/23
Excel(*.xls)とADOで接続、.Addnewしてみた
[ページTOPへ戻る]

<Excel(*.xls)とADOで接続、.Addnewしてみた>

こんにちは、三流プログラマーのKen3です。 今回は、 Excel(*.xls)とADOで接続後、 レコードセット.Addnewでレコード追加、 rs.Fields("名前").Value = 値 rs.Fields(フィールド番号).Value = 値 とデータをセットして、 .Updateで更新 と 普通に操作してみます。 拾い読みして、何かの参考となれば幸いです。

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

No.53 ADOでExcelファイル(*.xls)とやっと接続できた(ほっ) http://www.ken3.org/backno/backno_asp11.html#53 で、 サーバーに置いた、*.xlsファイルに接続できたので、 読み込みが出来たら、書き込みでしょ、、 って流れで、 .AddNewでデータを追加してみたいと思います。

/* * 2.普通にAddNewで出来ないの? */

さてと、下記のような感じで、Excelファイルにアクセスできました。 http://www.ken3.org/cgi-bin/test/test053-1.asp 参照。 'ADO DB Recordset オブジェクトを作成する、英文そのままじゃん Set rs=Server.CreateObject("ADODB.Recordset") strSQL = "select * from DATA_RANGE" Con = "Driver={Microsoft Excel Driver (*.xls)};DBQ=" & _ Server.MapPath("test053.xls") & ";" Response.Write "作った、使った接続文字列は<br>" & Con & "<hr>" '接続文字列、SQLを渡して、レコードセットを開く Rs.Open strSQL, Con, 0 '0=adOpenForwardOnly strOUT = "" Do While Rs.EOF = False For Each FieA In Rs.Fields strOUT = strOUT & FieA.Name & " -- " & FieA.Value & "<BR>" Next Rs.MoveNext '次のレコードへ移動 Loop Rs.Close Set Rs = Nothing パターン的には、 '接続文字列、SQLを渡して、レコードセットを開く Rs.Open strSQL, Con, 0 '0=adOpenForwardOnly の 0=adOpenForwardOnlyを追加可能なカーソルにすればOKかなぁ。 カーソル関係の定数を見ると (ローカル内のadovbs.incを参照しました) '---- CursorTypeEnum Values ---- Const adOpenForwardOnly = 0 Const adOpenKeyset = 1 Const adOpenDynamic = 2 Const adOpenStatic = 3 となっているから、adOpenDynamic = 2にして、 '接続文字列、SQLを渡して、レコードセットを開く Rs.Open strSQL, Con, 2 .AddNew 'レコードセットの追加 としたけど、、、あれ、 ADODB.Recordset エラー '800a0cb3' オブジェクトまたはプロバイダは要求された操作を実行できません。 /cgi-bin/test/test056-1.asp, 行 31 あっ、ロックのタイプ、書いてないや '---- LockTypeEnum Values ---- Const adLockReadOnly = 1 Const adLockPessimistic = 2 Const adLockOptimistic = 3 Const adLockBatchOptimistic = 4 は、adLockOptimistic = 3を使用すればOKだろうと軽く考えて、 '接続文字列、SQLを渡して、レコードセットを開く Rs.Open strSQL, Con, 2, 3 Microsoft OLE DB Provider for ODBC Drivers エラー '80004005' [Microsoft][ODBC Excel Driver] 更新可能なクエリであることが必要です。 /cgi-bin/test/test056-1.asp, 行 36 えっ、なんで、、、更新可能じゃないの??? う〜ん。

/* * 3.接続できたら、あとは簡単と豪語してたのに(笑) */

接続できたら、あとは追加・更新・削除は簡単と豪語してたのに(笑) やばいなぁ。。。 得意の人様のHPを観察して、パクるか。 AccessからADOでExcelを更新するページ見ても、できてるよなぁ普通に使って。。。 こりゃ、ハマったかな(爆) で、マイクロソフトのサポートページを見ていて、 英語のページに紛れ込んだ。 http://support.microsoft.com/default.aspx?scid=kb;EN-US;314763 FIX: ADO Inserts Data into Wrong Columns in Excel The information in this article applies to: ActiveX Data Objects (ADO) 2.1 ActiveX Data Objects (ADO) 2.5 ActiveX Data Objects (ADO) 2.6 Microsoft OLE DB Provider for Jet 4.0 英語、読めないんだけど(情けないことに中学生以下じゃないたぶん(笑)) おっ、と思うソースが目に飛び込んできた。
Private Sub Command1_Click()
   Dim strCn As String
   Dim cn As ADODB.Connection
   Dim rs As ADODB.Recordset
   Dim fld As ADODB.Field

   'Open connection
   strCn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=" & App.Path & "\Test.xls;" & _
      "Extended Properties=Excel 8.0"
   Set cn = New ADODB.Connection
   cn.Open strCn
    
   'Add new values.
   Set rs = New ADODB.Recordset
   With rs
      .CursorLocation = adUseClient
      .Open "Select * from [Sheet1$]", cn, adOpenStatic, adLockOptimistic
      .AddNew
      .Fields("ColumnA").Value = 3
      .Fields("ColumnB").Value = 3
      .Fields("ColumnC").Value = ""
      .Fields("ColumnD").Value = 3
      .Fields("ColumnE").Value = 3
      .Fields("ColumnF").Value = "testing"
      .Update
      .Close
   End With
   Set rs = Nothing
   cn.Close
   Set cn = Nothing
End Sub
英語、読めなくても、ソースって意外と読めるもんなんですよね。 ※このサンプルソース、英語のコメントが無いのが良かったのかも これって、見るからに、Excelファイルに追加してる、そんな感じするよね(笑) 自分のソースとの違いを見る。 まず、接続の作り方が、いきなりレコードセットじゃなく、 'Open connection strCn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & App.Path & "\Test.xls;" & _ "Extended Properties=Excel 8.0" とADODB.Connectionを開いてから、 Set rs = New ADODB.Recordset With rs .CursorLocation = adUseClient .Open "Select * from [Sheet1$]", cn, adOpenStatic, adLockOptimistic .AddNew と、レコードセットを開いて、.Addnewしてる。 .CursorLocation = adUseClient ってなんだ? 定数のファイル(ローカル内のadovbs.incを参照しました) を見てみると、 '---- CursorLocationEnum Values ---- Const adUseServer = 2 Const adUseClient = 3 となっていて、 adUseClientの上に、adUseServer? 英語わからない、私でも、これって?サーバーの指定?かもと予想。 これを参考にして、 訪問者の時刻、IPアドレス、端末情報を保存するサンプルを作ってみました。 Excelファイルのフォーマットと名前の定義は、 ↑みたいに作成しました。 <%@LANGUAGE=VBScript%> <html> <head> <title>Excel(*.xls)とADOで接続、.Addnewしてみた</title> </head> <body> <h2>Excel(*.xls)とADOで接続、.Addnewしてみた</h2> <!-- Ken3 --><!-- #include file="info.inc" --> test056-1.asp<br> ASPからADOを使用してExcel(*.xls)と接続して、<br> .AddNewでレコードを追加する。<br> <hr> <% '---- CursorTypeEnum Values ---- Const adOpenForwardOnly = 0 Const adOpenKeyset = 1 Const adOpenDynamic = 2 Const adOpenStatic = 3 '---- LockTypeEnum Values ---- Const adLockReadOnly = 1 Const adLockPessimistic = 2 Const adLockOptimistic = 3 Const adLockBatchOptimistic = 4 '---- CursorLocationEnum Values ---- Const adUseServer = 2 Const adUseClient = 3 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '接続文字列 strCon = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & Server.MapPath("test056.xls") & ";" & _ "Extended Properties=Excel 8.0" Response.Write "接続文字列は<br><b>" Response.Write strCon & "</b><br>です<br>" 'データベース(xls)を開く db.open strCon Response.Write "その次はレコードセット<br>" 'ADO DB Recordset オブジェクトを作成する、英文そのままじゃん Set rs=Server.CreateObject("ADODB.Recordset") rs.CursorLocation = adUseServer 'カーソルはサーバーの指定 Response.Write "Select * from FIELD_RANGE, db, 〜<br>" rs.Open "Select * from FIELD_RANGE", db, adOpenStatic, adLockOptimistic Response.Write "開いたレコードセットに対して.AddNew<br>" rs.AddNew Response.Write "フィールドにアクセスする<br>" '↓フィールド名でアクセス rs.Fields("F_HIZUKE").Value = Now() rs.Fields("F_IP").Value = Left(Request.ServerVariables("REMOTE_ADDR"), 9) '↓番号でアクセスも出来るよ rs.Fields(2).Value = Request.ServerVariables("HTTP_REFERER") rs.Fields(3).Value = Request.ServerVariables("HTTP_USER_AGENT") Response.Write ".Updateで更新(レコード確定)<br>" rs.Update Response.Write "rs.Close でレコードセットを閉じる<br>" rs.Close Set rs = Nothing 'オブジェクト変数を開放する Response.Write "db.Close でxlsとの接続を閉じる<br>" db.Close Set db = Nothing 'オブジェクト変数も開放する %> <hr> 時刻、IPアドレス(頭から9文字)ユーザーのブラウザ情報を書き込みました<br> [<a Href="test056.xls" TARGET="_blank">書き込んだtest056.xlsを開く</a>]<br> ↑書き込まれたデータの確認<br> </body> </html> テストは、 http://www.ken3.org/cgi-bin/test/test056-1.asp で、可能です。 アクセスすると、ログ情報をtest056.xlsに書き込みます。 アクセス後、Excelファイルをダウンロードして、 データが追加されていることを確認してみてください。

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

今回は、 簡単に.Addnewの解説、、と行きたかったけど、 ハマってしまった、、なんて情けないお話でした(三流プログラマーらしいよね) and 英語読めないのに、ソースは読める不思議な自分に気がついて、変な気分。 ※で、調子に乗ってマイクロソフトの英語サイト読んだけど、よくわかんなかった(笑) 私の失敗談が、 ASPからADOを使用して、Excelファイルに書き込む そんな処理の参考となれば幸いです。 テストは、 http://www.ken3.org/cgi-bin/test/test056-1.asp で、可能です。 素朴な疑問やリクエスト、今回みたいなクレームなどがあったら、 メール : qaqaqa@ken3.org 掲示板 : http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に気軽に書き込んでください。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.57 2003/05/26
Excelグラフ付の雛形シートにASPからADOを使用してデータセット
[ページTOPへ戻る]

<Excelグラフ付の雛形シートにASPからADOを使用してデータセット>

こんにちは、三流プログラマーのKen3です。

今回は、
グラフ付のExcelファイルとADOで接続後、
データをセット(更新)
そのExcelファイルをダウンロードさせます。

拾い読みして、何かの参考となれば幸いです。

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

No.53 ADOでExcelファイル(*.xls)とやっと接続できた(ほっ) http://www.ken3.org/backno/backno_asp11.html#53 で、 サーバーに置いた、*.xlsファイルに接続でき、 No.56 Excel(*.xls)とADOで接続、.Addnewしてみた http://www.ken3.org/backno/backno_asp12.html#56 で、 Excelの表にデータを追加することが出来ました。 そしたら、今度は更新でしょう ってことで、一週間分のログを日別に集計して、 Excelの表を更新してみます。 .AddNewの時、.Updateも使っているので、 普通の表だと面白みに欠けるので、 グラフ付のExcelファイルに書き込んでみます。

/* * 2.まずは、雛形ファイルの用意 */

A列 B列 C D列 日付 訪問者数 2001/1/1 10 2001/1/2 20 2001/1/3 30 横棒グラフを 2001/1/4 40 シートとリンクさせて作成 2001/1/5 50 雛形を作成。 2001/1/6 60 2001/1/7 70 2001/1/8 80 作成イメージは ↑みたいに作成しました。 今回は、名前の定義は作らないで、 DATA!A2:B9 みたいに指定してみたいと思います。

/* * 3.訪問者をSQL文で集計する */

ログファイルから日付別に集計するのは、 http://www.ken3.org/cgi-bin/test/test040-1.asp でやったSQL文を流用して、 Select Format(WriteTime, 'YYYYMMDD') AS YYYYMMDD, Count(*) AS CNT From log  GROUP BY Format(WriteTime, 'YYYYMMDD') を使用して、日付別に集計します。 集計値を配列に入れて、それをエクセルにセットする方法を取ります。 いきなり動作したソース載せちゃうけど、 http://www.ken3.org/cgi-bin/test/test057-1.asp でテスト可能です。ポイントの解説は下のほう見てください。 <%@LANGUAGE=VBScript%> <html> <head> <title>Excel(*.xls)グラフ付雛形にADOで接続しデータ更新</title> </head> <body> <h2>Excel(*.xls)グラフ付雛形にADOで接続しデータ更新</h2> <!-- Ken3 --><!-- #include file="info.inc" --> test057-1.asp<br> ASPからADOを使用してExcel(*.xls)と接続して、<br> .Updateでレコードを更新する。<br> <hr> <% '---- CursorTypeEnum Values ---- Const adOpenForwardOnly = 0 Const adOpenKeyset = 1 Const adOpenDynamic = 2 Const adOpenStatic = 3 '---- LockTypeEnum Values ---- Const adLockReadOnly = 1 Const adLockPessimistic = 2 Const adLockOptimistic = 3 Const adLockBatchOptimistic = 4 '---- CursorLocationEnum Values ---- Const adUseServer = 2 Const adUseClient = 3 '配列変数に集計値をまず入れます。 Dim PageCNT(10) '8個でいいんだけど Dim dHIZUKE(10) 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '接続DBの位置は、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("cnt.mdb") db.open 'やっとデータベースを開ける 'FORMAT関数を使用して、テーブル名logからデータを集計する 'SQL文を発行する strSQL = "Select Format(WriteTime, 'YYYY/MM/DD') AS YYYYMMDD, Count(*) AS CNT" strSQL = strSQL & " From log" strSQL = strSQL & " Where WriteTime >= #" & DateAdd("d", -7, Date) & "#" strSQL = strSQL & " GROUP BY Format(WriteTime, 'YYYY/MM/DD')" 'オマケで画面にデータ表示 Response.Write "<hr>発行する(した)SQL文は<br><B><font color='green'>" Response.Write strSQL & "</font></B><br>です<hr>" Set rs = db.Execute(strSQL) 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しをバカっぽく、そのまま書き込む Response.Write "<TR>" Response.Write "<TD>NO.</TD>" Response.Write "<TD>日付</TD>" Response.Write "<TD>閲覧ページ数</TD>" Response.Write "</TR>" 'EOFまでループ nCNT = 1 Do While rs.EOF = False '.EOFがFalseの間 Response.Write "<TR>" '内容を表示する Response.Write "<TD>" & nCNT & "</TD>" Response.Write "<TD>" & rs.Fields("YYYYMMDD") & "</TD>" Response.Write "<TD ALIGN='RIGHT'>" & rs.Fields("CNT") & "</TD>" Response.Write "</TR>" & Chr(13) & Chr(10) '配列変数に日付、カウント値を代入 dHIZUKE(nCNT) = rs.Fields("YYYYMMDD") PageCNT(nCNT) = rs.Fields("CNT") '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 'カウンタを増やす nCNT = nCNT + 1 Loop Response.Write "</TABLE><HR>" 'テーブルは終わりです 'お行儀よくオブジェクトも開放しましょう '今回同じ名前を使いまわしてみます、開放すれば大丈夫でしょう rs.Close '開いていたレコードセットを閉じる Set rs = Nothing db.Close 'データベースも閉じようよ Set db = Nothing '--------------------- 'ここからExcel側の処理 '--------------------- 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '接続文字列作成、test057.xlsを指定する strCon = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & Server.MapPath("test057.xls") & ";" & _ "Extended Properties=Excel 8.0" Response.Write "ExcelとのADO接続文字列は<br><b>" Response.Write strCon & "</b><br>です<br>" 'データベース(xls)を開く db.open strCon Response.Write "その次はレコードセット<br>" 'ADO DB Recordset オブジェクトを作成する、英文そのままじゃん Set rs=Server.CreateObject("ADODB.Recordset") rs.CursorLocation = adUseServer 'カーソルはサーバーの指定 Response.Write "Select * from [DATA$A1:B9], db, 〜<br>" rs.Open "Select * from [DATA$A1:B9]", db, adOpenStatic, adLockOptimistic Response.Write "開いたレコードセットに対して.MoveFirst<br>" rs.MoveFirst '先頭へ(A2:B2の行) Response.Write "ループで配列からフィールド(セル)へセット<br>" 'ループ For n = 1 To 8 '当日+一週間の7日で8回まわる rs.Fields(0).Value = dHIZUKE(n) rs.Fields(1).Value = PageCNT(n) rs.Update '更新 rs.MoveNext '次のレコードへ(次の行へ) Next Response.Write "rs.Close でレコードセットを閉じる<br>" rs.Close Set rs = Nothing 'オブジェクト変数を開放する Response.Write "db.Close でxlsとの接続を閉じる<br>" db.Close Set db = Nothing 'オブジェクト変数も開放する %> <hr> 集計値をtest057.xlsへ書き込みました<br> [<a Href="test057.xls" TARGET="_blank">書き込んだtest057.xlsを開く</a>]<br> ↑書き込まれたデータの確認、グラフ付はOKか確認する<br> </body> </html> ポイント解説 ~~~~~~~~~~~~ あまりポイントは、無いんだけど、 '接続文字列作成、test057.xlsを指定する strCon = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & Server.MapPath("test057.xls") & ";" & _ "Extended Properties=Excel 8.0" 接続までは、スムーズでした。 で いつものようにハマったのは、データエリアの指定です。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 回答を先に出してしまうけど、 Response.Write "Select * from [DATA$A1:B9], db, 〜<br>" rs.Open "Select * from [DATA$A1:B9]", db, adOpenStatic, adLockOptimistic と from [DATA$A1:B9]で指定すると、 シートの範囲をレコードセットにできます。 ※名前の範囲無くても使用できるので、意外と便利ですね 初め書いた書き方は(失敗例その1は) rs.Open "Select * from DATA!A2:B9", db, adOpenStatic, adLockOptimistic この書き方だと、 Microsoft JET Database Engine エラー '80040e14' FROM 句の構文エラーです。 /cgi-bin/test/test057-1.asp, 行 121 ちっ、また調べるのかよ(笑) http://www.microsoft.com/japan/msdn/columns/office/office10052000.asp がMSのページです。※よかった日本語だよ。 Excel Link Excel ワークブックへのリンク オブジェクト 構文 ワークシート sheetname$ 名前付き範囲 rangename 名前付きではない範囲 sheetname$rangeaddress えっと、この3種類が使えるなら、 DATA$A2:B9でいいのか、この位置に$は違和感あるけど、仕様なんでしょう。 !はエクセルのセル上の慣れてる書き方だったか。 rs.Open "Select * from [DATA$A2:B9]", db, adOpenStatic, adLockOptimistic で勝負。(失敗例その2) ADODB.Field エラー '800a0bcd' ~~~~~~~~~~~ BOF と EOF のいずれかが True になっているか、 または現在のレコードが削除されています。 要求された操作には、現在のレコードが必要です。 オイオイ、 あらら、まだダメなの、、、 ADODB.Field エラー? ~~~~~~~~~~~ あっ、フィールドかぁ、 A2:B9これってデータエリアで、見出しの行含んでないや。 これで、フィールド名が取れないのかな、もしかして。 rs.Open "Select * from [DATA$A1:B9]", db, adOpenStatic, adLockOptimistic と見出しの行を含ませたら、やっと動作しました。 ※意外と単純なミス?でした。。。  でも、エラーメッセージ、フィールド名が不明とか、  わかりやすく出してほしいよね......  えっ、そんなミスするのは三流君だけ??? あとは、ループで頭から配列変数からフィールドにデータをセット、 その後、.Updateで更新しました。 rs.MoveFirst '先頭へ(A2:B2の行) Response.Write "ループで配列からフィールド(セル)へセット<br>" 'ループ For n = 1 To 8 '当日+一週間の7日で8回まわる rs.Fields(0).Value = dHIZUKE(n) rs.Fields(1).Value = PageCNT(n) rs.Update '更新 rs.MoveNext '次のレコードへ(次の行へ) Next 余計な話なので、聞き流してほしいけど、 ADOって .Edit メソッドで編集状態に フィールド代入 フィールド代入 .Update メソッドでレコード確定 の流れじゃないのね。 DAOのクセで.Edit使ってたけど、 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Microsoft VBScript 実行時エラー エラー '800a01b6' オブジェクトでサポートされていないプロパティまたはメソッドです。: 'Edit' /cgi-bin/test/test057-1.asp, 行 128 .Editってメソッドは無いです。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

今回は、 ・Excelの雛形シートにASPからデータをセット ・Select Form [シート$範囲]でExcelの指定範囲をレコードセットに指定 ・指定範囲の先頭行にはフィールド名を指定するんだよ ・ADOには、.EDITメソッドは無いんだよ って話でした サクサクと、作成が進むと思ったのですが、 簡単な処理でもハマりました。 私の失敗談が、 ASPからADOを使用して、Excelファイルに書き込む そんな処理の参考となれば幸いです。 今回のグラフ付雛形シートにデータセット、 http://www.ken3.org/cgi-bin/test/test057-1.asp でテスト可能です。 素朴な疑問やリクエスト、今回みたいなクレームなどがあったら、 掲示板 : http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に気軽に書き込んでください。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.58 2003/05/29
復習、#Include,FileSystemObject,乱数ランダム
[ページTOPへ戻る]

<復習、#Include,FileSystemObject,乱数ランダム>

こんにちは、三流プログラマーのKen3です。 今回は、 復習を兼ねて、 #Include File で、ファイルをインクルードする FileSystemObjectでテクストファイルの読み込み処理、 乱数でランダムな数値を発生 なんて感じのネタをやってみたいと思います。 拾い読みして、何かの参考となれば幸いです。

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

テキスト広告のローテーションを作ってみたくて(笑) いろいろと試行錯誤した結果を兼ねて、ASP系のネタにしてみました。

/* * 2.#Include File で、ファイルをインクルードする */

ASPと言っても、通常は、HTML内に<% 〜 %>でスクリプトを埋め込んでます。 a.asp <% ASP の処理A %> <html> <head> </head> <body> ヘッダ部分に目次へのリンクなど 本文 <% ASP の処理B %> フッダ、広告など <% ASP の処理C %> </body> </html> <% ASP の処理D サブルーチンなど %> まぁ、書き方のキレイさ(見易さなど) 位置によっていろいろとあるのですが、 こんな感じです。 大体、HPを作成する時、構成を決めます。 ---- 上部 HPタイトルと目次、掲示板へのリンク、、 本文があって 下部 リンクを書く人や小金稼ぎのバナー広告 ---- まぁ、わかりやすく、こんな構成だとします。 すると、上部のHTMLと下部のHTMLは変わらないんですね。 なので、ひとつの方法は、雛形のHTMLファイルを作っておいて、 それを別名でコピーして修正する、そんな方法です。 ※私も使ってます。 この方法でも良いのですが、 2・3ヶ月たってくると、広告を差し替えたいなぁ、 新しいカテゴリできたので、タイトルにリンクを増やしたい・・・ と共通だったはずのヘッダ、フッダを修正する時があります。 そんな時に便利な方法が、 #Includeを使ってASPを作る方法です。 使い方は簡単で、 <!-- #Include File="info.inc" --> と外部から挿入したいファイルを書くだけです。 具体的な使い方は、 <%@LANGUAGE=VBScript%> <html> <head> <title>ASP #Include File="xxxx.inc" でファイルをインクルード</title> </head> <body bgcolor=#ffffff text=#000000> <!-- #Include File="info.inc" --> <!-- ↑ヘッダの共通イメージをインクルード --> <h2>ASP #Include File="xxxx.inc" でファイルをインクルード</h2> test058-1.asp<br> #Include File="xxxx.inc"とファイルをインクルードして、<br> 共通のヘッダ、フッダを使う<br> <hr> [<a Href="info.inc" TARGET="_blank">info.incを開く</a>] ←使用したヘッダファイル<br> [<a Href="inc_mokuji.inc" TARGET="_blank">inc_mokuji.incを開く</a>] ←使用したフッダファイル<br> <!-- #include file="inc_mokuji.inc" --> <!-- ↑フッダの共通イメージをインクルード --> </body> </html> ポイントは、 ~~~~~~~~~~~~ <!-- #Include File="info.inc" --> ↑ヘッダの共通イメージをインクルード <!-- #include file="inc_mokuji.inc" --> ↑フッダの共通イメージをインクルード なんだぁ、一行単純に書いてるだけなのね(笑) この単純に書いた一行の処理にしていると、 ヘッダやフッダのイメージを変えたい時は、 http://www.ken3.org/cgi-bin/test/info.inc http://www.ken3.org/cgi-bin/test/inc_mokuji.inc といったファイルの中身を変更するだけで、 実行時に読み込まれるので、表示内容を変更することが出来ます。 http://www.ken3.org/cgi-bin/test/test058-1.asp でテストできます。イメージを確認してください。

/* * 3.ランダムにローテーションバナーを表示させたい */

さてと、 #Include File を使うと、実行時にファイルを挿入可能なことがわかりました。 一歩進んだ要求だと(そんな要求私だけかもしれないけど) ランダムでバナー広告を切り替えて表示したい。 なんて、思うかもしれません。 乱数かぁ、、、 Randomize '乱数系を初期化 nNO = Int(Rnd * 10) で0〜9までの数を発生させられるので、 インクルードするファイルを http://www.ken3.org/cgi-bin/inc/hed0.inc http://www.ken3.org/cgi-bin/inc/hed1.inc http://www.ken3.org/cgi-bin/inc/hed2.inc   ・   ・ http://www.ken3.org/cgi-bin/inc/hed9.inc とバーナー広告を10種類用意しておいて、 切り替えてインクルードしてみたいです。 <% '頭で乱数の発生 Randomize '乱数系を初期化 nNO = Int(Rnd * 10) '0〜9までの乱数を発生させる strFNAME = "/cgi-bin/inc/hed" & nNO & ".inc" 'ファイル名を作る %> とファイル名を作ってから、 <!-- #include file="<%=strFNAME%>" --> で勝負、、あれれ、 Active Server Pages エラー 'ASP 0126' インクルード ファイルが見つかりません /cgi-bin/test/test058-2.asp, 行 22 インクルード ファイル '<%=strFNAME%>' が見つかりませんでした。 あっ、バカみたい、””で囲って文字列にしてるよ、 よし、””をはずして、 <!-- #include file=<%=strFNAME%> --> Active Server Pages エラー 'ASP 0126' インクルード ファイルが見つかりません /cgi-bin/test/test058-2.asp, 行 22 インクルード ファイル 'strFNAME' が見つかりませんでした。 できないのかなぁ、 まぁ、インクルードファイルが動的に切り替わる、、 なんて用途ないしね。 自分でファイルを開いて読みますか、 <% '自分でファイルを読む ' FileSystemObjectを生成します Set objFS = Server.CreateObject("Scripting.FileSystemObject") ' strFNAMEを読取専用モードで開きデータを読む Set ts = objFS.OpenTextFile(Server.MapPath(strFNAME), 1, True) Do While ts.AtEndOfStream = False 'ファイルの終端になってない間ループ strDATA = ts.ReadLine 'ファイルからデータを一行を読む Response.Write strDATA Response.Write vbCRLF '改行する Loop '使ったファイルは閉じようよ ts.close Set objFS = Nothing %> と素直に、テキストファイルを開いて1行読み込み、出力しました。 http://www.ken3.org/cgi-bin/test/test058-2.asp でテストできます。イメージを確認してください。 ポイントは ~~~~~~~~~~ 乱数の発生前に、 Randomize '乱数系を初期化 で 乱数系の初期化。 nNO = Int(Rnd * 10) strFNAME = "/cgi-bin/inc/hed" & nNO & ".inc" 'ファイル名を作る でファイル名を作ったら、 しかたなく自分でFileSystemObjectを生成して、 .ReadLineで一行読み込む、.AtEndOfStreamでファイルの終端チェック でした。

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

今回は、 ・インクルードファイルの使い方 ・乱数の発生 ・テキストファイルをFileSystemObjectで読み込み、インクルードもどき って話でした サクサクと、作成が進むと思ったのですが、 簡単な処理でもハマりました。 広告、切り替えても押されないよ(笑) http://www.ken3.org/cgi-bin/test/test058-1.asp http://www.ken3.org/cgi-bin/test/test058-2.asp でテスト可能です。 何かの参考となれば幸いです。 素朴な疑問やリクエスト、クレームなどがあったら、 掲示板 : http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に気軽に書き込んでください。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.59 2003/06/02
結果をExcelで返すならresponse.ContentType=application/vnd.ms-excel
[ページTOPへ戻る]

<結果をExcelで返すならresponse.ContentType=application/vnd.ms-excel>

こんにちは、三流プログラマーのKen3です。 今回は、 ASP Excel 系を探っていたら、 また新たに、 response.ContentType response.buffer = true response.flush response.end なんてサンプル拾ってきたので、 ネタにしてみたいと思います。 拾い読みして、何かの参考となれば幸いです。

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

なかなか、ASPでExcelの処理、ADO使ってごまかしたけど、 他に方法無いか?模索中です。 そしたら、マイクロソフトのHPから、おっ?と思うサンプルを拾う。

/* * 2.拾ったサンプル */

http://msdn.microsoft.com/library/en-us/dnwebteam/html/webteam07032000.asp ちっ、ここも英語かよ、日本語のサンプルは無いの? それとも日本語化される前に、ASP.NETになっちゃったの? なんて前置きは置いといて、 いつもの台詞で、英語読めないけどプログラムソースはなぜか読める そんな三流プログラマーが下記のソースを拾ってきた。 ※ページの下のほうに転がってました <%@ language=vbscript %> <% response.buffer = true response.ContentType = "application/vnd.ms-excel" response.AddHeader "content-disposition", "inline; filename=dynamic.xls" response.write "<table width=200>" response.write "<tr>" for i = 1 to 4 response.write "<td width=40>" response.write i + i response.write "</td>" next response.write "<td width=40><b>=sum(A1:D1)</b></td>" response.write "</tr>" response.write "</table>" response.flush response.end %> なにやら、 response.ContentType = "application/vnd.ms-excel" response.AddHeader "content-disposition", "inline; filename=dynamic.xls" とExcel処理の匂いがプンプン。 夏の女性の匂いに引き付けられないで、サンプルの匂いに魅かれてちゃダメだよ。 ここで、私がもしかしたら使えるのかも?と思ったのが、 response.write "<td width=40><b>=sum(A1:D1)</b></td>" と、セルの集計関数の=Sumを使っている場所。 データだけならCSV経由でサーバーから落として、 あと好きなように加工してね、、とやるんだけど、 もし=Sumなどワークシート関数使えるなら、 結果をASPからExcelで返す時、いろいろと使えるのでは? で、上記ソースをまるごとコピーして、実行してみました。 http://www.ken3.org/cgi-bin/test/test059-1.asp で実行できます。 すると、いつものxlsファイルを開く、保存の警告メッセージ。 ってことは、Excelのファイルとして認識? ※↑メッセージ画面 開くを選択して、開いてみると、=SUMの計算式が埋まっていた。 ※↑開いたイメージ。

/* * 3.拾ったサンプルを解析して自分のものにする */

さてと、そんな方法でExcelファイルを返すことが出来たので、 拾ったサンプルを自分のものにするために、 わからないことを探りますか。 response.buffer = true を調べると、 response.buffer = true の時は、出力をバッファして、 response.flush 途中でバッファを出力 response.end  ASPの処理を中止し、現在までの結果を返すのかぁ。 なるほどね。 関連項目として、今回出てこなかったけど、 response.clear ってのがあって、バッファに格納された出力をクリアすることが出来ます。 このクリアを使って、エラーが発生したら、途中までの出力を消して、 エラーのメッセージ画面を表示することも出来そうです。 ※また注意事項として、  response.buffer = trueは、<Html>などの出力の前に行うことです。  まぁ、出力のバッファだから、一番最初にやれってことね。 次は、 response.ContentType = "application/vnd.ms-excel" これは、今から送るデータのタイプは、 "application/vnd.ms-excel" ですよ、とブラウザに教えるために書きます。 response.ContentType = "imge/gif" など、指定します。 文字データだけじゃなくて、ASPでいろいろと出来るんだね、、と感じた。 response.AddHeader "content-disposition", "inline; filename=dynamic.xls" これは、詳しく載っていなかったけど、 動作や.AddHeaderから判断すると、ヘッダ情報にファイル名を載せている感じです。 response.write "<table width=200>" response.write "<tr>" ↑この、Excelファイルなのに、普通のテーブルってのが不思議だけど、 for i = 1 to 4 response.write "<td width=40>" response.write i + i response.write "</td>" next TDだから、横に数値を書き込んで、 response.write "<td width=40><b>=sum(A1:D1)</b></td>" ここが一番感動した、 =Sum とワークシート関数を入れている部分です。 普通にテーブルイメージなんですね。 response.write "</tr>" 行の終了、 response.write "</table>" テーブルの終了 response.flush バッファを出力 response.end ASP終了 って流れでした。

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

今回は、 あまり自分のものに出来てないけど、 ・出力バッファの制御 ・response.ContentType = "application/vnd.ms-excel"でExcelファイルを返す ・普通にテーブルのタグでOK ・response.write "<td width=40><b>=sum(A1:D1)</b></td>"と関数も使用可能 って話でした 何かの参考となれば幸いです。 ※ASPでWebのシステムって奥が深そう、、なんて言ってて、  もう時代はASP.NETになってくるのかぁ・・・ 素朴な疑問やリクエスト、クレームなどがあったら、 掲示板 : http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に気軽に書き込んでください。 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記事 バックナンバー目次]