none
Ler arquivos do excel e apagar xls em seguida

    Question

  • Olá,

     

    Estou com certos problemas para apagar um arquivo do excel logo após ler os dados.

     

    Abaixo as partes relevants do código

     

    Private con As OleDbConnection
    Private con As OleDbConnection
    
    ...
    
    Public Sub open(ByVal arquivo As String)
    
        conexao_string = "Provider=Microsoft.Jet.OleDb.4.0;data source=" & arquivo & ";Extended Properties=Excel 8.0;"
        con = New OleDbConnection(conexao_string)
        con.Open()
    
    End Sub
    
    ....
    
    Public Sub getDados(ByVal tab As String)
    
        Dim dbAdapter As New OleDbDataAdapter("SELECT * FROM [" & tab & "]", con)
    
        dt = New DataTable()
        dbAdapter.Fill(dt)
        dbAdapter.Dispose()
        dbAdapter = Nothing
    
    End Sub
    
    ....
    
    Public Function getCellValue(ByVal linha As Integer, ByVal coluna As Integer)
    
        Return dt.Rows(linha).Item(coluna) & ""
    
    End Function
    
    ...
    
    Public Sub close()
    
        If Not con Is Nothing Then
          con.Close()
          con.Dispose()
        End If
    
        If Not dt Is Nothing Then
          dt.Dispose()
        End If
    
        con = Nothing
        dt = Nothing
    
        GC.Collect()
    
        MyBase.Finalize()
    
    End Sub

    Eu abro o arquivo chamando o método open, leio o que for necessário e depois chamo o método close.

     

    Mesmo após dar close no objeto e chamar File.Delete(NomeArquivo) aparece a seguinte mensagem: The process cannot access the file NomeArquivo The process cannot access the file .

    Por que mesmo após fechar a conexão e os dados não consigo apagar o arquivo? O que poderia estar travando o mesmo?

     

    Uma observação é que dependendo do número de linhas que eu leio no arquivo eu consigo deletar após chamar o método close.

     

    Agradeço pela ajuda desde já.

     

    Rafael

     

    Tuesday, April 26, 2011 2:45 PM

Answers

  • Olá todos,

    Só gostaria de informar que consegui encontrar a solução. Quando eu fecho a conexão logo após preencher o DataTable e apago o arquivo logo em seguida, funciona.

    Exemplo considerando a estrutura que coloquei no primeiro post:

    Dim excel As New ExcelReader()
    
    excel.open(arquivo)
    
    excel.getDados(tab)

    excel.close() excel = Nothing File.Delete(arquivo)
    'Pega total de linhas no excel Dim totalNumRegistros = excel.getNumRegistros() While totalNumRegistros > linha 'Pega os dados de uma linha data = excel.getCellValue(linha, 0) taxa1 = excel.getCellValue(linha, 1) taxa2 = excel.getCellValue(linha, 2) preco1 = excel.getCellValue(linha, 3) preco2 = excel.getCellValue(linha, 4) base = excel.getCellValue(linha, 5) linha = linha + 1 End While

    A única diferença é que no método close não posso mais dar dispose() no DataTable. Mesmo fechando a conexão o DataTable, continua com os valores desejados e consigo apagar o arquivo normalmente.

     

    Obrigado a todos pela atenção e pela ajuda.

     

    Rafael 

     

    • Proposed as answer by Rui SantosModerator Thursday, April 28, 2011 2:37 PM
    • Marked as answer by rafpv Thursday, April 28, 2011 3:00 PM
    Wednesday, April 27, 2011 6:41 PM

All replies

  • Rafael,

    Você pode postar pra gente a parte em que você dá o Delete? É exatamente essa mensagem de erro que você está recebendo?


    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima
    Tuesday, April 26, 2011 3:40 PM
  • Olá André,

    Obrigado pela resposta.

     

    Isto que eu postei é apena uma parte de uma classe que estou utilizando. A chamada mesmo é feita em outra classe.Abaixo a parte do código que faz a leitra dos dados do excel.

     

    Dim excel As New ExcelReader()
    
    excel.open(arquivo)
    
    excel.getDados(tab)
    
    'Pega total de linhas no excel
    Dim totalNumRegistros = excel.getNumRegistros()
    
    While totalNumRegistros > linha
    
       'Pega os dados de uma linha
       data = excel.getCellValue(linha, 0)
       taxa1 = excel.getCellValue(linha, 1)
       taxa2 = excel.getCellValue(linha, 2)
       preco1 = excel.getCellValue(linha, 3)
       preco2 = excel.getCellValue(linha, 4)
       base = excel.getCellValue(linha, 5)
    
       linha = linha + 1
    
    End While
    
    excel.close()
    
    excel = Nothing
    
    File.Delete(arquivo)

    Em relação a mensagem de erro é esta mesmo.

    IOException was unhandled

    The process cannot access the file 'NomeArquivo' because it is being used by another process.

    Mesmo fechando as conexões e destruindo a classe, ainda existe algo que prende o arquivo e não consigo descobrir o que é.

    Se também houver uma forma de forçar o arquivo a ficar desbloqueado também serve, mas o correto seria ao dar close na conexão e na classe o arquivo ficasse liberado.

     

    Obrigado pela atenção!

    Tuesday, April 26, 2011 4:49 PM
  • Rafael,

    Estranho hein... Tem certeza que algum outro processo não está bloqueando esse arquivo? Fiz um teste aqui com o código que você postou (só que sem criar uma classe para fazer a leitura do xls) e funcionou normalmente... Tente aí (está em C#, mas, acredito que você vai entender perfeitamente o que está sendo feito):

    OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.Jet.OleDb.4.0;data source=c:\new folder\book1.xls;Extended Properties=Excel 8.0;");
    conn.Open();
    OleDbDataAdapter adp = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", conn);
    DataTable dt = new DataTable();
    adp.Fill(dt);
    
    int total = 0;
    
    foreach (DataRow row in dt.Rows)
      total += (int)(double)row[0];
    
    adp.Dispose();
    adp = null;
    conn.Close();
    dt.Dispose();
    conn = null;
    dt = null;
    
    File.Delete(@"c:\new folder\book1.xls");
    

    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima
    Tuesday, April 26, 2011 5:21 PM
  • Por acaso a pasta onde esta esse arquivo... não seria apenas "somente-leitura" ?

    é uma aplicação ASP.NET ? se for... qual usuario esta configurado no servidor IIS ? esse usuario teria permissão para excluir o arquivo ?

    Tuesday, April 26, 2011 6:17 PM
  • André,

     

    Creio que não existe outro processo bloqueando até porque eu fiz alguns testes especiais. Por exemplo, em qualquer lugar antes do while, se eu der close e File.Delete, funciona normalmente. Se eu colocar um breakpoint dentro do While, forçar um close e um File.Delete, também funciona.

    Em outro teste eu limitei o número de repetições do loop para apenas 50 (os arquivos geralmente possuem entre 250 e 350 linhas) e rodei o programa. Funcionou normalmente. O erro aconetece quando tenho que ler todas as linhas. Posso estar pensando errado, mas existe a possibilidade de ser algo relacionado a memória quando é preciso ler todas as linhas?

    Apenas para ter certeza em relação aos processos, existe uma forma de ver quais processos estão utilizando o arquivo? Se tiver posso verificar para garantir.

    Edição: Fiz um teste bem parecido com o seu,  sem usar a classe e o problema ocorre da mesma forma, mas seu eu "pular" o while, consigo apagar o arquivo normalmente. Talvez executar o comando dt.Rows(linha).Item(coluna) esteja causando o problema de alguma forma?

    Rui,

    O arquivo não está como "somente-leitura" não. Eu faço download do arquivo de um servidor, escrevo em uma pasta, leio o que preciso e apago. Se logo após o download eu tentar apagar o arquivo, eu consigo. O problema é após fazer vários loops durante a leitura do arquivo, não consigo mais apagar ele, pois o processo de alguma forma ainda bloqueia o arquivo.

    A aplicação é em VB.net e é desktop.

     

    Obrigado pela atenção.

     

    Rafael

     

     


    • Edited by rafpv Tuesday, April 26, 2011 7:42 PM Adicionando teste de código.
    Tuesday, April 26, 2011 7:30 PM
  • Olá todos,

    Só gostaria de informar que consegui encontrar a solução. Quando eu fecho a conexão logo após preencher o DataTable e apago o arquivo logo em seguida, funciona.

    Exemplo considerando a estrutura que coloquei no primeiro post:

    Dim excel As New ExcelReader()
    
    excel.open(arquivo)
    
    excel.getDados(tab)

    excel.close() excel = Nothing File.Delete(arquivo)
    'Pega total de linhas no excel Dim totalNumRegistros = excel.getNumRegistros() While totalNumRegistros > linha 'Pega os dados de uma linha data = excel.getCellValue(linha, 0) taxa1 = excel.getCellValue(linha, 1) taxa2 = excel.getCellValue(linha, 2) preco1 = excel.getCellValue(linha, 3) preco2 = excel.getCellValue(linha, 4) base = excel.getCellValue(linha, 5) linha = linha + 1 End While

    A única diferença é que no método close não posso mais dar dispose() no DataTable. Mesmo fechando a conexão o DataTable, continua com os valores desejados e consigo apagar o arquivo normalmente.

     

    Obrigado a todos pela atenção e pela ajuda.

     

    Rafael 

     

    • Proposed as answer by Rui SantosModerator Thursday, April 28, 2011 2:37 PM
    • Marked as answer by rafpv Thursday, April 28, 2011 3:00 PM
    Wednesday, April 27, 2011 6:41 PM