In this article I report some parts of the code I used to create an application that converts MDB (Microsoft Access 2000) files into SQLite databases. I don’t think it’s a common problem, but it’s convenient for the future me to have notes.
I omit the part related to the creation of the interface, I think it is quite simple to reproduce even without a guide.
Initialize the menu
When opening the main form, I initialize some components:
I clean the list of tables to export by setting the RowSource field to empty.
Forms!Menu!tableList.RowSource = ""
I also clean the log of export operations by setting the logExport field to empty.
Forms!Menu!logExport = ""
I simplify by always using the same source database. I put the database in the same folder as the main program. I derive the location of the application using
Choose the file to export
By clicking on Choose Database I choose the MDB file to export. After choosing the file I show the list of tables and select them all (generally I want to export a whole database). Finally I use the source database name to set the target database name:
The function to select a file seems simple enough but it is not:
The problem is that MS Access 2000 doesn’t have an easy way to select a file. To do this you need a special function
GetOpenFile(). I’m not reporting the code here, it’s about 300 lines, but on GitHub I uploaded the GetFile.bas. The code is not mine, it was created a few decades ago by Ken Getz, himself the result of code dating back to 1998.
Anyway, after figuring out how to select the database I can get the name of the target database:
I extract the last part of the address with
Right(strFullPath, Len(strFullPath) - InStrRev(strFullPath, "\")) and then replace the extension
db using a code similar to this
Left(nameWithExtension, Len(nameWithExtension) - 3) & "db".
To show the list of tables in the source database I have to break down the problem into two parts. The first is to understand how to read the name of the tables, the second how to show the names on the screen.
To understand how to fill a listbox, the post Listbox Add/Remove Item AC2000 is useful. In summary, just pass the list of names, separated by
; to the control through the property
MyList.RowSource = "Table1;Table2;Table3".
Instead to read the names of the tables I have to establish a connection to the database:
Dim db As DAO.database Dim tdf As DAO.TableDef Set db = OpenDatabase(pathDatabase, False)
Then I can use the TableDefs collection (DAO) to extract the table names:
For Each tdf In db.TableDefs Debug.Print tdf.name Next
But I don’t care about the names of the system tables or the temporary ones. To avoid adding to the list I can simply filter them:
For Each tdf In db.TableDefs If Not (tdf.name Like "MSys*" Or tdf.name Like "~*") Then Debug.Print tdf.name End If Next
By combining everything I get the function
To select all the tables in the list box I use a function written by Allen Browne
Choose the destination folder
Even choosing the destination folder seems a simple thing, but it is not. Or at least it wasn’t in the late 1990s.
BrowseFolder is a function that takes care of opening a dialog box to select a folder. The original codex is by Terry Kreft. On GitHub I uploaded the GetFolderName.bas file with a copy of the code.
Create the SQLite database
The export involves two distinct operations:
First I create a new SQLite database, and then I fill it with Microsoft Access tables.
The simplest way to create a new SQLite database is to start from an existing empty one, copy it to the destination folder and rename it.
To copy a file, I must first verify that it exists. To do this I use a simple function:
The same thing for folders; I have to make sure that a destination folder exists. The function
CreateFolder takes care of this:
To copy a file I can use
FileCopy filePath, destinationFile. To delete any previous file with the same name I can instead use
Kill destinationFile. By merging these snippets I can create the function
Export the tables
The function that deals with exporting the tables is this:
updateMessage is a function that updates the log message and does not contribute to the export:
The important part is
ExportFromOtherDatabaseToSQLite dbAccess, nameTable, destinationFile. This function accepts as input the location of the source database, the name of the table to be exported and the location of the target database.
To make things easier I import the tables which I then have to export using:
DoCmd.TransferDatabase acImport, "Microsoft Access", dbAccess, acTable, table, table, False
Then, after finishing the export, I delete the table with
DoCmd.DeleteObject acTable, table
ExportToSQLite table, dbSQLite looks for the table
table and exports it to
Well, that’s it with that. This project was very interesting because it required me to do research on some issues of a few decades ago. I found it very instructive to confront some limitations of MS Access. And, to be honest, it’s also very frustrating to look for workarounds to solve things that I take for granted today.