Caros, saudações.
Sou novato no VBA, e estou empacado numa questão: preciso me conectar numa fonte de dados externa, via ODBC, recuperar alguns dados e gravar numa tabela local. Pelas pesquisas que fiz, devo utilizar o ADODB para recuperar os dados, e até aí tudo bem (já estou conseguindo obter os dados e colocá-los num recordset), mas estou com algumas dúvidas quanto à inserção dos dados do recordset na tabela local. Uma forma que encontrei e que funcionou foi utilizar a instrução SQL "INSERT INTO" dentro de uma repetição, para inserir os registros do recordset na tabela um a um. Esse processo é muito lento, tenho gasto cerca de 10 minutos só pra uma tabela. Um exemplo do código:
* adRs é um ADODB.Recordset
* adConn é um ADODB.Connection
* db é um DAO da tabela local
Notem que utilizo o ADODB para obter os dados externos e o DAO para a tabela local. Nessa forma, além de ser lenta, tive um problema na hora de inserir os dados na tabela local (em uma das consultas) ao inserir valores do tipo "double". Por isso pensei em procurar alguma alternativa que fosse mais rápida, e que não precisasse da repetição, que parece ser o que está deixando a execução lenta. Encontrei o que parecia ser uma alternativa: utilizar a função UpdateBatch de um recordset do tipo ADODB. Então eu mudei o código acima para não mais utilizar o tipo DAO:
E não funciona. Acho que me perdi, quando setei o recordset para a tabela local e depois setei o mesmo recordset para receber os dados externos e ainda setei o recordset para apagar os dados da tabela. Como disse inicialmente, sou iniciante em VBA, então não conheço muito bem essas classes. A ideia geral do projeto é: me conectar a fonte externa, executar uma consulta SELECT (isso é imprescindível) para obter os dados e depois inseri-los numa tabela local, e na forma mais rápida e eficiente possível. Este segundo código está no caminho certo? Qual é o jeito certo de se fazer?
Qualquer ajuda será bem vinda.
Obrigado.
Sou novato no VBA, e estou empacado numa questão: preciso me conectar numa fonte de dados externa, via ODBC, recuperar alguns dados e gravar numa tabela local. Pelas pesquisas que fiz, devo utilizar o ADODB para recuperar os dados, e até aí tudo bem (já estou conseguindo obter os dados e colocá-los num recordset), mas estou com algumas dúvidas quanto à inserção dos dados do recordset na tabela local. Uma forma que encontrei e que funcionou foi utilizar a instrução SQL "INSERT INTO" dentro de uma repetição, para inserir os registros do recordset na tabela um a um. Esse processo é muito lento, tenho gasto cerca de 10 minutos só pra uma tabela. Um exemplo do código:
* adRs é um ADODB.Recordset
* adConn é um ADODB.Connection
* db é um DAO da tabela local
- Código:
'executa consulta
Set adRs = adConn.Execute("SELECT * FROM TIPO;")
'atualiza status e atualiza tabela
If Not IsNull(adRs) Then
'limpa dados da tabela desatualizada
If Not IsNull(DLookup("Name", "MSysObjects", "Name='TIPO'")) Then
Application.DoCmd.SetWarnings False
db.Execute ("DELETE * FROM TIPO"), dbFailOnError
Application.DoCmd.SetWarnings True
End If
'popula tabela com recordset
Do Until adRs.EOF
db.Execute ("INSERT INTO TIPO (ID_TIPO, SIGLA, DESCRICAO) " & _
" VALUES (" & adRs![ID_TIPO] & ", '" & LTrim(RTrim(adRs![SIGLA])) & "', '" & Replace(LTrim(RTrim(adRs![DESCRICAO])), "'", "''") & "');"), dbFailOnError
adRs.MoveNext
Loop
'verifica se tabela foi populada
If Not IsNull(DLookup("Name", "MSysObjects", "Name='TIPO'")) Then
Set adRs = Nothing
Else
Set adRs = Nothing
Msgbox("Erro ao atualizar tabela local TIPO!")
End If
Else
Set adRs = Nothing
Msgbox("Erro na importação dos dados tabela TIPO!")
End If
Notem que utilizo o ADODB para obter os dados externos e o DAO para a tabela local. Nessa forma, além de ser lenta, tive um problema na hora de inserir os dados na tabela local (em uma das consultas) ao inserir valores do tipo "double". Por isso pensei em procurar alguma alternativa que fosse mais rápida, e que não precisasse da repetição, que parece ser o que está deixando a execução lenta. Encontrei o que parecia ser uma alternativa: utilizar a função UpdateBatch de um recordset do tipo ADODB. Então eu mudei o código acima para não mais utilizar o tipo DAO:
- Código:
Dim connLocal As ADODB.Connection
Dim connExterna As ADODB.Connection
'recordset
Dim adoRS As ADODB.Recordset
'instancia conexao local
Set connLocal = New ADODB.Connection
connLocal.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Application.CurrentProject.Path & "\BDGC.accdb"
Set adoRS = New ADODB.Recordset
adoRS.Open "TIPO", connLocal, adOpenKeyset, adLockOptimistic, acCmdTable
'instancia conexao externa
Set connExterna = New ADODB.Connection
connExterna .ConnectionTimeout = 30
connExterna .Open Conexao, Usuario, Senha
'verifica se conexao foi aberta
If connExterna.State = adStateOpen Then
'executa consulta e seta recordset local
Set adoRS = connExterna.Execute("SELECT * FROM TIPO;")
'atualiza tabela
If Not IsNull(adoRS) Then
'apaga dados desatualizados
adoRS.Open "DELETE * FROM TIPO", connLocal, adOpenKeyset, adLockOptimistic, adCmdText
'insere dados na tabela
adoRS.MoveFirst
adoRS.UpdateBatch
'verifica se tabela foi populada
If Not IsNull(DLookup("Name", "MSysObjects", "Name='TIPO'")) Then
adoRS.Close
Set adoRS = Nothing
Else
Msgbox("Erro ao atualizar tabela local TIPO!")
End If
Else
Msgbox("Erro na importação dos dados tabela TIPO!")
End If
Else
Msgbox("Erro na conexao externa!")
End If
E não funciona. Acho que me perdi, quando setei o recordset para a tabela local e depois setei o mesmo recordset para receber os dados externos e ainda setei o recordset para apagar os dados da tabela. Como disse inicialmente, sou iniciante em VBA, então não conheço muito bem essas classes. A ideia geral do projeto é: me conectar a fonte externa, executar uma consulta SELECT (isso é imprescindível) para obter os dados e depois inseri-los numa tabela local, e na forma mais rápida e eficiente possível. Este segundo código está no caminho certo? Qual é o jeito certo de se fazer?
Qualquer ajuda será bem vinda.
Obrigado.