Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

A saída da consulta SQL no VBA é diferente do SQL Oracle


O problema é CopyFromRecordset - está truncado em 255 caracteres, e não é o único método Excel.Range que faz isso.

A questão é:eu tenho um método que não tem? E você tem um driver OLEDB que está fazendo isso no seu Recordset antes mesmo de chegar ao estágio de escrever para o intervalo?

Você deve percorrer seu conjunto de registros, no VBA, e verificar o campo incorreto no VBA para um valor superior a 255 caracteres de comprimento. Se os campos já estiverem truncados, tente usar os drivers nativos do Oracle Client em sua string de conexão, em vez do provedor Microsoft Oracle OLEDB - Connections.com terá as informações.

Depois de saber que o conjunto de registros realmente contém seus dados, sem truncamento, tente CopyFromRecordset novamente. Na verdade, não espero que ele escreva um campo com mais de 255 caracteres, mas já faz um tempo desde que encontrei o erro, pode ter sido corrigido e é sempre bom dar uma surpresa agradável a um pessimista.

Próximo:

Um substituto do VBA para CopyFromRecordset


Há três tarefas aqui:
  1. Preencha uma variante de matriz VBA com os dados usandoRecordset.GetRows();
  2. Transponha a matriz, porque GetRows é o caminho errado para o Excel;
  3. Dimensione um intervalo de destino e escreva a matriz comoRange.Value = Array , uma tarefa repetitiva que deve ser automatizada em uma rotina ArrayToRange().

...E talvez algum trabalho auxiliar com a escrita dos nomes dos campos, mas estou ignorando isso em uma resposta curta.

O resultado final é que você executa este código:



    ArrayToRange rngTarget, ArrayTranspose(rst.GetRows)

Transpor a matriz é trivial, mas aqui está de qualquer maneira:

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 é trivial se você não adicionar verificações para dimensões de array e preservar fórmulas nas células de destino:o ponto essencial é que você pode escrever seus dados em um único 'hit' se as dimensões do intervalo corresponderem exatamente ao dimensões da 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

Uma nota de cautela:em versões mais antigas do Excel (Office 2000, se bem me lembro), a matriz 'write' ainda era truncada para 255 caracteres. Isso não é mais um problema; e se você ainda estiver usando o XL2000, as células que contêm uma string com mais de 255 caracteres são um problema suficiente para você ficar satisfeito com o truncamento.