Le problème est CopyFromRecordset
- il tronque à 255 caractères, et ce n'est pas la seule méthode Excel.Range qui fait cela.
La question est :ai-je une méthode qui n'en a pas ? Et avez-vous un pilote OLEDB qui le fait sur votre jeu d'enregistrements avant même d'arriver à l'étape d'écriture dans la plage ?
Vous devez parcourir votre jeu d'enregistrements, dans VBA, et vérifier le champ incriminé dans VBA pour une valeur supérieure à 255 caractères de longueur. Si les champs sont déjà tronqués, essayez d'utiliser les pilotes natifs du client Oracle dans votre chaîne de connexion, au lieu du fournisseur Microsoft Oracle OLEDB - Connections.com disposera des informations.
Une fois que vous savez que le jeu d'enregistrements contient réellement vos données, sans troncature, essayez à nouveau CopyFromRecordset. Je ne m'attends pas à ce qu'il écrive un champ de plus de 255 caractères, mais cela fait un moment que je n'ai pas rencontré l'erreur, elle a peut-être été corrigée et c'est toujours agréable de donner une agréable surprise à un pessimiste.
Ensuite :
Un substitut VBA pour CopyFromRecordset
Il y a trois tâches ici :
- Remplir une variante de tableau VBA avec les données à l'aide de
Recordset.GetRows()
; - Transposez le tableau, car GetRows est dans le mauvais sens pour Excel ;
- Agrandissez une plage cible et écrivez le tableau sous la forme
Range.Value = Array
, une tâche répétitive qui devrait être automatisée dans une routine ArrayToRange().
... Et peut-être un travail auxiliaire avec l'écriture des noms de champs, mais j'ignore cela dans une réponse courte.
Le résultat final est que vous exécutez ce code :
ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)
Transposer le tableau est trivial, mais le voici quand même :
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
...Et ArrayToRange est trivial si vous n'ajoutez pas de vérifications des dimensions du tableau et de préservation des formules dans les cellules cibles :le point essentiel est que vous pouvez écrire vos données en un seul "hit" si les dimensions de la plage correspondent exactement à la dimensions du tableau :
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
Une note de prudence:dans les anciennes versions d'Excel (Office 2000, si je me souviens bien), le tableau "write" était toujours tronqué à 255 caractères. Ce n'est plus un problème; et si vous utilisez toujours XL2000, les cellules contenant une chaîne de plus de 255 caractères sont suffisamment problématiques pour que vous soyez satisfait de la troncature.