1

我在编写将输出记录数组的函数时遇到问题。我试图做的是调用一个函数来获取表中的所有记录,并将创建一个多维数组,我可以在调用该函数的页面中使用该数组。

你能告诉我我做错了什么吗?

 function get_admins 
    set rs = Server.CreateObject("ADODB.recordset")
    rs.cursorType = 3
    getsql = "select * from users order by name asc"
    rs.Open getsql, conn
    total = rs.RecordCount
    ra = array
    c = 0
    if total < 1 then 
        o = "There are no admins yet."
    else
        do until rs.EOF
        id = rs.Fields("id").value
        username = rs.Fields("username").value
        adminname = rs.Fields("name").value
        email = rs.Fields("email").value

        Redim Preserve ra(c,4) '<-- This is the line the error doesn't like
    ra(c,0) = id
    ra(c,1) = username
    ra(c,2) = adminname
    ra(c,3) = email
    c = c + 1

        rs.MoveNext
        loop

       end if
      rs.close
      get_admins = ra
    end function

这是我得到的错误:

Microsoft VBScript 运行时错误“800a0009”

下标超出范围

页面上的函数调用如下所示:

<pre><%
        dim seeme 
    set seeme = get_admins
%></pre>

以下是我发现的一些类似问题:

Classic ASP 3.0 Create Array from a Recordset - 帮助很大,但还不够。

Redim Preserve 给出了“下标超出范围” ——这让我很困惑。

4

2 回答 2

3

ReDim Preserve只能更改多维数组中最后一个维度的大小,因此在您的情况下它并不是很有用。但是,您可以使用一个数组数组:

ReDim ra(-1)  'initialize record array as empty array
...
Else
  Do Until rs.EOF
    ReDim va(3)  'initialize value array (clear values)
    va(0) = rs.Fields("id").value
    va(1) = rs.Fields("username").value
    va(2) = rs.Fields("name").value
    va(3) = rs.Fields("email").value

    Redim Preserve ra(UBound(ra)+1) 'grow record array
    ra(UBound(ra)) = va             'put value array into record array

    rs.MoveNext
  Loop
End If

这将允许您访问嵌套数组的元素,如下所示:

WScript.Echo ra(3)(1)

以上将打印第4嵌套数组(索引 3)中的第 2值(索引 1 )。

至于返回数组,不能Set在赋值中使用关键字:

set seeme = get_admins   '<-- will fail!

那是因为该关键字是为对象分配保留的,而数组不是对象。将该行更改为:

seeme = get_admins
于 2013-07-25T20:12:55.150 回答
1

与其自己动手,不如看看.GetRows方法。

在我的声明后面加上一些代码:

  Dim oTCN  : Set oTCN = CreateObject( "ADODB.Connection" )
  Dim sTDir : sTDir    = "M:\lib\kurs0705\testdata\txt"  ' <-- ohne \ am Ende!
  Dim sCS   : sCS      = Join( Array( _
                                "Provider=MSDASQL" _
                              , "Driver={Microsoft Text Driver (*.txt; *.csv)}" _
                              , "DBQ=" & sTDir _
                         ), ";" )
  oTCN.Open sCS
  Dim oRS
  Set oRS = oTCN.Execute("SELECT TOP 3 * FROM [gendata.txt]")
  Dim nUB : nUB = oRS.Fields.Count - 1
  ReDim aRow(nUB) ' array for one row
  ReDim aRows(nUB, -1) ' 2nd dim growable array for all rows
  Dim f
  For f = 0 To UBound(aRow)
      aRow(f) = oRS.Fields(f).Name
  Next
  WScript.Echo Join(aRow, ",")
  Do Until oRS.EOF
     ReDim Preserve aRows(nUB, UBound(aRows, 2) + 1)
     For f = 0 To UBound(aRow)
         aRow(f) = oRS.Fields(f).Value
         aRows(f, UBound(aRows, 2)) = oRS.Fields(f).Value
     Next
     WScript.Echo Join(aRow, ",")
     oRS.MoveNext
  Loop
  oRS.MoveFirst
  Dim aMagic : aMagic = oRS.GetRows() ' this is all you need!
  Dim r, c
  For r = 0 To UBound(aMagic, 2)
      For c = 0 To UBound(aMagic, 1)
          WScript.Echo r, c, aMagic(c, r), aRows(c, r)
      Next
      WScript.Echo
  Next

  oTCN.Close

输出:

=============================================================
iID,sFrsName,sLstName,sSex,dtBirth
1,Yqiqpbcmunrzvi,Pmyqcxfoffrfnwbd,U,8/7/2008
2,Viyvfshpxu,Xjtfbjuiiwojhyjwkefcu,U,7/27/2008
3,Hoocyseiiiawrt,Mrpuhzuhysslzhwhnpp,F,8/7/2008
0 0 1 1
0 1 Yqiqpbcmunrzvi Yqiqpbcmunrzvi
0 2 Pmyqcxfoffrfnwbd Pmyqcxfoffrfnwbd
0 3 U U
0 4 07.08.2008 07.08.2008

1 0 2 2
1 1 Viyvfshpxu Viyvfshpxu
1 2 Xjtfbjuiiwojhyjwkefcu Xjtfbjuiiwojhyjwkefcu
1 3 U U
1 4 27.07.2008 27.07.2008

2 0 3 3
2 1 Hoocyseiiiawrt Hoocyseiiiawrt
2 2 Mrpuhzuhysslzhwhnpp Mrpuhzuhysslzhwhnpp
2 3 F F
2 4 07.08.2008 07.08.2008

=============================================================

所以 - 与 Ansgar 的“你不能在多维数组上使用 ReDim Preserve”相反 - 你可以增加多维数组的最后一个维度。这意味着您必须在 col/row 中增加行并将数组布局,而不是更“自然”的 row/col 结构。

aRows 展示了如何正确滚动自己的 .GetRows。当然,明智的策略是使用,如

Dim aMagic : aMagic = oRS.GetRows() ' this is all you need!
于 2013-07-25T20:38:02.667 回答