Notifications
Clear all

Bloquear acesso ao Access enquanto a macro atualiza

9 Posts
3 Usuários
0 Reactions
1,681 Visualizações
(@robo8268)
Posts: 73
Trusted Member
Topic starter
 

Boa tarde pessoal tudo bem?

Tenho um banco de dados Access na rede, que uso como back end entre o sql e o excel, pois conectando o excel com o sql, a busca fica extremamente lenta, então preferi colocar os dados já processados no access para melhorar a performance.

Esse banco atualiza a cada meia hora, e a cada atualização, ele exclui a tabela do mês atual, e cria uma nova com os dados atualizados.

Cada usuario tem uma planilha que conecta com esse banco access e atualiza as informações.

Porém da erro quando o usuario puxa os dados durante a atualização, e eu gostaria de bloquear esse acesso enquanto a macro de atualização está rodando no access, e dar uma mensagem tipo "dados em atualização, tente novamente daqui a 1 minuto".

Como eu posso fazer isso?

Obs: não tenho como colocar arquivo de exemplo, porque estou no trabalho e é bloqueado.

Segue o código usado:
Excel

Public Sub conexaoNice()
Dim sheetMeta As Worksheet, sheetCalculo As Worksheet
Dim cnx As ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd As ADODB.Command
Dim nomeTabela As String, sql As String, mes As String, firstName As String
Dim insert As Variant, dados() As Variant
Dim contagem As Integer, posicao As Integer
posicao = 0

mes = Sheets("Cálculo Monitoria").Range("mes").Value
nomeTabela = criarNomeTabela(mes)

insert = inserts()


Application.StatusBar = "Conectando com o NICE..."
usuario = Sheets("Cálculo Monitoria").Range("usuario").Value



'sql = "Select top 1 iEvalID from vwNiceDBKITEvaluationQuestions where iEvalID is not null"
Set sheetMeta = ThisWorkbook.Sheets("Metas")
Set sheetCalculo = ThisWorkbook.Sheets("Cálculo Monitoria")


Set cnx = New ADODB.Connection

  
  'iniciando o objeto da conexão
  Set cnx = New ADODB.Connection
  
  'atribuindo as propriedades de conexão (servidor,nome do banco, usuário, senha e etc)
  'cnx.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\fswcorp\CEICACCMONITQUAL4. Operações Terceirizadas - Vanessa SilvaMonitoria Qualidade AtendimentoProdutividadeProdutividade Equipe Vanessa.accdb;Extended Properties =Excel 8.0;HDR=YES"
  With cnx
     .Provider = "Microsoft.ACE.OLEDB.12.0"
     .Open "\fswcorp\CEICACCMONITQUAL4. Operações Terceirizadas - Vanessa SilvaMonitoria Qualidade AtendimentoProdutividadeProdutividade Equipe Vanessa.accdb"
     .CursorLocation = adUseClient
     
  End With
  
  'iniciando o comando
  Set cmd = New ADODB.Command
  firstName = Mid(usuario, 1, InStr(1, usuario, " ") - 1)
  With cmd
    .CommandTimeout = 0 'propriedade para não dar erro de Time Out quando a query demorar para executar
    .ActiveConnection = cnx  'dizendo ao comando que a conexão que será usada é a cnx
  End With
  
  cmd.CommandText = "drop Table celulas" & firstName
  On Error Resume Next
  cmd.Execute
  
  
  cmd.CommandText = "Create Table celulas" & firstName & "(Celula Varchar(50))"
  cmd.Execute
  
  For i = 1 To UBound(insert)
    cmd.CommandText = insert(i)
    cmd.Execute
  Next i

  
  sql = Query(nomeTabela, firstName)
  cmd.CommandText = sql
  
  'executando o comando e armazenando o resultado no recordset
  Set rs = New ADODB.Recordset
  With rs
     .CursorLocation = adUseClient
     .CursorType = adOpenStatic
     
  End With
  
  Set rs = cmd.Execute
  
  
  contagem = rs.RecordCount
  ReDim dados(1 To contagem, 1 To 4)
  
  dados = rs.GetRows

  
  For i = 1 To contagem
  If IsNull(dados(1, posicao)) Then
    dados(1, posicao) = 0
  End If
     Sheets("Cálculo Monitoria").Range("Celulas").Cells(i).Offset(0, 2) = dados(1, posicao)
     posicao = posicao + 1

  Next i
  
  
  rs.Close
  On Error Resume Next
  cmd.CommandText = "drop table celulas" & firstName

   
   cnx.Close
Application.StatusBar = ""
Exit Sub


End Sub

Access

Public Sub Conexão()
   Dim sql As String, data As String, id As String, analista As String, celula As String, nomeTabela As String
   Dim cnx As ADODB.Connection, rs As ADODB.Recordset, cmd As ADODB.Command
   Dim dados As Variant
   Dim numeroRegistros As Double
   
   nomeTabela = criarNomeTabela()
   sql = Query()
   
   Set cnx = New ADODB.Connection
   Set cmd = New ADODB.Command
   
   cnx.ConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=True;User ID=dbkit;Password=dbkit123;Initial Catalog=nice_dw;Data Source=svtt006cto;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=500010288757-IS;Use Encryption for Data=False;Tag with column collation when possible=False"
   With cnx
     .CursorLocation = adUseClient
   End With
   
   cnx.Open
   
   With cmd
      .CommandText = sql
      .CommandTimeout = 0
      .ActiveConnection = cnx
   End With
   Set rs = New ADODB.Recordset
   
   With rs
      .CursorLocation = adUseClient
      .CursorType = adOpenStatic
   End With
   
  
   
   Set rs = cmd.Execute
   numeroRegistros = rs.RecordCount
   
   ReDim dados(numeroRegistros, 4)
   
   dados = rs.GetRows
   On Error Resume Next
   CurrentDb.Execute "DROP TABLE " & nomeTabela
   
   CurrentDb.Execute "CREATE TABLE " & nomeTabela & " (Data Varchar(10),ID Varchar(10), Analista Varchar(50), Célula Varchar(50))"
   
   For i = 0 To numeroRegistros
      data = dados(0, i)
      id = dados(1, i)
      analista = dados(2, i)
      celula = dados(3, i)
      CurrentDb.Execute "INSERT INTO " & nomeTabela & "(Data,ID,Analista,Célula) VALUES (" & Chr(34) & data & Chr(34) & "," & Chr(34) & id & Chr(34) & "," & Chr(34) & analista & Chr(34) & "," & Chr(34) & celula & Chr(34) & ")"
   Next i
   
   

End Sub

Obrigado.

 
Postado : 26/02/2016 8:32 am
(@mprudencio)
Posts: 2749
Famed Member
 

Tente assim:

Apos essa parte do codigo


mes = Sheets("Cálculo Monitoria").Range("mes").Value
nomeTabela = criarNomeTabela(mes)

insert = inserts()

Cole essas:


On Error GoTo Erro

Erro:

MsgBox "Dados em Atualização..." & Chr(13) & Chr(13) & "Tente Daqui 1 Minuto.", vbInformation, "Atualizando Tabela..."

Exit Sub

Não testei mas deve funcionar

Marcelo Prudencio
Microsoft Excel Brasil no Facebook

"Começar já é a metade do caminho."
Autor Desconhecido

Simplifica que simples fica.
Nicole Tomazella.

"O Simples é Sempre Melhor Que o Complicado"
Jorge Paulo Lemann.

 
Postado : 26/02/2016 11:12 am
(@robo8268)
Posts: 73
Trusted Member
Topic starter
 

Marcelo, primeiramente obrigado pela resposta... um tratamento de erros nesse caso até funciona, só que a minha macro enquanto o access atualiza, ele armazena os resultados da consulta em um recordset, depois eu gravo este recordset em um array, e por fim eu faço um for nesse array fazendo vários inserts na tabela até o ultima posição.

Dessa forma, o usuário iria conseguir puxar os dados antes do término da atualização caso o for esteja rodando no exato momento, pois são milhares de registros.

na verdade eu precisaria no caso de uma função para bloquear o acesso e depois liberar após o término da execução de toda a macro...

Obrigado.

 
Postado : 26/02/2016 11:37 am
(@mprudencio)
Posts: 2749
Famed Member
 

Mas não é exatemente esse a causa do erro??? Enquanto esta atualizando travar pq o usuario quer acessar o banco de dados, o tratamento de erro solicita que o usuario tente o acesso apos a atualização.
Se eu entendi enquanto e, esta atualizando o usuario nao pode acessar o bd pq a tabela onde ele busca os dados nao existe, e isso gera o erro.

Estou imaginando que vc tenha feito a programação da seguinte maneira, exclui a tabela anterior e vc tem uma consulta criar tabela, ou seja ele cria uma nova com os mesmos parametros atualizando os dados novos.

Pq ao inves de excluir a tabela vc nao exclui apenas os dados ( a tabela continua existindo, e teoricamente não causaria o erro), assim vc pode atualizar carregando os dados novamente, como ja faz hoje, talvez funcione.

Marcelo Prudencio
Microsoft Excel Brasil no Facebook

"Começar já é a metade do caminho."
Autor Desconhecido

Simplifica que simples fica.
Nicole Tomazella.

"O Simples é Sempre Melhor Que o Complicado"
Jorge Paulo Lemann.

 
Postado : 26/02/2016 12:05 pm
(@robo8268)
Posts: 73
Trusted Member
Topic starter
 

Marcelo, obrigado novamente...

Acontece que estas planilha é uma planilha de produtividade, onde o usuario puxa os dados e consolida os totais.

Caso a macro tenha criado a tabela porém não terminou de inserir os dados, o usuario poderá puxar dados incorretos.

Não conheço nenhuma forma de excluir apenas os dados, sei que no sql é o comando truncate, porém não conheço nenhum equivalente no Access...

 
Postado : 26/02/2016 12:24 pm
EdsonBR
(@edsonbr)
Posts: 1057
Noble Member
 

Boa tarde, robo8268

E se vc usasse, no lugar que vc quer bloquear o acesso ao Excel o

Application.Interactive = False

lembrando de religá-lo com True depois.

Talvez também o uso da função "DoEvents", mas não estou seguro disso no seu caso.

 
Postado : 26/02/2016 12:27 pm
(@mprudencio)
Posts: 2749
Famed Member
 

Bom pessoalmente meu modesto conhecimento de VBA e Acess acabam aqui

Mas para excluir os dados como sugerir vc pode tentar assim:

https://support.office.com/pt-br/articl ... 52cd4c3ec5

Ou tentar assim ( nao testei este). http://comunidade.itlab.com.br/eve/foru ... 8781027652

Marcelo Prudencio
Microsoft Excel Brasil no Facebook

"Começar já é a metade do caminho."
Autor Desconhecido

Simplifica que simples fica.
Nicole Tomazella.

"O Simples é Sempre Melhor Que o Complicado"
Jorge Paulo Lemann.

 
Postado : 26/02/2016 1:08 pm
(@robo8268)
Posts: 73
Trusted Member
Topic starter
 

Edson, na verdade o que eu preciso bloquear é o access e não o excel..

Obrigado pela resposta

 
Postado : 29/02/2016 12:21 pm
(@robo8268)
Posts: 73
Trusted Member
Topic starter
 

Pessoal, fiz um teste com a macro rodando, e o próprio access bloqueou o acesso sem eu fazer nada, acredito que por causa da configuração de segurança padrão.
Nesse caso, o tratamento de erros conforme o MPrudencio sugeriu, resolveu o meu problema. Muito obrigado pela ajuda de vocês.

 
Postado : 29/02/2016 12:50 pm