Problemem jest CopyFromRecordset
- obcina do 255 znaków i nie jest to jedyna metoda Excel.Range, która to robi.
Pytanie brzmi:czy mam metodę, która tego nie robi? A czy masz sterownik OLEDB, który robi to z twoim zestawem rekordów, zanim jeszcze dojdziesz do etapu zapisywania do zakresu?
Powinieneś przejść przez swój zestaw rekordów w VBA i sprawdzić nieprawidłowe pole w VBA dla wartości przekraczającej 255 znaków. Jeśli pola są już obcięte, spróbuj użyć rodzimych sterowników klienta Oracle w ciągu połączenia, zamiast dostawcy Microsoft Oracle OLEDB - Connections.com będzie mieć informacje.
Gdy już wiesz, że zestaw rekordów faktycznie zawiera Twoje dane, bez obcinania, spróbuj ponownie skopiować CopyFromRecordset. Właściwie nie spodziewam się, że napisze pole o długości przekraczającej 255 znaków, ale minęło trochę czasu, odkąd natknąłem się na błąd, mógł zostać naprawiony i zawsze miło jest sprawić pesymiście miłą niespodziankę.
Dalej:
Zamiennik VBA dla CopyFromRecordset
Są tu trzy zadania:
- Wypełnij wariant tablicy VBA danymi za pomocą
Recordset.GetRows()
; - Transponuj tablicę, ponieważ GetRows jest niewłaściwym sposobem 'zaokrąglania forExcel;
- Zwymiaruj zakres docelowy i zapisz tablicę jako
Range.Value = Array
, powtarzające się zadanie, które powinno być zautomatyzowane w procedurze ArrayToRange().
...I może trochę pracy pomocniczej z zapisywaniem nazw pól, ale ignoruję to w krótkiej odpowiedzi.
Efektem końcowym jest uruchomienie tego kodu:
ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)
Transpozycja tablicy jest trywialna, ale i tak jest:
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
... A ArrayToRange jest trywialne, jeśli nie dodasz kontroli wymiarów tablicy i nie zachowasz formuł w komórkach docelowych:najważniejsze jest to, że możesz zapisać swoje dane w jednym „trafieniu”, jeśli wymiary zakresu dokładnie odpowiadają wymiary tablicy:
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
Uwaga:w starszych wersjach programu Excel (Office 2000, jeśli sobie przypominam) tablica „write” nadal jest obcięta do 255 znaków. To już nie jest problem; a jeśli nadal używasz XL2000, komórki zawierające ciąg przekraczający 255 znaków są wystarczającym problemem, że możesz być zadowolony z obcięcia.