sql >> Base de Datos >  >> RDS >> Oracle

La salida de SQL Query en VBA es diferente a la de SQL Oracle

El problema es CopyFromRecordset - se trunca en 255 caracteres, y no es el único método de Excel.Range que hace eso.

La pregunta es:¿tengo un método que no lo tenga? ¿Y tiene un controlador OLEDB que lo está haciendo en su conjunto de registros incluso antes de llegar a la etapa de escritura en el rango?

Debe recorrer su conjunto de registros, en VBA, y verificar el campo infractor en VBA para un valor superior a 255 caracteres de longitud. Si los campos ya están truncados, intente usar los controladores nativos de Oracle Client en su cadena de conexión, en lugar del proveedor Microsoft Oracle OLEDB:Connections.com tendrá la información.

Una vez que sepa que el conjunto de registros realmente contiene sus datos, sin truncamiento, intente CopyFromRecordset nuevamente. En realidad, no espero que escriba un campo que exceda los 255 caracteres de longitud, pero ha pasado un tiempo desde que encontré el error, podría haberse solucionado y siempre es bueno darle una sorpresa agradable a un pesimista.

Siguiente:

Un sustituto de VBA para CopyFromRecordset

Hay tres tareas aquí:

  1. Rellene una variante de matriz de VBA con los datos usando Recordset.GetRows();
  2. Transponga la matriz, porque GetRows es el camino equivocado para Excel;
  3. Amplíe el tamaño de un rango objetivo y escriba la matriz como Range.Value = Array , una tarea repetitiva que debería automatizarse en una rutina ArrayToRange().

... Y tal vez algún trabajo auxiliar con la escritura de los nombres de los campos, pero lo estoy ignorando en una respuesta breve.

El resultado final es que ejecuta este código:


    ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)

Transponer la matriz es trivial, pero aquí está de todos modos:


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
... Y ArrayToRange es trivial si no agrega controles para las dimensiones de la matriz y conserva fórmulas en las celdas de destino:el punto esencial es que puede escribir sus datos en un solo 'golpe' si las dimensiones del rango coinciden exactamente con el dimensiones de la matriz:

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 de precaución:en versiones anteriores de Excel (Office 2000, si mal no recuerdo) la matriz 'escribir' aún se truncaba a 255 caracteres. Esto ya no es un problema; y si todavía está usando XL2000, las celdas que contienen una cadena que excede los 255 caracteres son un problema suficiente como para que le agrade el truncamiento.