bollywood actresses hair loss hair rehab london contact number cheap hair extensions brazilian curly hair with closure hair extension fails human hair wigs black ponytail hairstyles 2018 sunny hair extensions uk hair extensions remy hair extensions weft koko one piece hair extensions clip hair
Transferir dados entre tabelas com campos dos tipos Anexo e Múltiplos Valores

... Assinatura do site por 1 ano + Kit MontaRibbons + 3 Livros em PDF + Diversas Revistas (pdf) de brinde, por apenas R$100,00
(
podendo parcelar em até 10 vezes no cartão de crédito)...

Clique aqui e obtenha mais detalhes do nosso kit completo e de como comprar.


Transferir dados entre tabelas com campos dos tipos Anexo e Múltiplos Valores 

Antes de iniciar sua leitura, clique aqui e cadastre-se para receber comunicados sobre novos artigos.

Novos tipos de campos

Da versão 2007 em diante, dois novos tipos de campos foram inseridos no Access: o campo tipo Anexo e o campo tipo Múltiplos Valores

Usando Access - campo tipo Anexo e múltiplos Valores

Esses dois tipos de campos não são permitidos em consultas de ação de Inclusão (INSERT) e de Alteração (UPDATE).  A razão de não funcionarem com as consultas de ação é que o Access cria tabelas internas para armazenar os dados dos campos.  Além das tabelas, o Access também cria um relacionamento de 1 para Muitos entre a tabela que contém o campo em questão e a tabela interna. 

Para o campo tipo Anexo, o Access cria três campos na tabela interna, de nomes:  FileData, FileName e FileType.  Veja na lista da consulta: 

Usando Access - campo tipo Anexo

Na tabela interna do campo tipo Múltiplos Valores, o campo criado recebe o nome de Value. 

Usando Access - campo tipo Mútiplos Valores

É importante saber esses nomes criados, pois serão utilizados nos códigos oferecidos mais abaixo.

Vamos supor que você tenha criado a seguinte consulta de inserção (INSERT), na qual a tabela_A e a tabela_B  tenham a mesma estrutura e  campos do tipo Anexo e/ou do tipo Múltiplos Valores:

Currentdb.execute "INSERT INTO Tabela_B SELECT * FROM Tabela_A;"

Ao executar a consulta, como era de se esperar, será exibida a seguinte mensagem de falha:

Usando Access - Erro 3824

Qual é a solução para este caso ?

A solução é fazer uso dos Recordset para poder acessar as tabelas internas e  percorrer registro por registro para capturar os dados e realizar a gravação. 

Exemplo fornecido

Para entender como o Recordset  funciona na prática, segue um arquivo exemplo que contém quatro tabelas.  Duas tabelas contendo campo do tipo Anexo e as outras duas contendo campo do tipo Múltiplos Valores. 

Usando Access - Arquivo exemplo


A tabela tblCampoAnexoArquivo receberá os registros da tabela tblCampoAnexo

A tabela tblCampoMultiplosValoresArquivo receberá os registros da tabela tblCampoMultiplosValores

Baixe o arquivo exemplo:

Código exemplo para o campo do tipo Múltiplos Valores

Veja o código utilizado para gravar o campo do tipo Valores Múltiplos.  Leia atentamente os comentários :

Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rsfilho As DAO.Recordset2
Dim rsfilho2 As DAO.Recordset2

CurrentDb.Execute "DELETE * FROM tblCampoValoresMultiplosArquivo;"
'-----------------------------------
'Abre a tabela tblValoresMúltiplos
'------------------------------------
Set rs = CurrentDb.OpenRecordset("tblCampoValoresMultiplos")
'------------------------------------------------------------------
'Abre a tabela tblValoresMultiplosArquivo que receberá os registros
'da tabela tblValoresMúltiplos
'------------------------------------------------------------------
Set rs2 = CurrentDb.OpenRecordset("tblCampoValoresMultiplosArquivo")
'---------------------------------------------------------
'Percorre todos os registros da tabela tblvaloresMultiplos
'---------------------------------------------------------
Do While Not rs.EOF
   '-------------------------------------------------------------
   'Passa os registros da tabela interna, do campo carros para
   'o Recordset rsFilho. Com isso temos acesso aos dados contidos
   'do campo carro.
   '----------------------------------------------------------
   Set rsfilho = rs!carro.Value
   '----------------------------------------------------------------
   'Inicia a gravação dos campos da tabela tblValoresMúltiplos na
   'tabela tblValoresMultilosArquivo
   '---------------------------------------------------------------
   rs2.AddNew
      '-----------------------------------------------------------
      'O Recordset rsFilho2 assume a tabela interna do campo 
      'carro, da tabela tblValoresMultiplosArquivo.
      '----------------------------------------------------------- 
      Set rsfilho2 = rs2!carro.Value
      rs2!Cliente = rs!Cliente
      '-------------------------------------------------------------------
      'Percorre todos os registros da tabela interna do campo carro.
      '-------------------------------------------------------------------     
      Do While Not rsfilho.EOF
         rsfilho2.AddNew
            '------------------------------------------------------------ 
            'A cada registro percorrido, o campo VALUE de uma tabela 
            'interna será gravado na outra tabela interna.
            '------------------------------------------------------------
            rsfilho2!Value = rsfilho!Value
         rsfilho2.Update
         rsfilho.MoveNext
      Loop
   rsfilho2.Close
   rsfilho.Close
   rs2.Update
rs.MoveNext
Loop
rs2.Close
rs.Close
Set rsfilho2 = Nothing
Set rsfilho = Nothing
Set rs2 = Nothing
Set rs = Nothing
MsgBox "Registros transferidos com sucesso para a _
tabela tblCampoValoresMultiplosArquivo...", vbInformation, "Aviso"
DoCmd.OpenTable "tblCampoValoresMultiplosArquivo"

Código exemplo para o campo do tipo Anexo

Agora, observe o código para gravação do campo tipo Anexo.  São necessários dois campos da tabela interna (FlieName e FileData) para realizar a gravação:

Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rsfilho As DAO.Recordset2
Dim rsfilho2 As DAO.Recordset2

CurrentDb.Execute "DELETE * FROM tblCampoAnexoArquivo;"
Set rs = CurrentDb.OpenRecordset("tblCampoAnexo")
Set rs2 = CurrentDb.OpenRecordset("tblCampoAnexoArquivo")
Do While Not rs.EOF
   Set rsfilho = rs!Imagens.Value
   rs2.AddNew
      Set rsfilho2 = rs2!Imagens.Value
      rs2!paciente = rs!paciente
      Do While Not rsfilho.EOF
         rsfilho2.AddNew
            rsfilho2!FileName = rsfilho!FileName
            rsfilho2!FileData = rsfilho!FileData
         rsfilho2.Update
         rsfilho.MoveNext
      Loop
   rsfilho2.Close
   rsfilho.Close
   rs2.Update
   rs.MoveNext
Loop
rs2.Close
rs.Close
Set rsfilho2 = Nothing
Set rsfilho = Nothing
Set rs2 = Nothing
Set rs = Nothing
MsgBox "Registros transferidos com sucesso para a _
tabela tblCampoAnexoArquivo...", vbInformation, "Aviso"
DoCmd.OpenTable "tblCampoAnexoArquivo"

Abra o formulário frmTesteCopiaRegistro e clique nos botões para ver em ação, os códigos aqui apresentados.

Bom estudo!


 

 


22 comentários

Harysohn Pina   12/03/2014 13:51:36

Perfeito Mestre!

Cumprimentos.

Luís Augusto   12/03/2014 19:51:00

Parabéns Avelino!
Toda vez que leio um artigo seu, me surpreendo com o conteúdo e a forma clara com que explica.
Espero que nunca se canse de passar adiante o seu conhecimento.
Um grande abraço.

Atenciosamente, Luís Augusto.

Marcos Santos   12/03/2014 19:59:02

Muito bom!
Meus cumprimentos e agradecimentos, Avelino!

Luiz Carlos Junior   13/03/2014 08:55:12

Mestre dos mestres!

Belgamazzi   13/03/2014 09:24:06

Artigo muito bom. Explicação bem objetiva de facil entendimento...

Ronilson Silva   13/03/2014 10:10:48

Avelino este seu artigo me deu uma ideia para meu projeto. Como sempre nos surpreendendo e compartilhando conosco o seu conhecimento.

Avelino Sampaio   13/03/2014 10:39:37

Fico muito grato pela participação de todos!

Ronilson,

com este código ainda é possível subir e descer arquivo para uma pasta (compo tipo anexo), utilizando os métodos SaveToFile e LoadFromFile

rsfilho2!FileData.SaveToFile (strCaminho)
rsfilho2!FileData.LoadFromFile(strCaminho)

Sucesso!

Juliano   13/03/2014 11:26:23

Muito bom o artigo Avelino, fico na seguinte situação:
Como tratar para que o anexo não seja incorporado, apenas vinculado. Ou seja, utilizo apenas o caminho (string) do arquivo, para quando necessário exibi-lo sem precisar estar incorporado ao banco, "pesando" a minha aplicação?!

Avelino Sampaio   13/03/2014 11:50:11

Juliano,

vá na seção DICAS aqui do site e leia o artigo "Como vincular imagens PNG em botões"

Se pretende abrir um DOC, PDF, PPT, ... Pode utilizar o comando FollowHyperlink

application.FollowHyperlink INDIQUE AQUI O LOCAL DO ARQUIVO

Copie e cole este endereço no seu navegador e veja este caso. (tem que se cadastrar no fórum)

http://maximoaccess.maisforum.com/t17780-resolvidoproblemas-em-colocar-todos-os-arquivos-numa-listbox
Sucesso!

Haroldo Lima   13/03/2014 12:14:25

O Access 365 trabalha com o MSQL na Web?

Juliano   13/03/2014 12:39:46

Este exemplo eu ja conhecia, obrigado. Falo pelo controle "Anexo" porque ele permite múltiplos anexos ao campo, entretanto e infelizmente somente incorporados, não vinculados.
Para contornar isso, teria que ser uma outra tabela apenas para receber estes anexos (string do caminho), onde eu posso utilizar o relacionamento 1 para muitos e depois com FollowHyperlink acessar o arquivo. Bem, quem sabe a microsoft nao muda para as demais versoes e permita o anexo ser vinculado.

WaL   15/03/2014 20:16:17

Valeu pela explicação vou treinar mais. Obrigado.

Ricardo   31/03/2014 19:18:01

Excelente.
Estou a precisar de utilizar o código acima apresentado, mas verificando o seu arquivo de exemplo, os dados não estão a ser carregados nas tabelas... pode verificar por favor.

Avelino Sampaio   01/04/2014 07:06:09

Ricardo,

baixe novamente o aplicativo exemplo. Fiz uma pequena modificação.

Qual é a versão do seu Access ?

No aguardo

Syan   08/07/2015 13:23:32

Olá, gostaria de pedir uma ajuda. Estou tentando aplicar um filtro em um formulário que faz uso de um campo MULTIPLOS VALORES, mas aparece uma mensagem com o seguinte erro: "O campo '[x]' de valores múltiplos não pode ser usado em cláusula WHERE ou HAVING."

Como eu posso aplicar um filtro com esse campo?

Carol   26/08/2015 11:10:11

Syan, eu tive o mesmo problema e pra solucionar eu fiz o seguinte:

Criei uma consulta e lá no critério eu coloquei [MinhaTabela]![CampoMultiplo].[Value] = [Formulários]![MeuFormulario]![CampoDoFormulario]

Ou seja, além de colocar o campo tem que especificar que quer o valor selecionado da lista.

Espero ter ajudado.

José Waldick   08/03/2016 17:37:27

Avelino,
Parabéns pelo material apresentado, excelente!

Adalberto Rosado   06/05/2016 09:56:01

Grande ajuda.
Muito obrigado e parabéns pelo trabalho!

André Silveira   28/08/2016 17:02:05

Avelino, boa tarde!

Tenho que transferir da tabela A para a tabela B todos os registros que estão com o status finalizados e excluindo da tabela A os que foram transferidos, deixando somente os com status em aberto.
Tentei adaptar mas não consegui, isto é possível, conhece algum código?

Obrigado

Flavio Kneipp   19/05/2017 12:29:56

Tentei com o "Código exemplo para o campo do tipo Anexo" e não obtive sucesso.
Criei um Banco com as informações do texto acima, fui em formulário, criei um ícone, cliquei com botão direito, "construir evento, construtor de código" e entrei com o código abaixo.
Só que não passa nem da primeira linha.
Alguém pode me ajudar? Se precisar passo o Banco que criei para sugestões.
flaviokneipp@yahoo.com.br

Private Sub Comando3_Click()

Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rsfilho As DAO.Recordset2
Dim rsfilho2 As DAO.Recordset2

CurrentDb.Execute "DELETE * FROM tblCampoAnexoArquivo;"
Set rs = CurrentDb.OpenRecordset("tblCampoAnexo")
Set rs2 = CurrentDb.OpenRecordset("tblCampoAnexoArquivo")
Do While Not rs.EOF
Set rsfilho = rs!Imagens.Value
rs2.AddNew
Set rsfilho2 = rs2!Imagens.Value
rs2!paciente = rs!paciente
Do While Not rsfilho.EOF
rsfilho2.AddNew
rsfilho2!FileName = rsfilho!Imagens
rsfilho2!FileData = rsfilho!Imagens

rsfilho2.Update
rsfilho.MoveNext
Loop
rsfilho2.Close
rsfilho.Close
rs2.Update
rs.MoveNext
Loop
rs2.Close
rs.Close
Set rsfilho2 = Nothing
Set rsfilho = Nothing
Set rs2 = Nothing
Set rs = Nothing
MsgBox "Registros transferidos com sucesso para a _
tabela tblCampoAnexoArquivo...", vbInformation, "Aviso"
DoCmd.OpenTable "tblCampoAnexoArquivo"

End Sub

Paulo gesse da Costa   30/07/2017 12:05:56

usei seu modulo. deu certo.
tentei adaptar para excluir o anexo e não deu certo. tem alguma sugestão para apagar o anexo pelo mesmo metodo

paulo gesse da costa   31/07/2017 09:48:19

retire o argumento que funciona.
CurrentDb.Execute "DELETE * FROM tblCampoAnexoArquivo;"

não entendi para que serviu esta parte.


Envie seu comentário: