Problemet er CopyFromRecordset
- den afkortes ved 255 tegn, og det er ikke den eneste Excel.Range-metode, der gør det.
Spørgsmålet er:har jeg en metode, der ikke har? Og har du en OLEDB-driver, der gør det til dit Recordset, før du overhovedet når til det stadie, hvor du skriver til rækken?
Du bør gå gennem dit rekordsæt i VBA og kontrollere det stødende felt i VBA for en værdi på mere end 255 tegn i længden. Hvis felterne allerede er afkortet, kan du prøve at bruge de oprindelige Oracle Client-drivere i din forbindelsesstreng i stedet for Microsoft Oracle OLEDB-udbyderen - Connections.com vil have oplysningerne.
Når du ved, at postsættet faktisk indeholder dine data uden trunkering, kan du prøve CopyFromRecordset igen. Jeg forventer faktisk ikke, at den skriver et felt, der overstiger 255 tegn, men det er et stykke tid siden, jeg stødte på fejlen, den er måske blevet rettet, og det er altid rart at give en pessimist en behagelig overraskelse.
Næste:
En VBA-erstatning for CopyFromRecordset
Der er tre opgaver her:
- Fyld en VBA-arrayvariant med dataene ved hjælp af
Recordset.GetRows()
; - Transponer arrayet, fordi GetRows er den forkerte vej rundt for Excel;
- Størrelse på et målområde, og skriv arrayet som
Range.Value = Array
, en gentagen opgave, som bør automatiseres i en ArrayToRange() rutine.
...Og måske noget hjælpearbejde med at skrive feltnavnene, men det ignorerer jeg i et kort svar.
Slutresultatet er, at du kører denne kode:
ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)
Transponering af arrayet er trivielt, men her er det alligevel:
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
...Og ArrayToRange er trivielt, hvis du ikke tilføjer checks for matrixdimensioner og bevarer formler i målcellerne:det væsentlige er, at du kan skrive dine data i et enkelt 'hit', hvis dimensionerne af området nøjagtigt matcher dimensioner af arrayet:
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
En advarsel:I ældre versioner af Excel (Office 2000, hvis jeg husker det) er arrayet 'write' stadig afkortet til 255 tegn. Dette er ikke længere et problem; og hvis du stadig bruger XL2000, er celler, der indeholder en streng, der overstiger 255 tegn, et problem nok til, at du kan blive glad for trunkeringen.