Проблемът е CopyFromRecordset
- съкращава се на 255 символа и не е единственият метод на Excel.Range, който прави това.
Въпросът е:имам ли метод, който не го прави? И имате ли OLEDB драйвер, който го прави с вашия набор от записи, преди дори да стигнете до етапа на запис в диапазона?
Трябва да преминете през набора от записи във VBA и да проверите неправилното поле във VBA за стойност над 255 символа по дължина. Ако полетата вече са съкратени, опитайте да използвате собствените драйвери на Oracle Client във вашия низ за връзка, вместо доставчика на Microsoft Oracle OLEDB - Connections.com ще има информацията.
След като разберете, че наборът от записи действително съдържа вашите данни, без съкращаване, опитайте отново CopyFromRecordset. Всъщност не очаквам да напише поле с дължина над 255 символа, но мина известно време, откакто се сблъсках с грешката, може да е била коригирана и винаги е хубаво да направиш приятна изненада на песимиста.
Следва:
VBA заместител на CopyFromRecordset
Тук има три задачи:
- Попълване на вариант на VBA масив с данните чрез
Recordset.GetRows()
; - Транспонирайте масива, тъй като GetRows е грешен начин за кръг за Excel;
- Увеличете размера на целеви диапазон и запишете масива като
Range.Value = Array
, повтаряща се задача, която трябва да бъде автоматизирана в рутина ArrayToRange().
...И може би някаква спомагателна работа с писане на имената на полетата, но пренебрегвам това в кратък отговор.
Крайният резултат е, че изпълнявате този код:
ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)
Транспонирането на масива е тривиално, но все пак ето го:
Public Function ArrayTranspose(InputArray As Variant) As Variant
Application.Volatile False
Dim arrOutput As Variant
Dim i As Long
Dim j As Long
Dim iMin As Long
Dim iMax As Long
Dim jMin As Long
Dim jMax As Long
iMin = LBound(InputArray, 1)
iMax = UBound(InputArray, 1)
jMin = LBound(InputArray, 2)
jMax = UBound(InputArray, 2)
ReDim arrOutput(jMin To jMax, iMin To iMax)
For i = iMin To iMax
For j = jMin To jMax
arrOutput(j, i) = InputArray(i, j)
Next j
Next i
ArrayTranspose = arrOutput
End Function
...И ArrayToRange е тривиален, ако не добавите проверки за размери на масива и запазване на формули в целевите клетки:същественото е, че можете да запишете данните си в едно „ударение“, ако размерите на диапазона съвпадат точно с размери на масива:
Public Sub ArrayToRange(rngTarget As Excel.Range, InputArray As Variant) ' Write an array to an Excel range in a single 'hit' to the sheet ' InputArray should be a 2-Dimensional structure of the form Variant(Rows, Columns)
' The target range is resized automatically to the dimensions of the array, with ' the top left cell used as the start point.
' This subroutine saves repetitive coding for a common VBA and Excel task.
' Author: Nigel Heffernan http://Excellerando.blogspot.com
On Error Resume Next
Dim rngOutput As Excel.Range
Dim iRowCount As Long Dim iColCount As Long
iRowCount = UBound(InputArray, 1) - LBound(InputArray, 1) iColCount = UBound(InputArray, 2) - LBound(InputArray, 2)
With rngTarget.Worksheet
Set rngOutput = .Range(rngTarget.Cells(1, 1), _ rngTarget.Cells(iRowCount + 1, iColCount + 1))
Application.EnableEvents = False
rngOutput.Value2 = InputArray
Application.EnableEvents = True
Set rngTarget = rngOutput ' resizes the range This is useful, most of the time
End With ' rngTarget.Worksheet
End Sub
Бележка за внимание:в по-старите версии на Excel (Office 2000, ако си спомням) масивът "write" все още е съкратен до 255 знака. Това вече не е проблем; и ако все още използвате XL2000, клетките, съдържащи низ, надвишаващ 255 знака, са достатъчен проблем, че може да се радвате на съкращаването.