Il problema è CopyFromRecordset
- sta troncando a 255 caratteri e non è l'unico metodo Excel.Range che lo fa.
La domanda è:ho un metodo che non lo fa? E hai un driver OLEDB che lo sta facendo sul tuo Recordset prima ancora di arrivare alla fase di scrittura sull'intervallo?
Dovresti scorrere il recordset, in VBA, e controllare il campo offensivo in VBA per un valore di lunghezza superiore a 255 caratteri. Se i campi sono già troncati, prova a utilizzare i driver Oracle Client nativi nella stringa di connessione, invece del provider Microsoft Oracle OLEDB:Connections.com avrà le informazioni.
Una volta che sai che il recordset contiene effettivamente i tuoi dati, senza troncamento, prova di nuovo CopyFromRecordset. In realtà non mi aspetto che scriva un campo che superi i 255 caratteri di lunghezza, ma è passato un po' di tempo da quando ho riscontrato l'errore, potrebbe essere stato corretto ed è sempre bello fare una piacevole sorpresa a un pessimista.
Prossimo:
Un sostituto VBA per CopyFromRecordset
Ci sono tre attività qui:
- Popolare una variante dell'array VBA con i dati utilizzando
Recordset.GetRows()
; - Traspone l'array, perché GetRows è il modo sbagliato per Excel;
- Ridimensiona un intervallo target e scrivi l'array come
Range.Value = Array
, un'attività ripetitiva che dovrebbe essere automatizzata in una routine ArrayToRange().
...E forse qualche lavoro ausiliario con la scrittura dei nomi dei campi, ma lo sto ignorando in una breve risposta.
Il risultato finale è che esegui questo codice:
ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)
Trasporre l'array è banale, ma eccolo comunque:
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
...E ArrayToRange è banale se non si aggiungono controlli per le dimensioni dell'array e si preservano le formule nelle celle target:il punto essenziale è che puoi scrivere i tuoi dati in un singolo 'hit' se le dimensioni dell'intervallo corrispondono esattamente al dimensioni della matrice:
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
Una nota di cautela:nelle versioni precedenti di Excel (Office 2000, se ricordo bene) l'array "write" veniva ancora troncato a 255 caratteri. Questo non è più un problema; e se stai ancora utilizzando XL2000, le celle contenenti una stringa superiore a 255 caratteri sono un problema sufficiente per farti essere contento del troncamento.