Oracle
 sql >> Database >  >> RDS >> Oracle

L'output della query SQL in VBA è diverso da quello in SQL Oracle

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:

  1. Popolare una variante dell'array VBA con i dati utilizzando Recordset.GetRows();
  2. Traspone l'array, perché GetRows è il modo sbagliato per Excel;
  3. Ridimensiona un intervallo target e scrivi l'array comeRange.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.