
Code
<%
'===============================================
' 分页类
' Author : s1ihome (cnsdsxg@gmail.com)
'-----------------------------------
' Update : 2008年11月14日
' 处理重写规则,需结合httpd.ini中重写规则处理复杂情况如存在不确定参数的情况
'-----------------------------------
' Update : 2008/04/3 12:06
' 显示多页导航时,当总页数少于特定多页时(例如要显示5页导航,但总页数只有2页),仅显示总共页数
'-----------------------------------
' Update :  2008/03/23 12:15
' Fix :当显示多页导航时显示 <0的页数

'***********************************************
'读写属性
'  allSql     -- 最后形成的总的sql,可以用于输出捕获错误
'  sltFld     -- select 字段
'  keyFld     -- 主键or索引字段
'  FROMTbl    -- 表名,视图名,查询语句,可以带where,不带order by
'  sqlOrder   -- 排序字段
'  sqlWhere   -- 条件字段
'  pageSize   -- 页大小
'  pCurPage   -- 当前页
'  pTotalRec  -- 总记录数
'  pTotalPage -- 总页数
'  pPageNavTableWidth -- 显示分页的table宽度
'  pUrlPrefix -- 定义除页号外(page=)的自定义url前缀
'  pageNavID  -- 分页导航的ID,用以表明不同的input的ID
'只写属性
'  getConn    -- 获取conn对象
'  RewriteUrl-- 重写的页面url,以[page]代表page参数所在位置,like: infos_zufang_[page].shtml
'Public 方法
'  outputErr  -- 显示跟踪信息

'Example 以操作NorthWind数据库中 orders 表为例
' 建立对象:
'   Set oPage=New clsPageRs2
'
'   With oPage
'     .sltFld  = "orderID,customerID,orderDate"  '选取字段
'     .fromTbl = "orders"                        '调用表,多表联合 Like " tbl1 INNER JOIN tbl2 ON tbl1.ID = tbl2.ID"
'     .sqlOrder= "Order By orderID DESC"         '进行排序的字段,带order by
'     .sqlWhere= ""             'WHERE 条件语句,带where
'     .keyFld  = "orderID"                       '主键OR索引字段 不可缺少,同时选取字段sltFld 中必须包含该主键字段
'     .pageSize= 30
'     .frmJumpStyle ="select"                    '分页导航中跳转到页的表单元素样式,默认为 文本框+提交按钮,"select":下拉列表框直接跳转
'     .showMultiPageNum = 5                      '分页导航显示分页号数量,默认为0,不显示页号导航;<0时不显示"上一页"等文字导航
'     .toPageLinkStyle = "arrow"                 '到上一页、下一页的链接的样式,为空则为默认,显示为文字
'     .getConn = conn
'     Set rs  = .pageRs
'   End With
' 循环显示数据记录
'   Do While Not rs.Eof
'     response.Write rs(1)
'   rs.MoveNext
'   Loop
' 显示总记录数
'  response.Write oPage.pTotalRec
' 显示分页导航
'   Call oPage.pageNav()
'销毁对象
'   Set oPage = Nothing
'***********************************************

Class clsPageRs2
  Public  sltFld
  Public  keyFld
  Public  allSql    '只传入最后总sql
  Public  showMultiPageNum
  Public  pTotalRec
  Public  pUrlPrefix
  Public  speTipStr
  Public  toPageLinkStyle
  Public  pPageNavTableWidth
  Public  pCurPage,pTotalPage
  Public  pageNavID

  Private fFromTbl
  Private fSqlOrder    'e.g.: ' ID DESC'
  Private fSqlWhere
  Private fPageSize
  Private fPageSql
  Private fConn
  Private fRs
  Private fFrmJumpStyle
  Private fRewriteUrl
  Private  fSqlGetTotalCount  '获取总记录数的sql语句

  Private Sub Class_Initialize
    fPageSize = 15
    pCurPage  = 1
    fOrderSql = ""
    showMultiPageNum = 0
    speTipStr = "总记录数: | 条"
    toPageLinkStyle = "text"
          pPageNavTableWidth ="100%"
    fRewriteUrl=""
    pageNavID  = 1
  End Sub

  '输出错误信息
  Public Function outputErr
    response.Write "当前页:"& pCurPage&"<br/>"
    response.Write "总页:"& pTotalPage&"<br/>"
    response.Write "分页sql:"& fPageSql&"<br/>"
    response.Write "获取记录数sql:"& fSqlGetTotalCount&"<br/>"
    response.Write "错误信息:"& err.Description&"<br/>"
    response.Write "错误来源:"& err.Source&"<br/>"
  End Function
  '分解
  Private Function splitAllSql
     allSql = Trim(allSql)
     If Len(allSql)>0 And Len(fFromTbl)=0 And Len(sltFld)=0 Then
       Dim sltPos
       Dim frmPos
       Dim wherePos
       sltPos = 1
       fromPos = InstrRev(Ucase(allSql)," FROM ")
       wherePos = InstrRev(Ucase(allSql)," WHERE ")
       orderPos = InstrRev(Ucase(allSql)," ORDER ")

       If orderPos =0 Then orderPos = Len(allSql)
       If wherePos =0 Then wherePos = orderPos


       sltFld=Trim(Mid(allSql, sltPos+7, fromPos-sltPos-7))
       fFromTbl=Trim(Mid(allSql, fromPos+6, wherePos-fromPos-5))
       If wherePos =0 Then fSqlWhere = " WHERE 1=1 " Else fSqlWhere = Trim(Mid(allSql, wherePos, orderPos-wherePos))
       fSqlOrder = Trim(Mid(allSql, orderPos))
     End If
  End Function

  Private Sub Class_Terminate
     Set fRs = Nothing
     Set fConn = Nothing
  End Sub

  '获取conn
  Public Property Let getConn(byRef val)
    Set fConn=val
  End Property
  '获取pagesize
  Public Property Let pageSize(byVal val)
    fPageSize=val
  End Property

  Public Property Get pageSize()
    pageSize = fPageSize
  End Property

  Public Property Let FromTbl(byVal val)
    fFromTbl=val
  End Property
  Public Property Let sqlWhere(byVal val)
    fSqlWhere=val
  End Property
  Public Property Let sqlOrder(byVal val)
    fSqlOrder=val
  End Property

  Public Property Let RewriteUrl(byVal val)
    fRewriteUrl=val
  End Property

  Public Property Get totalPage
    totalPage = pTotalPage
  End Property
  Private Property Get FromTbl
    FromTbl = replace(fFromTbl,"'","''")
  End Property
  Public Property Get sqlWhere
    sqlWhere = fSqlWhere
    If Len(sqlWhere)=0 Then sqlWhere="WHERE 1=1"
  End Property
  Private Property Get sqlOrder
    sqlOrder = fSqlOrder
  End Property
  Public Property Let frmJumpStyle(byVal val)
    fFrmJumpStyle = val
  End Property
  Private Property Get frmJumpStyle
    frmJumpStyle = fFrmJumpStyle
  End Property



  '----------获取总页数、总记录数等
  Public Function getTotalPage
    On Error Resume Next
    splitAllSql
    fSqlGetTotalCount="SELECT COUNT(1) FROM "& FromTbl &" "& sqlWhere

    Set fRs = fConn.Execute(fSqlGetTotalCount)
    pTotalRec = fRs(0)
    fRs.Close
    Set fRs = Nothing
    If Err.number>0 Then outputErr

    pTotalPage=pTotalRec\fPageSize
    If (pTotalRec Mod fPageSize) Then pTotalPage=pTotalPage+1
    If pTotalPage=0 Then pTotalPage=1
    pCurPage = Request("page")
    If Len(pCurPage)=0 Or (Not isNumeric(pCurPage)) Then pCurPage=1
    If pCurPage - pTotalPage >0 Then pCurPage=pTotalPage
    If pCurPage -1<0 Then pCurPage=1
  End Function
  'End ----------获取总页数、总记录数等

  Public Function pageRs
    getTotalPage

    Dim tSql

    fPageSql = "SELECT TOP "& fPageSize&" "& sltFld&" FROM "
    tSql = " "& fFromTbl & " "& fSqlWhere & " "& fSqlOrder
    If Trim(fSqlWhere)="" Then fSqlWhere = "WHERE 1=1"
    If pCurPage=1 Then   '为第一页时直接获取top
      fPageSql = fPageSql & tSql
    Else
      sqlStart = fPageSql & fFromTbl & " "& fSqlWhere & " AND "& keyFld
      sqlEnd   = "(SELECT TOP "& (pCurPage -1)*fPageSize &" "& keyFld &" FROM "& tSql &") "
      If Instr(fFromTbl,",")=0 And Instr(Lcase(fFromTbl)," join ")=0 AND Instr(fSqlOrder,",")=0 AND Instr(Lcase(fSqlOrder)," "& Lcase(keyFld))>0 Then  '表明为单表并且是按主键排序操作
        If Instr(Lcase(fSqlOrder)," desc")=0 Then 'asc order
          fPageSql = sqlStart &">(SELECT MAX("& keyFld&") FROM "& sqlEnd&" AS T)"&" "& fSqlOrder
        Else
          fPageSql = sqlStart &"<(SELECT MIN("& keyFld&") FROM "& sqlEnd&" AS T)"&" "& fSqlOrder
        End If
      Else  '联合查询等时最好使用Not In
        fPageSql = sqlStart &" NOT IN "& sqlEnd &" "& fSqlOrder
      End If
    End If
    Set pagers = fConn.Execute(fPageSql)
  End Function

  '==========================================================================
  '* Description    :  获得去除了"&page="参数的翻页链接url
  '==========================================================================
  Function GetQryStrNoPage()
    Dim pagerUrl
    '----------去掉"page="参数防止重复----------
    Dim str : str=request.ServerVariables("QUERY_STRING")
    Dim queryStr
    If Len(str)>0 Then
      pos1=Instr(str,"&page=")    'querystring中是否存在"page="参数连接
      If pos1=0 Then
        queryStr=str
      Else
        queryStr=left(str,pos1-1)
        Dim oPos : oPos = Instr(pos1+1,str,"&") '针对&page参数在中间的情况,需把&page参数去除并连接其后的参数
        If oPos>1 Then queryStr = queryStr & Mid(str,oPos)
      End If
    Else
      queryStr="1=1"
    End If
    '//----------去掉"page="参数防止重复----------

    pUrlPrefix = Trim(pUrlPrefix)
    If Len(pUrlPrefix)=0 Then pUrlPrefix=request.ServerVariables("script_name")

    If inStr(pUrlPrefix,"?")>0 Then   '指定urlPrefix中存在queryString参数
      GetQryStrNoPage = pUrlPrefix
    Else
      GetQryStrNoPage = pUrlPrefix&"?"& queryStr
    End If
  End Function


  '==========================================================================
  '* Description    :  分页时导航部分表格
  '* Parms          :  (隐式)pCurPage--当前页 pTotalPage--总页数  pTotalRec--总记录数
  '                    (显式)speTipStr-- 显示分页提示
  '* Memo           :
  '     1.可自定义提示总记录条数信息 speTipStr Like "记录总数|条" 以"|"进行分割
  '==========================================================================
  Sub pageNav
    Dim lC
    toPageLinkStyle = LCase(toPageLinkStyle)

    If speTipStr="" Then speTipStr="总记录数: | 条"
    Dim arrTip   : arrTip  = Split(speTipStr,"|")
    %>
    <script language="javascript" type="text/javascript">
    <!--
    function $(id) {if(typeof(id)=='object') return id;try {return document.getElementById(id);}catch(e){try{return document.getElementsByName(id)[0]} catch(e){return null;}}}
    function $F(id) {
      var e = $(id);
      switch (e.tagName.toLowerCase()) {
        case 'input':{if(e.type.toLowerCase() =="checkbox" || e.type.toLowerCase() =="radio") return e.checked ? e.value : '';return e.value;}
       case 'textarea':{return e.value;}
        case 'select':{  var index = e.selectedIndex;return index >= 0 ? this.optionValue(e.options[index]) : '';}
      }
    }
    function hidden_link(link) {
     var a = document.createElement('A');
     a.href = link;
     a.target = '_self';
     a.style.visibility = 'hidden';
     document.body.appendChild(a);
     a.click();
    }


    function gotoPage(pageNo) {
      var pageNo = parseInt(pageNo);if(isNaN(pageNo)) return false;
      var pageUrl='';
      <%If fRewriteUrl<>"" Then %>
      pageUrl = '<%=fRewriteUrl%>'.replace(/\[page\]/gi,pageNo);
      <%Else%>
      pageUrl = '<%=GetQryStrNoPage%>'+'&page='+ pageNo;
      <%End If%>
      hidden_link(pageUrl);
    }
    //-->
    </script>
    <table border=0 cellspacing=0 cellpadding=0 align=center width="<%=pPageNavTableWidth%>" style="margin:5px 0px 3px 0px;">
     <tr align="center">
      <%If showMultiPageNum>-1 And pCurPage>1 Then%>
      <td><a href="<%=replacePageParm(1)%>" style="text-decoration:none;"><%If toPageLinkStyle="arrow" Then%><font face="Webdings">9</font><%Else%>首页<%End If%></a></td>
      <td>
      <a href="<%=replacePageParm(pCurPage -1)%>" style="text-decoration:none;">
      <%If toPageLinkStyle="arrow" Then%><font face="Webdings">3</font><%Else%>上一页<%End If%>
      </a>
      </td>
     <%
     Else
       response.Write "<td width='20%'>  </td>"
     End If
     %>
     <td>
     <%
     If showMultiPageNum<1 Then
       If pTotalRec>0 Then response.Write arrTip(0)& pTotalRec & arrTip(1)&"  "

       response.Write pCurPage&"/"& pTotalPage&" 页"
       response.Write "  "& fPageSize&"/页"
     Else    '一次显示多个页
       Dim tCurPage
       For i = getFirPageNo To getFirPageNo+showMultiPageNum-1
         If i-pTotalPage>0 Then Exit For
         If i - pCurPage = 0 Then tCurPage ="<font color='#ff0000'><b>"& i&"</b></font>" Else tCurPage = i
         response.Write "<a href='"& replacePageParm(i)&"'>"& tCurPage &"</a> "
       Next
     End If
     %>
     </td>
     <%If pCurPage - pTotalPage <0 Then %>
     <td> <a href="<%=replacePageParm(pCurPage+1)%>" style="text-decoration:none;"><%If toPageLinkStyle="arrow" Then%><font face="Webdings">4</font><%Else%>下一页<%End If%></a></td>
     <td> <a href="<%=replacePageParm(pTotalPage)%>" style="text-decoration:none;"><%If toPageLinkStyle="arrow" Then%><font face="Webdings">:</font><%Else%>尾页<%End If%></a></td>
     <%
     Else
       response.Write "<td> </td>"
     End If
     %>
     <td align="center">
      到 
     <%
     If Lcase(frmJumpStyle)<>"select" Then
     %>
       <input type=text size=4 onKeyUp="value=value.replace(/[^\d]/,'')" name="page" id="goPage<%=pageNavID%>" maxlength="5" value="<%=pCurPage%>"> 页 
       <input name="GO" type="button" style="padding:2px;background-color:#ccc;" value="Go!" onclick="gotoPage($F('goPage<%=pageNavID%>'))">
     <%
     Else
     %>
       <select name="page" size="1" id="goPage<%=pageNavID%>" onChange="gotoPage(this.options[this.selectedIndex].value)">
       <%
       For lC=1 To pTotalPage
         response.Write("<option value='"& lC&"'")
         If lC- pCurPage =0 Then response.Write(" selected")
         response.Write(">"& lC & "</option>")
       Next
       %>
       </select>页
     <%End If %>
     </td>
     </form>
    </tr>
    </table>
    <%
  End Sub

  '==========================================================================
  '* Description    :  替换Url中page参数,为空时
  '* Parms          :  (隐式)pCurPage--当前页 pTotalPage--总页数  pTotalRec--总记录数
  '                    (显式)speTipStr-- 显示分页提示
  '* Memo           :
  '     1.可自定义提示总记录条数信息 speTipStr Like "记录总数|条" 以"|"进行分割
  '==========================================================================
  Private Function replacePageParm(pageNo)
    If fRewriteUrl<>"" Then
      replacePageParm = Replace(fRewriteUrl,"[page]",pageNo,1)
    Else
      replacePageParm = GetQryStrNoPage&"&page="& pageNo
    End If
  End Function


  '当多页导航时获取 该导航组的首页(例如显示6-10页时首页为6)
  Private Function getFirPageNo
    Dim tGetFirPageNo
    If pCurPage - Int(showMultiPageNum/2)>0 Then
      If (pCurPage+Int(showMultiPageNum/2)) - pTotalPage>0 Then
        tGetFirPageNo = pTotalPage-showMultiPageNum+1
      Else
        tGetFirPageNo = pCurPage -Int(showMultiPageNum/2)
      End If
    Else
      tGetFirPageNo = 1
    End If
    If tGetFirPageNo<1 Then tGetFirPageNo=1

    getFirPageNo = tGetFirPageNo
  End Function
End Class
%>