3

再会,

我一直有一些简单的 VBA 的问题。我编写了一个脚本来进行文本查询(没有输入参数,因此没有真正的用户交互、SQL 注入等),针对数据库运行它,然后将其转储到新的工作表中。这是一些开发人员分析的简单一次性,因此功能非常简单。

如果查询返回每一列的值,则没有问题。但是,如果查询中有任何空值(在我的例子中是 ROLLUP() 的结果),整个子例程将在 MoveNext 处失败(注意:不是将空值分配给单元格)。最初,脚本在空行被访问之前就失败了

Range(Cells(2, 1), Cells(rsData.RecordCount + 1, rsData.Fields.Count)).NumberFormat = "@"

对此进行了评论并将其移至逐个单元格,目的是添加检查当前单元格是否为空(迄今为止互联网上最常见的建议)。

查询已使用后端 SQL 编辑器进行验证,并且是正确的。我读过的所有其他文章要么特定于某个产品,要么不适用。那么,问题很简单:应该如何处理 Recordset 中的空值?我想避免删除数据库端的空值,因为这个 sub 用于许多不同的查询,并且不得不用一堆 NVL() 语句来填充我的查询的想法非常令人不快。

提前感谢您的任何帮助。完整代码如下:

Sub runReport(query As String, sheetName As String)

    Dim cnDatabase As ADODB.Connection
    Dim rsData As ADODB.Recordset
    Dim row As Integer
    Dim column As Integer

    'Create new worksheet
    Sheets.Add.Name = sheetName
    Excel.Application.Worksheets(sheetName).Select

    'Connect to database
    Set cnDatabase = New Connection
    cnDatabase.ConnectionString = "Provider=OraOLEDB.Oracle;Data Source=DB.EXAMPLE.COM;User ID=FOO;Password=BAR;ChunkSize=1000;FetchSize=100;"
    cnDatabase.Open

    'Retrieve dataset
    Set rsData = New Recordset
    Set rsData.ActiveConnection = cnDatabase
    rsData.Source = query
    rsData.CursorLocation = adUseClient
    rsData.CursorType = adOpenStatic
    rsData.Open

    'Output header row
    For column = 1 To rsData.Fields.Count
        Cells(1, column).Value = rsData.Fields(column - 1).Name
        Rows(1).Font.Bold = True
    Next

    'Set all fields as text
    'Range(Cells(2, 1), Cells(rsData.RecordCount + 1, rsData.Fields.Count)).NumberFormat = "@"

    'Output retrieved data from database
    row = 2
    While Not rsData.EOF
      For column = 1 To rsData.Fields.Count
         Cells(row, column).NumberFormat = "@"
         Cells(row, column).Value = rsData.Fields(column - 1).Value
      Next

      rsData.MoveNext
      row = row + 1
   Wend
   cnDatabase.Close

End Sub
4

1 回答 1

3

尝试改变:

rsData.CursorLocation = adUseClient

到:

rsData.CursorLocation = adUseServer

(基于此归档的 Microsoft 支持文章,关于不同的 Oracle 问题)

于 2012-11-06T22:28:53.000 回答