ASP Tips
MENU
■TOPへ戻る - BLUE-TRANSPARENCY〜限りなく透明に近いブルー〜
■決まりごと
決まり文句(Option Explicit)
■データベース(DB)
DB接続
DB使用時の文字化けを回避
■ストアドプロシージャ(SP)
ストアドプロシージャの実行引数の指定レコードセットの取得方法
ストアドプロシージャの実行からアウトプットの取得方法(return含む)
レコードセットとアウトプットの両方の取得方法
■エクセル(Excel)
テーブルタグをエクセルで開く
エクセルで改行しない。(テーブルタグで改行しない)
エクセルに画像を張る方法
■ブラウザ(IE)
複数ブラウザとセッションについて
ブラウザのタイムアウト防止処理(SPの非同期実行とパケット送信)
■変数
アプリケーション変数のロック
Session変数・application変数の一覧表示
IPアドレスの取り方(環境変数の取得)
■文字列
ループ内での文字列連結(A = A & B) は遅い
■ヌル(null)
A = null & "a" はnull
■ページ遷移
ページ遷移(Response.Redirect)
■クラス(class)
class(クラス)ステートメント
■レスポンスバッファー(Respons.Buffer)
Response.Buffer(一気に送信するかどうか)
■文字化け
文字化けの回避
■サブミット
Enterキーを押すと勝手にサブミットする現象を阻止
■停止
ASP、SPは途中でとまるのか?(送信ボタンを連続で押したとき等)
■テーブル(table)
tableを隠す方法
Request("ID")という参照はダメ
■その他
思ったこと
参考文献

■決まりごと
決まり文句(Option Explicit)
ASPの最初で宣言。
Option Explict '変数の宣言を強制する。
On Error Resume Next 'エラーが起きても終了しない。(デバッグ時はつけないほうがよい)

■データベース(DB)
DB接続
'------------------------------------------
'データベース接続用文字列を定義します。
------------------------------------------

Const DB_PROVIDER = "SQLOLEDB" 'OLE DB Provider
Const DB_DATASOURCE = "TEST_SERVER" 'データベースサーバ名
Const DB_USERID = "sa" 'SQLサーバユーザID
Const DB_PASSWORD = "" 'SQLサーバパスワード
Const DB_INITIALCATALOG = "TEST_DB" 'データベース名(ストアドプロシージャ用)

Dim DB_CONNECT_STR 'DB接続用文字列

DB_CONNECT_STR = "Provider=" & DB_PROVIDER & _
"; Data Source=" & DB_DATASOURCE & _
"; User ID=" & DB_USERID & _
"; Password=" & DB_PASSWORD & _
"; Initial Catalog=" & DB_INITIALCATALOG & ";"

'------------------------------------------
'DBに接続します。
'------------------------------------------
'Connectionオブジェクト作成 - 定型
Dim objConnection
Set objConnection = Server.CreateObject("ADODB.Connection")
objConnection.ConnectionTimeout = 0 'タイムアウト値
objConnection.Open DB_CONNECT_STR

If err.number<>0 Then 'DB接続失敗
 'DBの接続時にエラーが発生した場合は、
 '接続を閉じエラーページへ飛ぶなどする。
 objConnection.close
 Set objConnection = Nothing
 Response.Redirect( "Error_DB.asp" )
Else
 '何か処理をする。
 'ストアドプロシージャの実行
 'レコードセットの取得など

 '------------------------------------------
 'DBの切断
 '------------------------------------------
 objConnection.close
 Set objConnection = Nothing
End If
DB使用時の文字化けを回避
DBで日本語を使っていると、ASPを実行した際に文字化けが起こることがあります。これを回避するにはASPの先頭に以下のように書きます。

<%@ CodePage=932 %>

■ストアドプロシージャ(SP)
ストアドプロシージャの実行引数の指定レコードセットの取得方法

ストアドの実行は、DB接続のようにDBに接続した中で行ってください。
※ ストアドの中でset nocount on をつけていないと レコードセットが取れない場合があります。
※ ストアド実行時にコマンドオブジェクトを使う利点は、'を''に置き換える処理をしなくていい。

' ---------------------------------------------
' コマンドオブジェクトと実行するストアドの宣言
' ---------------------------------------------
Set objCommand = Server.CreateObject("ADODB.Command") 'コマンドオブジェクト
objCommand.CommandTimeout = 0 'クエリがタイムアウトしないため
objCommand.ActiveConnection = objConnection '現在のコネクションを使用
objCommand.CommandType = 4 'ストアドプロシージャを指定
objCommand.CommandText = "testsp" 'ストアドプロシージャ名

' ---------------------------------------------
' ストアドに渡す引数の設定(インプットのみ)
' ---------------------------------------------
Set objParm = objCommand.CreateParameter("@IntNo1",3,1,,IntNo)
objCommand.Parameters.Append objParm
Set objParm = objCommand.CreateParameter("@ChrStr1",200,1,1,"0")
objCommand.Parameters.Append objParm

' ---------------------------------------------
' ストアドの実行&レコードセットの取得
' ---------------------------------------------
Set objRecordSet = Server.CreateObject("ADODB.Recordset") 'レコードセットオブジェクト
Set objRecordSet = objCommand.Execute 'コマンド実行
' ---------------------------------------------
' コマンド実行時にエラーが起きた場合はエラー画面に遷移
' ---------------------------------------------
If Err.Number <> 0 Then
 objRecordSet.close
 Set objRecordSet = Nothing

 If objConnection.State <> 0 Then '閉じていなければ閉じる。
  objConnection.close
 End If
 Set objCommand = Nothing
 Set objConnection = Nothing
 Response.Redirect( "Error_DB.asp" )
Else

 ' ---------------------------------------------
 ' レコードセットの表示
 ' ---------------------------------------------
 Do While Not objRecordSet.EOF
  response.write objRecordSet.Fields(SpecialNum).Value
  
  objRecordSet.MoveNext '次のレコードへ。
 Loop

End if

'------------------------------------------------------------
' Connectionクローズ
'------------------------------------------------------------
If objConnection.State <> 0 Then '閉じていなければ閉じる。
 objConnection.close
End If

Set objCommand = Nothing 'オブジェクトを開放する(別にしなくてもよい)
Set objConnection = Nothing 'オブジェクトを開放する(別にしなくてもよい)

ストアドプロシージャの実行からアウトプットの取得方法(return含む)

ストアドの実行は、DB接続のようにDBに接続した中で行ってください。

' ---------------------------------------------
' コマンドオブジェクトと実行するストアドの宣言
' ---------------------------------------------
Set objCommand = Server.CreateObject("ADODB.Command") 'コマンドオブジェクト
objCommand.CommandTimeout = 0 'クエリがタイムアウトしないため
objCommand.ActiveConnection = objConnection '現在のコネクションを使用
objCommand.CommandType = 4 'ストアドプロシージャを指定
objCommand.CommandText = "testsp" 'ストアドプロシージャ名

' ---------------------------------------------
' ストアドに渡す引数の設定
' ---------------------------------------------
'Retun 戻り値
Set objParm = objCommand.CreateParameter("Return",3,4,,RetErrorNumber) objCommand.Parameters.Append objParm

'ストアドのインプット値
Set objParm = objCommand.CreateParameter("@IntID",3,1,,IntID) objCommandParameters.Append objParm

'ストアドのアウトプット値1
Set objParm = objCommand.CreateParameter("@ChrOut1",129,1,2,ChrOut1) objCommand.Parameters.Append objParm

'ストアドのアウトプット値2
Set objParm = objCommand.CreateParameter("@ChrOut2",129,1,2,ChrOut2) objCommand.Parameters.Append objParm

'ストアドのアウトプット値3
Set objParm = objCommand_WA.CreateParameter("@ChvOut3",200,2,255,ChvOut3) objCommand.Parameters.Append objParm

' ---------------------------------------------
' ストアドの実行
' ---------------------------------------------
objCommand.Execute 'コマンド実行

' -----------------------------------------------------
' コマンド実行時にエラーが起きた場合は戻り値としてエラーを返す
' -----------------------------------------------------
If Err.Number = 0 Then
 ChrOut1 = objCommand("@ChrOut1") 'アウトプット1
 ChrOut2 = objCommand("@ChrOut2") 'アウトプット2
 ChvOut3 = objCommand("@ChvOut3") 'アウトプット3
 RetErrorNumber = objCommand("Return") 'Returnコード

 If RetErrorNumber = 0 Then
 Else
  RetValue = -1 'エラー発生
 End If

Else
 RetValue = -1 'エラー発生
End if

'------------------------------------------------------------
' Connectionクローズ
'------------------------------------------------------------
If objConnection.State <> 0 Then '閉じていなければ閉じる。
 objConnection.close
End If

Set objCommand = Nothing 'オブジェクトを開放する(別にしなくてもよい)
Set objConnection = Nothing 'オブジェクトを開放する(別にしなくてもよい)

レコードセットとアウトプットの両方の取得方法

ストアドの実行は、DB接続のようにDBに接続した中で行ってください。

レコードセットオブジェクトを一度クローズし、アウトプット値を取得した後、レコードセットオブジェクトをクローズすることにより、両方をとることができます。


' ---------------------------------------------
' コマンドオブジェクトと実行するストアドの宣言
' ---------------------------------------------
Set objCommand = Server.CreateObject("ADODB.Command") 'コマンドオブジェクト
objCommand.CommandTimeout = 0 'クエリがタイムアウトしないため
objCommand.ActiveConnection = objConnection '現在のコネクションを使用
objCommand.CommandType = 4 'ストアドプロシージャを指定
objCommand.CommandText = "testsp" 'ストアドプロシージャ名

' ---------------------------------------------
' ストアドに渡す引数の設定
' ---------------------------------------------
'ストアドのインプット値
Set objParm = objCommand.CreateParameter("@IntID",3,1,,IntID) objCommandParameters.Append objParm

'ストアドのアウトプット値
Set objParm = objCommand.CreateParameter("@ChrOut1",129,1,2,ChrOut1) objCommand.Parameters.Append objParm

' ---------------------------------------------
' ストアドの実行
' ---------------------------------------------
Set objRecordSet = Server.CreateObject("ADODB.Recordset") 'レコードセットオブジェクト
Set objRecordSet = objCommand.Execute 'コマンド実行

' -----------------------------------------------------
' コマンド実行時にエラーが起きた場合は戻り値としてエラーを返す
' -----------------------------------------------------
If Err.Number = 0 Then
 objRecordset.Close 'レコードセットを一度閉じる

 ChrOut1 = objCommand("@ChrOut1") 'アウトプット1を取得

 objRecordset.Open 'レコードセットをオープン

 ' ---------------------------------------------
 ' レコードセットの表示
 ' ---------------------------------------------
 Do While Not objRecordSet.EOF
  response.write objRecordSet.Fields(SpecialNum).Value
  
  objRecordSet.MoveNext '次のレコードへ。
 Loop

Else
 RetValue = -1 'エラー発生
End if


'------------------------------------------------------------
' Connectionクローズ
'------------------------------------------------------------
If objConnection.State <> 0 Then '閉じていなければ閉じる。
 objConnection.close
End If

Set objCommand = Nothing 'オブジェクトを開放する(別にしなくてもよい)
Set objConnection = Nothing 'オブジェクトを開放する(別にしなくてもよい)

■エクセル(Excel)
テーブルタグをエクセルで開く
HTMLのテーブルをエクセルのセルとして表示することができます。
それには、Response.AddHeaderをASPの最初の方で宣言します。
※エクセル2000の場合、最新版のサービスパックを当てなければ動きません。

1) エクセルで開く。もしくは保存させる場合 (ダウンロード)
Response.AddHeader "content-disposition", "attachment; filename=aaa.xls"

2)ブラウザのエクセルで開く場合。
Response.AddHeader "content-disposition", "inline; filename=aaa.xls"
'ブラウザがどのアプリケーションで開くかを設定する。
Response.ContentType = "application/vnd.ms-excel"
エクセルで改行しない。(テーブルタグで改行しない)

テーブルタグをエクセルで開くでやったように、テーブルタグをエクセルで開くとき、セルの中身を改行させない方法

1)style=white-space:nowrapを使う方法。
以下のように書くことによって、テーブル全体が改行しないようになります。

<TABLE border=1 style=white-space:nowrap>

2)<TD>タグに直接書く方法。
以下のように書くことによって、そのタグのみ改行しないようになります。

<TD nowrap>

エクセルに画像を張る方法
テーブルタグをエクセルで開くの方法でエクセルを表示した場合、エクセルに画像を張るときはフルパスで指定しなければなりません。
エクセルで表示する場合は、

 <IMG src=""http://123.456.78.99/SCORE/score_logo_test.gif"">

のように、フルパスで指定しなければなりません。下のようには出来ません。
 ×<IMG src=""score_logo_test.gif"">

■ブラウザ(IE)
複数ブラウザとセッションについて

複数のブラウザを開くときに、以下の2種類の状況があります。
@ブラウザを2つ別々に起動した場合。(別プロセスで起動)
Aブラウザを1つ起動し、「ファイル-新規作成-ブラウザ」から新規ブラウザを開いた場合(又はCtrl+N)。(同一プロセスとして起動)

@の場合、Sessionは別々になり、Session変数も別々に持ちます。
Aの場合、Sessionは同じで、Session変数も同じものを使います。

このため、Aの場合は、片方のブラウザでASPを呼び、Session変数が変更されるともう片方の使っているSession変数も変わったことになります。

このため、Session変数はあまり使わない方が良いといえます。

ブラウザのタイムアウト防止処理(SPの非同期実行とパケット送信)
※ この方法は、ストアドの実行に相当の時間がかかってしまう場合のみ使ってください。

IEなどのブラウザ自体にタイムアウトの時間が設定されています。ストアドの実行中にその時間を越えても大丈夫なようします。
ストアドは非同期実行を行い、ASPではストアドの実行が終わるまで、パケットを送りつづけるという処理を行います。

' ---------------------------------------------
' ストアドの非同期実行
' ---------------------------------------------
 Call objCommand.Execute(,,16)
' ---------------------------------------------
' ブラウザのタイムアウト防止関数
' ---------------------------------------------
 Call SendComment(objCommand)

' ---------------------------------------------
' ストアドの実行が終わった後は、非同期のコマンドを止める
' ---------------------------------------------
 objCommand.Cancel

------------------------------------------------------------------
' ---------------------------------------------
' タイムアウト防止関数の中身
' ---------------------------------------------
Sub SendComment(p_objCommand)

 Const adStateExecuting = 4
 Dim objWait 'ウェイトタイマーオブジェクト
 Dim Num 'カウンタ
 Num = 0

 Set objWait = Server.CreateObject("ADODB.Connection")
 objWait.CommandTimeout = 100 ' WAITFOR に指定する時間に見合うだけの時間にさらに少し余裕を持って設定する。
 Call objWait.Open( DB_DATABASE_STR,"sa","" )

 'オブジェクトがコマンド実行中はループする
 Do while p_objCommand.state AND adStateExecuting

  'もしクライアントとのコネクションが切れていたら処理を終わる。
  If Response.IsClientConnected = False Then
   Response.End
  End If

  Call objWait.Execute("WAITFOR DELAY '00:00:02'") ' 2 秒間待機

  If Num = 5 Then '10秒ごとにコメント
   Call Response.Write("<!-- " & Now() & " -->" & vbNewLine) ' ブラウザをタイムアウトさせないための response として HTML のコメントを送信。
   Response.Flush
   Num = 0
  End If

  Num = Num + 1

  'エラー処理
  If Err.Number <> 0 Then
   Response.Redirect( "Error_DB.asp" )
  End If

 Loop

 Call objWait.Close()
 Set objWait = Nothing

End Sub

■変数
アプリケーション変数のロック
アプリケーション変数は複数クライアント間で共通なため、カウントなどをとる場合は、ロックをする必要があります。
Lockでロック、Unlockでロック解除できます。

Application.Lock
 Application("cnt") = Application("cnt") + 1
Application.Unlock
Session変数・application変数の一覧表示
Dim i
For Each i In Session.Contents
 Response.Write(i & "=" & Session(i) & "<BR>")
Next
IPアドレスの取り方(環境変数の取得)
環境変数を取得するコレクションを使います。
IPアドレスは
 Request.ServerVariables("REMOTE_ADDR")
で取得できます。

以下は 使用できる環境変数を全て列挙するサンプルです。

Dim name
For Each name In Request.ServerVariables
 Response.write name & " " & Request.ServerVariables(name) &"<br>"
Next

■文字列
ループ内での文字列連結(A = A & B) は遅い
VBSでは、文字列の連結をしすぎると遅くなるそうです。
JavaScript等の
 A += B
は遅くないそうです。

たとえば、出力バッファがオン(Response.Buffer = True )になっているとして、

レコードセットなどを連結するときに、
 A)
 Do While Not objRecordSet.EOF
  response.write objRecordSet.Fields(SpecialNum).Value
  objRecordSet.MoveNext '次のレコードへ。
 Loop

とするのと、
 B)
 A = ''
 Do While Not objRecordSet.EOF
  A = A & objRecordSet.Fields(SpecialNum).Value
  objRecordSet.MoveNext '次のレコードへ。
 Loop
 Response.Write A

とするのでは、A)の方が早くなるそうです。
パフォーマンスとスタイルに関する ASP 25+ の Tipsより

■ヌル(null)
A = null & "a" はnull
null と結合しても null です。

■ページ遷移
ページ遷移(Response.Redirect)

ASPの途中でエラーが起きたときにエラー画面に遷移したいときなど、
以下のように書きます。
If Err.Number <> 0
 Response.Redirect("Error.asp")
End If

ただし、Response.write 等で、一度送信してしまってから Response.Redirect をしようとするとエラーになります。

■クラス(class)
class(クラス)ステートメント

以下のようにして中にプロパティ、メソッドを定義すればクラスが使えます。

Class name
   statements
End Class

インスタンスの作成は以下のようにします。
Dim X Set X = New classname

■レスポンスバッファー(Respons.Buffer)
Response.Buffer(一気に送信するかどうか)

Response.Buffer = True にすると、Response.Flush が呼ばれるか、ページが終了するまで、送信が行われません。
Response.Buffer = False の時は、Response.Write 毎に送信されます。

トータルのパフォーマンスでは、一気に送信するほうがよくなりますが、Response.Flushが呼ばれるまで送信されないので、遅く感じます。なので、グループに分けて適当な大きさ毎にResponse.Flushを行うのがいいかと思われます。

※ Response.Buffer = True の設定はASPの一番最初に実行しないとエラーになります。(送信する前)デフォルトでは Response.Buffer = Falseになっています。

■文字化け
文字化けの回避
以下のように、HTMLのHEADタグでタイプを宣言する。

<HEAD><META HTTP-EQUIV="Content-Language"CONTENT="ja"><META HTTP-EQUIV="Content-Type"CONTENT="text/html;CHARSET=shift_jis"></HEAD>

■サブミット
Enterキーを押すと勝手にサブミットする現象を阻止
HTMLタグにおいて、テキストボックスが1つだとリターンを押すと勝手にサブミットしてしまうする現象を阻止する方法。

FORMタグ か BODYタグに onSubmit="return false;"を付けることで阻止できる。

<BODY onSubmit="return false;">

■停止
ASP、SPは途中でとまるのか?(送信ボタンを連続で押したとき等)
通常はタイムアウトにならない限り止まることはありません。送信ボタン等でASPを実行する場合、ボタンを2回押すとASPも2回実行されます。1回押すごとに5分かかる処理であれば、2回押すと10分かかります。ただし以下のように止まってしまうときもあります。

ASPの中でストアドプロシージャを呼んでいる場合。
006のように、ストアドプロシージャの実行には、同期実行と非同期実行があります。

同期で実行しているときは、ASPもSPも途中で止まることはありません。もしASPがタイムアウトで止まってしまった場合も、実行中のSPが途中で止まることはありません。

非同期で実行している場合は、ボタンを2回押すと、1回目のASPもストアドも途中で止まり、2回目のASPの実行が走ります。

(※ このTipsについては間違っているかもしれません。)

■テーブル(table)
tableを隠す方法

<TABLE border="1" id="tab_1" style="background:#98e7e4; font-coler: #000000; width:650;visibility:hidden" >
hiddenをvisibleにすれば可視状態。
Request("ID")という参照はダメ
名前から参照するため、修飾を行わないと遅くなります。
×Request("ID")
○Request.Form("ID") や Request.QueryString("ID")

セッション変数も同じです。
×Session("MyName")
○Session.Contents("MyName")

■その他
思ったこと
●ASPでは、インラインフレームは使わない方がよい気がする。
●サーバの応答が必要なところの判定でメッセージボックスを使わないほうがよい気がする。画面遷移を行ったほうが安全ぽい。
●メッセージボックスは入力判定など、クライアントのみで完結する場合のみに使ったほうが良い気がする。
●クライアント側でできることは、なるべくクライアントでやる方がいい気がする。
●Session変数はあまり使わないほうがよい。(同一プロセスの複数ブラウザの場合同じ変数を使うため)
参考文献

サイト
・初心者による Active Server Pages(ASP) プログラミング・メモ
・unibon のページ (unibon)
・TRY!ASP
・Baba Centerfolds(BASP21[メール送信、ファイルアップロードコンポーネント]のページ)
・USERS GROUP
・MSDN ライブラリ(VBScript)
・一撃必殺!JavaScript日本語リファレンス
・パフォーマンスとスタイルに関する ASP 25+ の Tips


・今日から使えるASP3.0 サンプル集 秀和システム
・ASP実践プログラミング入門 技術評論社


クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 クリックして下ちぃ。 笑いシーク 日記才人追加 クリックして下ちぃ。 クリックして下ちぃ。  
クリック不要Death。 クリック不要