COMO CRIO UM ARQUIVO ACCDB SEM O ACCESS INSTALADO?

PROFESSOR 15/02/2014 19:48:18
#434840
KERPLUNK

Cara, essa do Access, heim? Você está começando á ficar parecido comigo... Olha o coração...

MARSOLIM

Veja, a estação do usuário não precisa ter o MS-Access instalado, de forma alguma, mesmo que você não [Ô]incorpore[Ô] os Interop da MDAC, mas ela precisa da MDAC e dos drivers, e ainda, observe que o ADOX é um componente de 32 bits, enquanto que o driver do Access pode ser de 32 bits (ACE / Jet) ou de 64 bits (ACE).

Ao referenciar a ADO, a ADOMD ou ADOX, automaticamente a solução passa á depender abolutamente dessas bibliotecas e nem sempre será fácil instalar seu aplicativo, seja por questões de versão ou de segurança.

Se ao invés disso você apenas chamar o método CreateObject, os resultados serão os mesmos, mas sem essa [Ô]dependência[Ô] absoluta. Em outras palavras, independente de qual seja a versão instalada na estação, o CreateObject irá retornar uma instância válida, desde que, claro, alguma MDAC esteja instalada.

Novamente, atente para o detalhe: Como essas bibliotecas são de 32 bits, aconselho que seu aplicativo também dê preferência á essa plataforma.

A dica do TUNUSAT funciona, não há dúvidas, mas desde que, além da ADOX, o driver Access que foi usado no desenvolvimento também esteja registrado na estação que não possui o MS-Office. E neste caso, o ideal é que a estação receba o Access Runtime na versão de 32 bits, para facilitar a sua vida.

Para garantir que a estação onde sua aplicação sera instalada seja capaz de a executar, mesmo sem ter o Microsoft Office instalado, é preciso portanto que ela possua o MDAC e os drivers OleDb (ao menos os relacionados ao Jet Engine, ou do ACE, no caso do MS-Access), e uma das formas mais adequadas de fazer isso, é incorporar o Access Runtime ao seu pacote de instalação. E o Runtime do Access 2013, como eu já havia postado aqui no forum há algum tempo, pode ser baixado aqui, no site da Microsoft. Claro, você pode optar por outras versões, basta procurar no mesmo site.

Ainda, a minha sugestão é para adaptar um pouco a sugestão do TUNUSAT, tornando desnecessária a referência ao ADOX, permitindo indicar a pasta onde o banco de dados será criado e encerrando a conexão ao banco de dados após sua criação, coisa que ele involuntariamente acabou esquecendo, e seria algo parecido com o seguinte:


[ô]...
Public Enum dbVersion
Access4x
Access10
End Enum
[ô]...
Public Shared Function CreateDatabase(Optional folder As String = [Ô][Ô],
Optional version As dbVersion = dbVersion.Access4x) As Boolean
Dim ret As Boolean = False
Dim dbFolderName As String = [Ô][Ô]
If (String.IsNullOrEmpty(folder) = False) Then
dbFolderName = folder
Else
dbFolderName = System.AppDomain.CurrentDomain.BaseDirectory
End If
If dbFolderName.EndsWith([Ô]\[Ô]) = False Then dbFolderName &= [Ô]\[Ô]
Try
If My.Computer.FileSystem.DirectoryExists(dbFolderName) = False Then
My.Computer.FileSystem.CreateDirectory(dbFolderName)
End If
If My.Computer.FileSystem.DirectoryExists(dbFolderName) = True Then
Dim dbFileName As String = [Ô]MeuRepositório[Ô]
Dim dbPass As String = [Ô]123456[Ô]
Dim dbProviderName As String = [Ô]Microsoft.ACE.OLEDB.12.0[Ô]
Dim dbFileExtension As String = [Ô]accdb[Ô]
If version = dbVersion.Access4x Then
dbProviderName = [Ô]Microsoft.Jet.OleDB.4.0[Ô]
dbFileExtension = [Ô]mdb[Ô]
End If
Dim dataSource As String = String.Format([Ô]{1}{2}.{3}[Ô],
dbFolderName,
dbFileName,
dbFileExtension)
Dim nBanco As Object = Nothing
Dim cs As String = String.Format([Ô]Provider={0};[Ô] & _
[Ô]Data Source={1};[Ô] & _
[Ô]Jet OLEDB:Database Password={2};[Ô] & _
[Ô]User ID=Admin;[Ô], _
dbProviderName, dataSource, dbPass)
Try
nBanco = CreateObject([Ô]ADOX.Catalog[Ô])
If (nBanco IsNot Nothing) Then
Try
nBanco.Create(cs)
ret = True
Catch ex As Exception
[ô]MinhaRotinaDeTratamentoDeErros(ex) ou MessageBox.Show(ex.Message)
Finally
Try
nBanco.ActiveConnection.close()
Catch ex As Exception
[ô]MinhaRotinaDeTratamentoDeErros(ex) ou MessageBox.Show(ex.Message)
End Try
End Try
nBanco = Nothing
Else
[ô]MinhaRotinaDeTratamentoDeErros(ex) ou MessageBox.Show(ex.Message)
End If
Catch ex As Exception
[ô]MinhaRotinaDeTratamentoDeErros(ex) ou MessageBox.Show(ex.Message)
End Try
End If
Catch ex As Exception
[ô]MinhaRotinaDeTratamentoDeErros(ex) ou MessageBox.Show(ex.Message)
End Try
Return ret
End Function
[ô]...


Observe que para o Jet Engine a extensão do arquivo não significa absolutamente nada. Você pode criar arquivos do Jet com a extensão [Ô]mdb[Ô] ou [Ô]accdb[Ô], e ambos irão [Ô]abrir[Ô] no Office, mas ainda assim, a versão será até a 4.x, nunca a 12.0, se não alterar o provider da conexão.

E se você está usando o MS-Access justamente para poder criar e usar o banco de dados por meio da sua própria aplicação, sem precisar se conectar á um servidor, pense bem se o SQL Server CE não é uma alternativa melhor, além de ser gratuita, ter versões x86 e x64, não precisar de servidor e vir com capacidade de até 4 Gbytes por base de dados. Só para comparar, adaptando a rotina acima para fazer exatamente a mesma coisa, mas usando o SQL Server CE, ela ficaria assim:


Public Shared Function CreateDatabase(Optional folder As String = [Ô][Ô]) As Boolean
Dim ret As Boolean = False
Dim dbFolderName As String = [Ô][Ô]
If (String.IsNullOrEmpty(folder) = False) Then
dbFolderName = folder
Else
dbFolderName = System.AppDomain.CurrentDomain.BaseDirectory
End If
If dbFolderName.EndsWith([Ô]\[Ô]) = False Then dbFolderName &= [Ô]\[Ô]
Try
If My.Computer.FileSystem.DirectoryExists(dbFolderName) = False Then
My.Computer.FileSystem.CreateDirectory(dbFolderName)
End If
If My.Computer.FileSystem.DirectoryExists(dbFolderName) = True Then
Dim dataSource As String = String.Format([Ô]{1}{2}.{3}[Ô],
dbFolderName,
[Ô]MeuRepositório[Ô],
[Ô]sdf[Ô])
Dim cb As New SqlCeConnectionStringBuilder
With cb
.DataSource = dataSource
.FileMode = [Ô]read write[Ô] [ô]ou exclusive ou shared read
[ô]Opcional, senha de acesso ao arquivo.
.Password = [Ô]123456[Ô]
[ô]Opcional, se manterá as credenciais em memória.
.PersistSecurityInfo = True [ô]ou false
[ô]Opcional, valor máximo (4091) equivale aos 4Gbytes.
.MaxDatabaseSize = 4091
End With
Using j As New SqlCeEngine(cb.ConnectionString)
j.CreateDatabase()
ret = True
End Using
End If
Catch ex As Exception
[ô]MinhaRotinaDeTratamentoDeErros(ex) ou MessageBox.Show(ex.Message)
End Try
Return ret
End Function


Finalmente, me desculpem todos, eu pessoalmente acho o MS-Access muito bom para muitos fins, mas mesmo sendo parte de um pacote corporativo, o MS-Access tem limitações bem claras quando se trata da combinação de acesso remoto e volume de dados. Eu mesmo lidei com MS-Access para uma grande empresa multinacional por vários anos, com um volume de dados enorme (mais de 2.5 Gbytes, ou seja, mais do que a própria Microsoft aponta como limite de capacidade) e sei bem quais são as deficiências desse mecanismo. é muito bom para o uso pessoal ou departamental, para armazenar informações locais, que sejam acessadas por no máximo 50 estações de trabalho e mesmo assim, com os devidos cuidados de manutenção. Serve bem para armazenar e servir dados de pequeno volume para aplicações Web somente-consulta ou com baixo volume de acesso para operações CRUD. E tem algumas funcionalidades únicas, que outros mecanismos não são capazes de oferecer, por conta de seu [Ô]dialeto[Ô] VBA e de algumas [Ô]peculiaridades[Ô] do Jet, como a possibilidade de criar tabelas [Ô]escondidas[Ô], por exemplo.

Mas para aplicações mais robustas, utilizar o MS-Access somente faz sentido se for como um repositório temporário de dados, mono-estação, aquele arquivo em que você [Ô]despeja[Ô] as informações antes de avaliar, processar e mandar para a base de dados de verdade, e depois apaga. Ou ainda, para [Ô]carregar[Ô] os dados desde o servidor de verdade e ficar em [Ô]stand by[Ô] para servir de referência no caso de pêrda de conexão. Outros usos do MS-Access em aplicações robustas, acho pura pêrda de tempo.
MARSOLIM 16/02/2014 16:27:16
#434873
bem eu instalei o xp em uma máquina virtual aqui e fiz uns testes na seguinte sequência

* instalei o net fremework 3.5 e copiei o exe para a pasta e ele rodou tranquilo
* tentei criar o accdb e deu erro claro
* copiei a dll do adox e rodei e deu erro de novo claro
* instalei o AccessDatabaseEngine e aí tudo funcionou certinho

depois de executar os passos acima o aplicativo rodou e criou o accdb sem problemas com a senha e tudo. sei que criou accdb e não mdb porque quando foi criado foi aberto o arquivo laccdb e não ldb.

só para informar é preciso importar os objetos abaixo
Imports System.Data
Imports System.Data.OleDb
professor agradeço pela atenção. ainda não tentei a sua dica mas só para eu entender o que vai fazer não precisar instalar e nem referenciar quase nada usando dessa forma? pergunto porque vi que está usando o adox tambem. se ele está usado não deve ser referenciado e a dll copiada para a pasta do aplicativo?
______________________________________________________
EDIÇÃO DO POST:

bem já agora consegui alterar como dica do professor de forma que não precisa referenciar a dll e nem levar ela para o pc aonde o programa vai ser usado e tambem não precisando dos Imports. como a ideia é que o accdb seja criado sempre na mesma pasta do aplicativo ficou bem resumido assim

        Dim nBanco As Object = CreateObject([Ô]ADOX.Catalog[Ô])
nBanco.Create([Ô]Provider=Microsoft.ACE.OLEDB.12.0;Data Source=[Ô] & System.AppDomain.CurrentDomain.BaseDirectory() & [Ô]\DataBase.accdb;JET OLEDB:Database Password=123456[Ô])
nBanco = Nothing
claro que dentro de uma condição que vai checar se o accdb existe ou não para só criar no caso de não existir.
PROFESSOR 16/02/2014 21:51:38
#434880
Estive com o fornecimento de luz intermitente o dia inteiro. Agora parece que estabilizou.

Ok, bom, eu ia dar sequência no caso da mensagem de erro que você postou, mas parece que você já está chegando lá.

Um detalhe, é que, sendo Access, não faz diferença para alguma para a aplicação se o formato é o do ACE ou o do Jet, dá na mesma. Ainda aconselho o SQL Server CE, mas ele é para .Net.

Eu até tenho um produto meu que permite usar SQL Server CE 4.0 com o VB6, criando, compactando, com criptografia etc, mas é comercial (ou seja, não vou abrir o fonte) e o objetivo aqui não é fazer comércio, é trocar informações.

Assim, estou só aproveitando para postar um exemplo pequeno.
As funcionalidades são: Criar o banco, compactar o banco e efetuar operações CRUD por meio de uma classe que não mantém a conexão [Ô]eterna[Ô]. é algo como uma Data Access Layer para o MsAccess.

São dois [Ô]zip[Ô] dentro do arquivo [Ô]Exemplo.zip[Ô]: Um é o exemplo em VB6 e o outro, em VB.Net (2010).

Veja, quando for migrar, espero que o faça, é claro que há quem seja contrário á essa minha opinião, mas evite o Visual Studio do 2005 ao 2008, pelo menos. Use algo á partir do 2010. Há várias alterações e novidades para que você comece com a Framework 2.0 e depois tenha de [Ô]reaprender[Ô].

Agora vou andando. Até a próxima semana, se der tempo.
MARSOLIM 17/02/2014 16:47:59
#434920
professor muito agradeço pelas dicas e exemplos. no momento estou a usar o Visual Basic Express 2008. vou dar uma estudada no seu exemplo com certeza.

já agora meu projeto está a funcionar da forma seguinte: ao abrir o aplicativo verifica se tem o accdb na pasta. se não tiver será feita uma busca automática em todo o computador. encontrando o banco verifica se tem uma certa tabela com um certo campo que contem uma certa chave de validação para ver se é o banco correto. sendo o banco correto faz a conexão. se não encontrar o banco tentará criar ele na pasta do aplicativo. se der o erro 429 que acusa a falta dos componentes do access será feita uma busca no computador para tentar encontrar o instalador do AccessDatabaseEngine. se encontrar executa e se não encontrar fornece a opção de baixar ele da Internet e instalar em seguida e depois criar o banco com as tabelas. para o momento está completo como eu pretendia. agradeço as dicas de todos e deixo o tópico ainda em aberto para quem quiser comentar algo mais.

quanto a opção pelo accdb e não o mdb é porque é muito fácil descobrir a senha de um mdb. já a do accdb por enquanto está bem mais difícil de descobrir. claro que nada é 100% seguro mas não custa dificultar um pouco.
Página 2 de 2 [14 registro(s)]
Tópico encerrado , respostas não são mais permitidas