Oracle
 sql >> Base de données >  >> RDS >> Oracle

La sortie de la requête SQL dans VBA est différente de celle de SQL Oracle

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 :

  1. Remplir une variante de tableau VBA avec les données à l'aide de Recordset.GetRows();
  2. Transposez le tableau, car GetRows est dans le mauvais sens pour Excel ;
  3. 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.