/ / copyfromrecordset повертає порожній стовпець - excel, vba, sybase

copyfromrecordset повертає порожній стовпець - excel, vba, sybase

Я створюю ADODB-з'єднання з Sybaseбазу даних, виконуючи оператор SQL у набір записів, а потім використовуючи метод CopyFromRecordset, щоб вставити вміст набору записів в діапазон. Це добре працює, але я нещодавно перемістив ПК на роботу, і тепер одна зі стовпчиків нічого не повертає.

Коли я запускаю той же SQL у SQuirreL, стовпчик не є порожнім.

Якщо я призупинюю VBA і спробую переглянути одне з значень у відповідному стовпчику / області (наприклад, "rst.fields (1) .value у безпосередньому вікні"), я отримую таке повідомлення про помилку:

Помилка виконання "-2147467259 (80004005)": невизначена помилка.

У вкладці Метадані результатів Squirrel відповідний стовпець описується як:

ColumnIndex 2
getColumnName CommentText
getColumnTypeName text
getPrecision 2147483647
getScale 0
isNullable 0
getTableName xxxxxxx
getSchemaName
getCatalogName
getColumnClassName java.sql.Clob
getColumnDisplaySize 2147483647
getColumnLabel CommentText
getColumnType 2005
isAutoIncrement FALSE
isCaseSensitive FALSE
isCurrency FALSE
isDefinitelyWritable FALSE
isReadOnly FALSE
isSearchable FALSE
isSigned FALSE
isWritable TRUE

Нижче описаний код, але, як зазначено, код, здається, не є проблемою, оскільки він працював раніше - будь-які ідеї?

Sub ImportComments()

Dim wsData As Worksheet
Dim rng As Range
Dim cn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim x As Long
Dim rngSQL  As Range
Dim cell As Range
Dim sSQL As String
Dim sProvider As String
Dim sDS As String
Dim sDataSource As String
Dim sUser As String
Dim sCatalog As String
Dim sPassword As String
Dim rngDS As Range
Dim rngThisDS As Range
Dim sConnect As String
Dim sInstance As String
Dim fSuccess As Boolean
Dim sError As String

On Error GoTo ProcExit

"delete previous comments if they exist
If SheetExists("Comments_Data_Import", ThisWorkbook) = True Then
Application.DisplayAlerts = False
ThisWorkbook.Sheets("Comments_Data_Import").Delete
Application.DisplayAlerts = True
End If

"create comments sheet
Set wsData = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Sheets("EWI_Data_Import"))
wsData.Name = "Comments_Data_Import"

"build sql string
Set rngSQL = Range(ThisWorkbook.Sheets("SQL").Range("A2"), _
ThisWorkbook.Sheets("SQL").Range("A2").End(xlDown))
For Each cell In rngSQL
sSQL = sSQL & cell.Value & " "
Next cell

"define login components
Set rngDS = ThisWorkbook.Worksheets("Login").Range("rngInstance").CurrentRegion
Set rngDS = rngDS.Offset(1, 0).Resize(rngDS.Rows.Count - 1)
sProvider = "Provider=ASEOLEDB.1;"
sUser = "User ID=" & ThisWorkbook.Worksheets("Login").Range("rngUsername").Value & ";"
sPassword = "Password=" & ThisWorkbook.Worksheets("Login").Range("rngPassword").Value

"try to log in to each instance exiting when succesful
Set cn = New ADODB.Connection
cn.CommandTimeout = 600

"turn off error hadling to allow for connection errors    On Error Resume Next

For Each rngThisDS In rngDS.Rows

"complete connect string
Err = 0
sInstance = rngThisDS.Cells(1, 1)
sDS = "Data Source=" & rngThisDS.Cells(1, 2) & ";"
sCatalog = "Initial Catalog=" & rngThisDS.Cells(1, 3) & ";"
sConnect = sProvider & sDS & sUser & sCatalog & sPassword


"attempt to open
cn.Open sConnect

"If successful Then
If Err = 0 Then

"flag success
fSuccess = True

"execute SQL
On Error GoTo ProcError
Set rst = cn.Execute(sSQL)

"copy data into comments sheet
wsData.Range("A2").CopyFromRecordset rst


"Put in the headers
Set rng = wsData.Range("A1")
For x = 1 To rst.Fields.Count
rng.Offset(0, x - 1).Value = rst.Fields(x - 1).Name
Next x
FormatComments
Exit For
End If

Next rngThisDS

If fSuccess = False Then
MsgBox ("Unable to connect to Insight")
Else
MsgBox "Connected to and exported data from " & sInstance
End If

ProcExit:
Set wsData = Nothing
Set rng = Nothing
Set cn = Nothing
Set rst = Nothing
Set rngSQL = Nothing
Set cell = Nothing
Set rngDS = Nothing
Set rngThisDS = Nothing

Exit Sub

ProcError:

MsgBox "Error: " & Err.Description
Resume ProcExit

End Sub

Відповіді:

0 для відповіді № 1

Відповідно до CopyFromRecordset () MSDN:

Коли цей метод копіює набір записів на робочий аркуш, результати буде скорочено, якщо ви не вкажете достатньо великий діапазон тримати вміст набору записів.

Подумайте про визначення діапазону з MoveFirst скидання команд:

" Copy data into comments sheet
rst.MoveLast
rst.MoveFirst
wsData.Range("A2:Z500").CopyFromRecordset rst

Або цілком робочий аркуш (починаючи з A1, звичайно вставляючи рядок для заголовків стовпців)

wsData.Cells.CopyFromRecordset rst

Але навіть тоді CopyFromRecordset() чутливий до даних і бігових типів навітьпам'ять (оскільки ви витягнете всі дані і скиньте відразу), так що розглянете взагалі заміну методу та ітерації за записами для рядків. Навіть інші мови (PHP, Python, Java і т. Д.) Запускають запити таким чином, відкриваючи курсор і повторюючи через resultet.

" Put in the headers
Set rng = wsData.Range("A1")
For x = 1 To rst.Fields.Count
rng.Offset(0, x - 1).Value = rst.Fields(x - 1).Name
Next x

" Put in rows
Dim col As Integer, row As Integer
rst.MoveLast
rst.MoveFirst

Set rng = wsData.Range("A2")
row = 0
Do While Not rst.EOF
For col = 0 To rst.Fields.Count - 1
rng.Offset(row, col).Value = rst(col)
Next col
row = row + 1
rst.MoveNext
Loop