André Alves de Lima

Talking about Software Development and more…

Dica rápida: Compactar mdb (Microsoft Access) programaticamente com C#

Não é segredo para ninguém que os arquivos mdb (do Microsoft Access) são facilmente corrompidos e que, uma vez que o tamanho deles cresce, ele não é automaticamente reduzido de tamanho. Se você abrir o arquivo mdb diretamente no Microsoft Access, é possível compactá-lo e repará-lo utilizando a opção “Compact and Repair Database“. Mas, como podemos fazer isso programaticamente utilizando C#? É isso que veremos na dica rápida de hoje.

Uma das opções para chamarmos a funcionalidade de compactação e reparação dos arquivos mdb é utilizarmos “Office Automation“. Porém, eu não recomendo essa prática, uma vez que é necessário que o Microsoft Office esteja instalado no computador cliente para que essa metodologia funcione. Portanto, não vou mostrá-la nesse artigo.

Ao invés disso, vou mostrar como compactar mdb utilizando a JetEngine. Para isso, o primeiro passo que temos que realizar no nosso projeto é adicionar uma referência à biblioteca COM chamada “Microsoft Jet and Replication Objects“:

Feito isso, adicione o seguinte método ao seu projeto:

        public static void CompactarMdb(string caminhoMdb)
        {
            try
            {
                JRO.JetEngine jetEngine = (JRO.JetEngine)Activator.CreateInstance(Type.GetTypeFromProgID("JRO.JetEngine"));
                var arquivoTemporario = System.IO.Path.GetTempFileName();
                arquivoTemporario = System.IO.Path.ChangeExtension(arquivoTemporario, "mdb");
                string templateConnectionString = "Data Source={0};Provider=Microsoft.Jet.OLEDB.4.0;";
                string connectionStringFonte = string.Format(templateConnectionString, caminhoMdb);
                string connectionStringTemp = string.Format(templateConnectionString, arquivoTemporario);

                jetEngine.CompactDatabase(connectionStringFonte, connectionStringTemp);
                System.IO.File.Copy(arquivoTemporario, caminhoMdb, true);
                System.IO.File.Delete(arquivoTemporario);
            }
            catch { }
        }

Note que o método para compactar o mdb é muito simples. Primeiramente criamos uma instância de JetEngine. Depois criamos um arquivo temporário com extensão mdb (o mdb compactado e reparado será armazenado nesse caminho). Então chamamos o método “CompactDatabase” passando a string de conexão apontando para o mdb original e a string de conexão apontando para o arquivo temporário. Finalmente, substituímos o arquivo original pelo arquivo temporário (que nesse ponto já deverá ser o mdb compactado e reparado).

A utilização desse método é muito fácil. Basta chamá-lo passando o caminho para o arquivo mdb:

CompactarMdb("C:\\Diretorio\\NomeDoMdb.mdb");

Viu como é simples compactar e reparar um mdb programaticamente utilizando C#? Espero que ajude outras pessoas que precisem resolver esse mesmo problema no futuro.

Até a próxima!

André Lima

12 thoughts on “Dica rápida: Compactar mdb (Microsoft Access) programaticamente com C#

  • Gustavo Moreno disse:

    Show de bola.
    Uma pena que meu arquivo esta com vários gigas de tamanho, causando um certo atraso durante o runtime do C#.
    Abs

    • andrealveslima disse:

      Olá Gustavo, obrigado pelo comentário!

      Só uma dúvida: um banco do Microsoft Access com vários gigas? A chance de dar problemas é muito grande, hein.. A aplicação é acessada ao mesmo tempo por vários usuários ou somente um usuário o tempo todo? Os bancos do Access corrompem muito facilmente, principalmente quando começam a ficar muito grandes..

      Nesse caso eu recomendaria que você analisasse uma possível migração para o SQL Server Express.. Você já pensou nisso?

      Abraço!
      André Lima

  • elielson Ferreira disse:

    Ola André Lima
    teria como vc postar o fonte já pronto

  • elielson Ferreira disse:

    Muitíssimo obrigado André, sou usuário do delphi iniciando C# agora.
    no momento sei apenas abrir o Visual Studio, rsrs.

    Abraços.

    • andrealveslima disse:

      Magina Elielson! Qualquer dúvida sobre esse ou outros assuntos relacionados, é só entrar em contato novamente.. Desejo muito sucesso aí nos seus projetos!

      Abraço!
      André Lima

      • elielson Ferreira disse:

        Bom dia André, vou aproveitar suas palavras para tirar mais uma duvida,rsrs
        Usei o fonte que postou e tentei adicionar um form e um textbox, o endereço do banco seria obtido através da textbox, e um butonn daria o comando para compactar, infelizmente não consigui realizar essa proeza, adepto do Delphi, to tendo dificuldades com visual.

        Poderia me auxiliar nisso?

        Aguardo retorno.

  • Sames disse:

    Oi vou colaborar um pouco, esse código aqui deu certo comigo para accdb

    private void ribbonButton1_Click(object sender, EventArgs e)
    {
    DialogResult resultado = MessageBox.Show(“Para compactar a base de dados tenha certeza de que nenhuma usuário esteja utilizando o sistema!” + Environment.NewLine + Environment.NewLine + “Confirma a compactação da base de dados”, “Confirmação”, MessageBoxButtons.YesNo, MessageBoxIcon.Question);

    if (resultado == DialogResult.No)
    {
    return;
    }
    else
    {
    string retorno = CompactRepair();
    if (retorno != “Ok”)
    {
    MessageBox.Show(retorno, “Bloqueio”, MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    else
    {
    MessageBox.Show(“Base de Dados compactada com sucesso”, “Infomação”, MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    }

    }

    public string CompactRepair()
    {
    var dbe = new Microsoft.Office.Interop.Access.Dao.DBEngine();
    var arquivoTemporario1 = System.IO.Path.GetTempFileName();
    var arquivoTemporario2 = System.IO.Path.GetTempFileName();
    arquivoTemporario1 = Path.ChangeExtension(arquivoTemporario1, “accdb”);
    arquivoTemporario2 = Path.ChangeExtension(arquivoTemporario2, “accdb”);

    System.IO.File.Copy(Global.caminhoBD, arquivoTemporario1, true);

    try
    {
    dbe.CompactDatabase(arquivoTemporario1, arquivoTemporario2);
    System.IO.File.Copy(arquivoTemporario2, Global.caminhoBD, true);
    System.IO.File.Delete(arquivoTemporario1);
    System.IO.File.Delete(arquivoTemporario2);
    return “Ok”;
    }
    catch (Exception e)
    {
    return e.Message;
    }
    }

    • andrealveslima disse:

      Olá Sames!

      Muito obrigado por compartilhar o código aqui! Não sabia que a dll de interop do Access implementava esse esquema de compactar e restaurar com suporte a arquivos accdb também.. Valeu!

      Abraço!
      André Lima

  • Sames disse:

    Na verdade, o código que eu postei é diferente do seu, porque ele usa o dbengine do DAO. O seu usa o JRO.Eu peguei a forma como você fez e a forma que um outro cara fez, juntei as duas e saiu esse que funciona para accdb.

    Sames

    • andrealveslima disse:

      Olá Sames!

      Sim, eu vi que o seu código é diferente do meu.. Eu uso uma biblioteca e você usa outra.. Como eu disse no meu comentário anterior, eu não sabia que a dll de Interop do Access (que é a que você está utilizando: Microsoft.Office.Interop.Access.Dao.DBEngine) tinha essa funcionalidade para bancos accdb..

      Abraço!
      André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *