Pergunta

Estou copiando um trecho de código VBA do MSDN que me mostra como resultados da garra de uma consulta SQL em folha de Excel (Excel 2007):

Sub GetDataFromADO()

    'Declare variables'
        Set objMyConn = New ADODB.Connection
        Set objMyCmd = New ADODB.Command
        Set objMyRecordset = New ADODB.Recordset

    'Open Connection'
        objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;"
        objMyConn.Open

    'Set and Excecute SQL Command'
        Set objMyCmd.ActiveConnection = objMyConn
        objMyCmd.CommandText = "select * from myTable"
        objMyCmd.CommandType = adCmdText
        objMyCmd.Execute

    'Open Recordset'
        Set objMyRecordset.ActiveConnection = objMyConn
        objMyRecordset.Open objMyCmd

    'Copy Data to Excel'
        ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

End Sub

Eu já adicionou Microsoft ActiveX Data Objects 2.1 Library sob como uma referência. E esta base de dados é acessível.

Agora, quando eu executar este sub-rotina, que tem um erro:

Erro de tempo de 3704:. A operação não é permitida quando o objeto está fechado

Na declaração:

ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

Qualquer ideia porquê?

Graças.

Foi útil?

Solução

Eu adicionei o catálogo inicial para a seqüência de conexão. Eu também abandonded a sintaxe ADODB.Command em favor de simplesmente criar a minha própria instrução SQL e abrir o conjunto de registos nessa variável.

Espero que isso ajude.

Sub GetDataFromADO()
    'Declare variables'
        Set objMyConn = New ADODB.Connection
        Set objMyRecordset = New ADODB.Recordset
        Dim strSQL As String

    'Open Connection'
        objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=MyDatabase;User ID=abc;Password=abc;"
        objMyConn.Open

    'Set and Excecute SQL Command'
        strSQL = "select * from myTable"

    'Open Recordset'
        Set objMyRecordset.ActiveConnection = objMyConn
        objMyRecordset.Open strSQL            

    'Copy Data to Excel'
        ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

End Sub

Outras dicas

As alterações sugeridas:

  • não invocam o objeto de comando é Executar método;
  • Defina a propriedade Fonte do objeto Recordset para ser seu objeto de comando;
  • Invoke método Open do objeto Recordset sem parâmetros;
  • Remover os parênteses em torno do objeto Recordset na chamada para CopyFromRecordset;
  • Na verdade declarar suas variáveis:)

código revisto:

Sub GetDataFromADO()

    'Declare variables'
        Dim objMyConn As ADODB.Connection
        Dim objMyCmd As ADODB.Command
        Dim objMyRecordset As ADODB.Recordset

        Set objMyConn = New ADODB.Connection
        Set objMyCmd = New ADODB.Command
        Set objMyRecordset = New ADODB.Recordset

    'Open Connection'
        objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;"    
        objMyConn.Open

    'Set and Excecute SQL Command'
        Set objMyCmd.ActiveConnection = objMyConn
        objMyCmd.CommandText = "select * from mytable"
        objMyCmd.CommandType = adCmdText

    'Open Recordset'
        Set objMyRecordset.Source = objMyCmd
        objMyRecordset.Open

    'Copy Data to Excel'
        ActiveSheet.Range("A1").CopyFromRecordset objMyRecordset

End Sub

Eu estou sentado em um computador com nenhum dos bits relevantes do software, mas a partir da memória que o código parece errado. Você está executando o comando, mas descartando a RecordSet que objMyCommand.Execute retornos.

Eu faria:

Set objMyRecordset = objMyCommand.Execute

... e depois perder a parte "aberta de registros".

Isso é uma seqüência de conexão adequada?
Onde está a instância do SQL Server localizado?

Você vai precisar para verificar se você é capaz de conenct ao SQL Server usando a seqüência de conexão, você especificado acima.

EDIT: Olhe para a propriedade do Estado do conjunto de registros para ver se ele é Open
? Além disso, altere a propriedade CursorLocation para adUseClient antes de abrir o conjunto de registros.

Adicionar set nocount on para o início do proc armazenado (se você estiver em SQL Server). Eu só resolveu este problema no meu próprio trabalho e foi causada por resultados intermediários, como "1203 Rows Affected", sendo carregado no Recordset eu estava tentando utilização.

@firedrawndagger: lista de nomes de campos / cabeçalhos de coluna percorrer a coleção Fields de registros e inserir o nome:

Dim myRS as ADODB.Recordset
Dim fld as Field
Dim strFieldName as String 

For Each fld in myRS.Fields
    Activesheet.Selection = fld.Name
    [Some code that moves to next column]
Next
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top