Access + Webのホームへ戻る

レコードセットをページングするには

 

Accessのデータベースado.mdbから得意先テーブルのレコードセットを作成して複数のページに分割して表示する方法を説明します。レコードセットの内容をHTMLページに表示させるとき、レコード数を制約しないと結果が表示されるまで時間がかかり過ぎて実用的ではありません。この場合、1回の要求で表示するレコード数を適当な範囲で制約することにより快適なレスポンスを保障することができます。

 

レコードセットを複数のページに分割して表示する場合、すべてアプリケーション側で対処する方法もありますが、RecordsetオブジェクトのPageSize, PageCount, AbsolutePageプロパティを使用することにより比較的簡単にページング処理を行うことができます。

 

● ページ当たりのレコード数を固定とするサンプル

 

得意先テーブルのレコードセットをページ当たり10レコード単位で複数のページに分割して表示する方法を説明します。ここで紹介するサンプルは、ページを移動するために「Prev  1  2  3  4  5  Next」のようなハイパーリンクを表示します。3はカレントのページを意味します。Prevのリンクをクリックするとページ2を表示します。Nextのリンクをクリックするとページ4を表示します。ページ番号(1  2  4  5)のリンクをクリックすると対応するページを表示します。

 

Access + Webのダウンロードにサンプルが収録されています。ダウンロードの目次を表示させたら、「AbsolutePage, PageSize, PageCountプロパティを利用した手法」をクリックしてください。Internet Explorerの左側のフレームには、ASPのソースが表示されます。右側のフレームには、実行結果が表示されます。

 

リストの行43では、intPageSizeにページ当たりのレコード件数10を設定しています。このサンプルでは、1ページ当たり10レコード表示します。

 

43: intPageSize = 10

 

45-49では、RequestオブジェクトのQueryStringメソッドでカレントページ(page=)QueryStringを取得して値を調べています。カレントページのQueryStirngが空白のときは、intPageCurrent1を設定して初期化します。カレントページのQueryStringが指定されているときは、CInt()関数で整数型に変換してintPageCurrentに保存します。QueryStringは、ページ移動用のハイパーリンクに指定しています。

 

<a href='RecordsetPaging.asp?page=1'>1</a>

 

45: if len(request.QueryString("page")) = 0 then

46:    intPageCurrent = 1

47: else

48:    intPageCurrent = CInt(request.QueryString("page"))

49: end if

 

51-54では、Accessのデータベースado.mdbを接続するための処理を行っています。行51-52では、OLEDBProviderData Sourceを設定してstrConnectionに保存しています。行54では、ConnectionオブジェクトのOpenメソッドでado.mdbを接続しています。

 

51: strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" _

52:   & "Data Source=" & server.MapPath("webdb/ado.mdb")

53: set cnn = server.CreateObject("adodb.connection")

54: cnn.Open strConnection

 

56-58では、得意先テーブルからレコードを抽出するSQLを作成してstrSQLに保存しています。SQLSELECTのフィールド名には、得意先コード、得意先名、担当者名、電話番号を指定しています。また、このSQLには、ORDER BY句が指定されていますので得意先コード順に並べ替えられます。

 

56: strSQL = "Select 得意先コード,得意先名,担当者名,電話番号" _

57:   & " From 得意先" _

58:   & " Order by 得意先コード;"

 

60では、ServerオブジェクトのCreateObjectメソッドでRecordsetのインスタンスを生成しています。行61では、RecordsetオブジェクトのPageSizeプロパティにintPageSizeを設定します。intPageSizeには、10が保存されていますので1ページに10レコード表示されます。行62では、RecordsetCursorLocationプロパティにadUseClientを設定しています。行63では、RecordsetCashSizeプロパティにintPageSizeを設定しています。(つまり、キャッシュサイズとページサイズを一致させています。)行64-65では、RecordsetOpenメソッドで得意先テーブルのレコードセットを生成しています。

 

60: set rs = server.CreateObject("adodb.recordset")

61: rs.PageSize = intPageSize

62: rs.CursorLocation = adUseClient

63: rs.CacheSize = intPageSize

64: rs.Open strSQL, cnn, adOpenStatic, _

65:   adLockReadOnly, adCmdText

 

66-70では、RecordsetオブジェクトのPageCountプロパティを調べています。PageCountプロパティが0なら、Response.Clearメソッドでバッファの内容を消去してからEchoを呼び出して「レコードがありません!」のメッセージを表示します。最後に、Response.Endメソッドでこのページの処理を終了します。

 

66: if rs.PageCount = 0 then

67:   response.Clear

68:   Echo "レコードがありません!"

69:   response.End

70: end if

 

Sub Echoは、行6-8に定義されています。このSubは、引数で指定された文字列をResponse.Writeメソッドでブラウザに送信します。Sub EchoNLは、行9-11に定義されています。このSubは、引数で指定された文字列をResponse.Writeメソッドでブラウザに送信します。このとき、NewLine(CR+LF: Carriage Return + Line Feedの略)も同時に送信します。

 

72では、RecordsetオブジェクトのPageCountプロパティをintPageCountに保存しています。このプロパティにはレコードセットの総ページ数が格納されています。

 

72: intPageCount = rs.PageCount

 

74-79では、QueryStringのカレントページがRecordsetの総ページ数の範囲内か調べています。カレントページがRecordsetの総ページ数より大きいときは、カレントページをRecordsetの総ページ数にします。また、カレントページが1より小さいときは、1にします。

 

74: if intPageCurrent > intPageCount then

75:   intPageCurrent = intPageCount

76: end if

77: if intPageCurrent < 1 then

78:   intPageCurrent = 1

79: end if

 

81では、RecordsetAbsolutePageプロパティにQueryStringのカレントページを設定します。これでカレントレコードは、QueryStringのカレントページの先頭レコードに位置付けされます。

 

81: rs.AbsolutePage = intPageCurrent

 

82-84では、カレントページと総ページ数を「Page 1 of 6」の形式で表示します。

 

82: echo "Page <b>" & intPageCurrent _

83:   & "</b> of <b>" & intPageCount & "</b>"

84: echoNL"<br><br>"

 

86,107では、HTMLの表を作成するために<table>・・・</table>タグを送信しています。

 

86: EchoNL"<table border='1'>"

   ・・・

107: EchoNL"</table>"

 

87-93では、表の見出しを送信しています。行88-92for…nextでは、Recordsetのフィールド名を見出しとして送信しています。

 

87: EchoNL vbTab & "<tr>"

88: for intI = 0 to rs.Fields.Count - 1

89:   Echo vbTab & vbTab & "<th>"

90:   Echo rs.Fields(intI).Name

91:   EchoNL "</th>"

92: next

93: EchoNL vbTab & "</tr>"

 

95-106では、QueryStringのカレントページをブラウザに送信しています。行95では、カレントページに送信したレコード数を0に初期化しています。行96-106do while…loopでは、カレントページに表示するレコードを送信しています。行98-102for…nextでは、カレントレコードのすべてのフィールドを送信しています。行104では、カレントページに送信したレコード数を+1加算しています。行105では、RecordsetMoveNextメソッドで次のレコードに移動しています。カレントレコードがカレントページの最終レコードのとき、またはEOFが報告されたときdo while…loopが終了します。

 

95: intRecordsShown = 0

 96: do while intRecordsShown < intPageSize and not rs.EOF

 97:   EchoNL vbTab & "<tr>"

 98:   for intI = 0 to rs.Fields.Count - 1

 99:     Echo vbTab & vbTab & "<td>"

100:     Echo rs.fields(intI)

101:     EchoNL "</td>"

102:   next

103:   EchoNL vbTab & "</tr>"

104:   intRecordsShown = intRecordsShown + 1

105:   rs.MoveNext

106: loop

 

109-110では、レコードセットを閉じてデータベースを切断しています。

 

109: rs.Close

110: cnn.Close

 

115-132では、表の最後にページ移動用のハイパーリンク(HTML<a>・・・</a>タグ)を生成しています。行115-118では、カレントページが1以上のとき「Prev」のハイパーリンクを生成します。

 

<a href='RecordsetPaging.asp?page=3'>Prev</a>&nbsp;

 

115: if intPageCurrent > 1 then

116:   EchoNL "<a href='RecordsetPaging.asp?page=" _

117:     & intPageCurrent - 1 & "'>Prev</a>&nbsp;"

118: end if

 

120-127for…nextでは、カレントページを除く各ページのハイパーリンクを生成しています。カレントページは、通常のテキストとして表示します。「&nbsp;」は、印字されない空白でCHR(160)に対応します。HTMLでは、空白CHR(32)を送信しても無視されますが、CHR(160)を送信すると空白が確保されます。

 

<a href='RecordsetPaging.asp?page=1'>1</a>&nbsp;

<a href='RecordsetPaging.asp?page=2'>2</a>&nbsp;

<a href='RecordsetPaging.asp?page=3'>3</a>&nbsp;

4&nbsp;

<a href='RecordsetPaging.asp?page=5'>5</a>&nbsp;

<a href='RecordsetPaging.asp?page=6'>6</a>&nbsp;

 

120: for intI = 1 to intPageCount

121:   if intI = intPageCurrent then

122:     Echo intI & "&nbsp;"

123:   else

124:     EchoNL "<a href='RecordsetPaging.asp?page=" _

125:       & intI & "'>" & intI & "</a>&nbsp;"

126:   end if

127: next

 

129-132では、カレントページが最終ページ以外のとき「Next」のハイパーリンクを生成しています。

 

<a href='RecordsetPaging.asp?page=5'> Next</a>

 

129: if intPageCurrent < intPageCount then

130:   EchoNL "<a href='RecordsetPaging.asp?page=" _

131:     & intPageCurrent + 1 & "'> Next</a>"

132: end if

 

 

図 得意先テーブルのレコードを複数ページに分割して表示するサンプル(その1)

 

 

図 得意先テーブルのレコードを複数ページに分割して表示するサンプル(その2)

 

リスト  RecordsetPaging.aspのソースコード

  1: <%@ language=vbscript %>

  2: <% option explicit %>

  3: <% response.buffer = true %>

4: <!--#include file=adovbs.inc -->

  5: <%

  6: sub Echo(strMsg)

  7:   response.write strMsg

  8: end sub

  9: sub EchoNL(strMsg)

 10:   response.write strMsg & vbNewLine

 11: end sub

 12: %>

13: <html>

 14: <head>

 15: <style>

 16: tr {

 17: background: cyan;

 18: font-size: 80%;

 19: }

 20:

 21: th {

 22: color: blue;

 23: }

 24:

 25: td {

 26: color: black;

 27: }

 28:

 29: </style>

 30: </head>

 31: <body>

 32: <%

 33: dim cnn, rs

 34: dim strSQL

 35: dim strConnection

 36:

 37: dim intPageSize

 38: dim intPageCount

 39: dim intPageCurrent

 40: dim intRecordsShown

 41: dim intI

 42:

 43: intPageSize = 10

 44:

 45: if len(request.QueryString("page")) = 0 then

 46:    intPageCurrent = 1

 47: else

 48:    intPageCurrent = cint(request.QueryString("page"))

 49: end if

 50:

 51: strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" _

 52:   & "Data Source=" & server.MapPath("webdb/ado.mdb")

 53: set cnn = server.CreateObject("adodb.connection")

 54: cnn.open strConnection

 55:

 56: strSQL = "Select 得意先コード,得意先名,担当者名,電話番号" _

 57:   & " From 得意先" _

 58:   & " Order by 得意先コード;"

 59:

 60: set rs = server.CreateObject("adodb.recordset")

 61: rs.PageSize = intPageSize

 62: rs.CursorLocation = adUseClient

 63: rs.CacheSize = intPageSize

 64: rs.Open strSQL, cnn, adOpenStatic, _

 65:   adLockReadOnly, adCmdText

 66: if rs.PageCount = 0 then

 67:   response.clear

 68:   echo "レコードがありません!"

 69:   response.end

 70: end if

 71:  

 72: intPageCount = rs.PageCount

 73:

 74: if intPageCurrent > intPageCount then

 75:   intPageCurrent = intPageCount

 76: end if

 77: if intPageCurrent < 1 then

 78:   intPageCurrent = 1

 79: end if

 80:

 81: rs.AbsolutePage = intPageCurrent

 82: echo "Page <b>" & intPageCurrent _

 83:   & "</b> of <b>" & intPageCount & "</b>"

 84: echoNL"<br><br>"

 85:  

 86: echoNL"<table border='1'>"

 87: echoNL vbTab & "<tr>"

 88: for intI = 0 to rs.fields.count - 1

 89:   echo vbTab & vbTab & "<th>"

 90:   echo rs.fields(intI).name

 91:   echoNL "</th>"

 92: next

 93: echoNL vbTab & "</tr>"

 94:

 95: intRecordsShown = 0

 96: do while intRecordsShown < intPageSize and not rs.eof

 97:   echoNL vbTab & "<tr>"

 98:   for intI = 0 to rs.fields.count - 1

 99:     echo vbTab & vbTab & "<td>"

100:     echo rs.fields(intI)

101:     echoNL "</td>"

102:   next

103:   echoNL vbTab & "</tr>"

104:   intRecordsShown = intRecordsShown + 1

105:   rs.MoveNext

106: loop

107: echoNL"</table>"

108:

109: rs.close

110: cnn.close

111: set rs = nothing

112: set cnn = nothing

113:

114: echo "<br>"

115: if intPageCurrent > 1 then

116:   echoNL "<a href='RecordsetPaging.asp?page=" _

117:     & intPageCurrent - 1 & "'>Prev</a>&nbsp;"

118: end if

119:

120: for intI = 1 to intPageCount

121:   if intI = intPageCurrent then

122:     echo intI & "&nbsp;"

123:   else

124:     echoNL "<a href='RecordsetPaging.asp?page=" _

125:       & intI & "'>" & intI & "</a>&nbsp;"

126:   end if

127: next

128:

129: if intPageCurrent < intPageCount then

130:   echoNL "<a href='RecordsetPaging.asp?page=" _

131:     & intPageCurrent + 1 & "'> Next</a>"

132: end if

133: %>

134: </body>

135: </html>

 

 

   ページ当たりのレコード数を可変とするサンプル

 

ここで紹介するサンプルは、得意先テーブルのレコードセットを複数のページに分割して表示するとき、ページ当たりのレコード数をドロップダウンリストから選択することができます。さらに、レコードセットを得意先コード順、またはフリガナ順に並べ替えて表示させることができます。

 

Access + Webのダウンロードにサンプルが収録されています。ダウンロードの目次を表示させたら、「ページサイズ、ソート順を任意に選択可能とした例」をクリックしてください。Internet Explorerの左側のフレームには、ASPのソースが表示されます。右側のフレームには、実行結果が表示されます。

 

リスト にサンプルのソースを掲載していますが、網がけの部分が追加/変更された箇所です。ここでは、追加変更された箇所を中心に説明します。

 

49-65では、RequestオブジェクトのQueryStringメソッドでpage=, pagesize=, order=QueryStringを取得しています。これらのQueryStringは、ページ移動用のハイパーリンクで設定しています。再設定のボタンをクリックしたときは、ドロップダウンリストから選択したpagesize orderが自動的にQueryStringに設定されます。行49-53では、page=QueryStringを取得してintPageCurrentに保存しています。行55-59では、pagesize=QueryStirngを取得してintPageSizeに保存しています。行61-65では、order=QueryStringを取得してstrOrderByに保存しています。order=には、「得意先コード」または「フリガナ」が指定されますが、URLEncodeされています。たとえば、「得意先コード」の場合、以下のようにURLEncodeされて渡されます。

 

order=%93%BE%88%D3%90%E6%83R%81%5B%83h

 

Server.QueryStringメソッドで、order=QueryStringを取得すると自動的にDecodeされて「得意先コード」が返されます。

 

<a href='RecordsetPaging2.asp?page=7&pagesize=5&order='>Prev</a>

<a href='RecordsetPaging2.asp?page=1&pagesize=5&order='>1</a>

・・・

<a href='RecordsetPaging2.asp?page=12&pagesize=5&order='>12</a>

<a href='RecordsetPaging2.asp?page=8&pagesize=5&order='>Next</a>

 

49: if len(request.QueryString("page")) = 0 then

50:   intPageCurrent = 1

51: else

52:   intPageCurrent = CInt(request.QueryString("page"))

53: end if

54: 

55: if len(request.QueryString("pagesize")) = 0 then

56:   intPageSize = 10

57: else

58:   intPageSize = CInt(request.QueryString("pagesize"))

59: end if

60: 

61: if len(request.QueryString("order")) = 0 then

62:   strOrderBy = "得意先コード"

63: else

64:   strOrderBy = request.QueryString("order")

65: end if

 

72-74で得意先テーブルからレコードを取得するSQLを作成するとき、ORDER BY句には、QueryStirngorder=で指定されているフィールド名を使用します。

 

72: strSQL = "Select 得意先コード,得意先名,担当者名,電話番号" _

73:   & " From 得意先" _

74:   & " Order by " & strOrderBy & ";"

 

135-141では、カレントページが1以上のときPrevのハイパーリンクを生成します。行139では、ServerオブジェクトのURLEncodeメソッドでstrOrderByURLEncodeしています。strOrderByには、「得意先コード」または「フリガナ」が格納されています。漢字をQueryStringに指定するときは、URLEncodeした値を指定する必要があります。(Internet Explorerなどの最新のブラウザでは、自動的にURLEncodeしますが他のブラウザでは保障されません。)

 

<a href='RecordsetPaging2.asp?page=3&pagesize=10&order='>Prev</a>

 

135: if intPageCurrent > 1 then

136:   echoNL "<a href='RecordsetPaging2.asp?page=" _

137:     & intPageCurrent - 1 _