美好的一天,
我遇到了一些简单的VBA问题。我编写了一个脚本来进行文本查询(没有输入参数,因此没有真正的用户交互,SQL注入等),对数据库运行它,并将其转储到新的工作表。对于某些开发人员分析,这是一个简单的一次性,因此功能非常简单。
如果查询返回每列的值,则没有问题。但是,如果查询中有任何空值(作为ROLLUP()的结果,在我的情况下),整个子例程将在MoveNext失败(注意:不是将空值赋给单元格)。最初,在
访问空行之前,脚本失败了Range(Cells(2, 1), Cells(rsData.RecordCount + 1, rsData.Fields.Count)).NumberFormat = "@"
这被评论并移动为逐个单元格,目的是添加一个检查当前单元格是否为空(到目前为止是互联网上最常见的建议)。
使用后端SQL编辑器验证了查询并且这些查询是正确的。我读过的所有其他文章都是针对某个产品或不适用的。那么,问题很简单:如何在Recordset中处理空值?我想避免删除数据库端的空值,因为这个子用于许多不同的查询,并且不得不用一堆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
答案 0 :(得分:3)
尝试改变:
rsData.CursorLocation = adUseClient
为:
rsData.CursorLocation = adUseServer
(基于不同Oracle问题的archived Microsoft support article)