How Can I Import an Excel Spreadsheet Into an Access Database?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I import an Excel spreadsheet into an Access database?

— IE

SpacerHey, Scripting Guy! AnswerScript Center

Hey, IE. Wait! Don’t tell us; let us guess. Just a moment … we’re picking up the vibrations now … the sensation is getting stronger and more distinct … OK, got it: you’d like to know how to import an Excel spreadsheet into an Access database, wouldn’t you? Are we right? That’s what we thought.

Granted, some of you don’t seem too impressed by that. “Big deal,” you say. “Anyone could ‘predict’ what question IE was going to ask; all you have to do is read the question at the start of the column.” Oh ye of little faith. Sure, it’s true that we could have simply read IE’s question ahead of time and then made a “prediction.” However, how do you explain this: in yesterday’s column we predicted that today we would cover importing an Excel spreadsheet into an Access database. It’s true; just take a look at this quote from the April 3rd column:

“Does that mean that we could use a similar script to import data? As a matter of fact it does, and in tomorrow’s column we’ll show you how to do that very thing.”

That’s OK, no need to apologize; we’re used to dealing with skeptics. And for those of you wondering how we were able to make such an uncanny prediction, well, to tell you the truth, we don’t know; it’s just a gift. But don’t worry: the Scripting Guys vow to use this gift only for good, never for evil.

Well, maybe a little evil. But not much.

Of course, throughout the ages seers and psychics have been a dime-a-dozen; does the name Nostradamus ring a bell with anyone? But there’s one thing that separates the Scripting Guys from their fellow prophets and soothsayers: as near as we can tell, Nostradamus never wrote a script that imports an Excel spreadsheet into an Access database. Score one for the Scripting Guys:

Const acImport = 0
Const acSpreadsheetTypeExcel9 = 8

Set objAccess = CreateObject(“Access.Application”)
objAccess.OpenCurrentDatabase “C:\Scripts\Test.mdb”

objAccess.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
“Employees”, “C:\Scripts\Employees.xls”, True

Guess what: we knew you were going to take one look at this and think “Wow; that’s easy.” And you’re right: it is. As you can see, we start out by defining a constant name acImport and setting the value to 0; this tells the script that we want to import data (as opposed to exporting it). We then define a second constant, this one named acSpreadsheetTypeExcel9, and set the value to 8; this tells the script that we’re planning to import an Excel 2003 worksheet. Are there other spreadsheet formats that we can import into Access? You bet there are:



























After we define our constants we then use these two lines of code to create an instance of the Access.Application object and open the database C:\Scripts\Test.mdb (something we do by calling the OpenCurrentDatabase method):

Set objAccess = CreateObject(“Access.Application”)
objAccess.OpenCurrentDatabase “C:\Scripts\Test.mdb”

At that point all we have to do is invoke the TransferSpreadsheet method and import the spreadsheet data into the database:

objAccess.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
“Employees”, “C:\Scripts\Employees.xls”, True

Ah, yes, we had a feeling you were going to ask that; here’s what the parameters passed to the TransferSpreadsheet method represent:

acImport, the constant that tells the script that we want to import data rather than export it.

acSpreadsheetTypeExcel9, the constant that specifies the file format for the imported data.

“Employees”, the name of the table in Test.mdb we want to add the spreadsheet data to. Suppose the database doesn’t contain a table named Employees; what then? Well, in that case the script will automatically create a new table (named Employees, of course) for you.

“C:\Scripts\Employees.xls”, the full path to the Excel spreadsheet we want to import.

True, the HasFieldNames parameter, which tells the script that the first row in the spreadsheet file consists of field names. As you might expect, the import is more likely to work if the field names in your database match the field names in your spreadsheet. But what if they don’t match? Well, in that case you might simply import the data to a new table. Alternatively, you can set the HasFieldNames parameter to False; when you do that the script will simply match the first column of data in the spreadsheet with the first field in the database table, then match the second column with the second field, etc. That works just fine, but you do need to make sure that the field order in the database is the same as the column order in the spreadsheet. If your database table has fields named FirstName, LastName, and Address, in that order, then your spreadsheet needs to have columns listing first names, last names, and addresses, in that same order.

We should also add that it’s important that the data types match as well. If you have a database field named EmployeeID, a field that only accepts numeric data, don’t try importing spreadsheet data that includes non-numeric data (e.g., an employee ID of 1234ABC). That’s not going to work.

Oh, and here’s another thing we should add: there’s actually an optional sixth parameter (following HasFieldNames) that enables you to limit your import to a specified range of data. For example, suppose your spreadsheet has 6 columns of data (columns A through F) and you only want to import the first 25 rows in that spreadsheet. Okey-doke. That means that the range of data to be imported runs from cells A1 through cell F25 (A1:F25 in Excel-speak). In turn, that means you can import just those 25 records by using this command:

objAccess.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
“Employees”, “C:\Scripts\Employees.xls”, True, “A1:F25”

We’ve already thought of that: suppose you would like to import the spreadsheet into a brand-new database (as opposed to importing the data into an existing database). Is that possible? Not if you’re Nostradamus. But if you’re the Scripting Guys, well, then it’s a different story:

Const acImport = 0
Const acSpreadsheetTypeExcel9 = 8

Set objAccess = CreateObject(“Access.Application”)
objAccess.NewCurrentDatabase “C:\Scripts\New.mdb”

objAccess.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
“Employees”, “C:\Scripts\Employees.xls”, True

You’re right: this does look a lot like the first script we showed you, doesn’t it? In fact, there’s only one difference: this time we don’t use the OpenCurrentDatabase method in order to open an existing database file. Instead, we use the NewCurrentDatabase method to create a brand-new database (C:\Scripts\New.mdb):

objAccess.NewCurrentDatabase “C:\Scripts\New.mdb”

At this point in time it’s hard to believe that anyone could possibly doubt the Scripting Guys and their power of clairvoyance. Just in case, however, we might note that the Scripting Guy who writes this column won the annual NCAA college basketball challenge by, among other things, correctly foreseeing a Florida victory over Ohio State. (Sorry; over the Ohio State University. Sheesh.) Furthermore, he already has a prediction for next year’s championship game: the University of Washington 78, North Carolina 65. Remember, you read it here first.

Unless it turns out that we’re wrong. In that case, you didn’t read it here at all, and we have no idea what you’re talking about.

Comments (6)

  1. Alan Bell says:

    Can this code be modified so as to select different sheets (rather than currently defaulting to the first sheet in the workbook)to be imported.

    alan Bell 28/02/2010

  2. Lauri says:

    What a great article; extremely easy to follow and very informative, but I bet you knew I was going to say that.:)

    Thanks team.

  3. SCannon says:

    I need to allow the user to select the table that they're importing the file into (a simple dropdown list takes care of that), and be able to navigate to the file that they want to import.

    How do I collect these 2 variable names, and then pass them to the script, rather than using hard-coded table/file names?

  4. Gerhard Pool says:


    I seem to be getting an error if my range is more than 65536 Rows?

    (I have MS object library 12 enabled, and the acSpreadsheetType set to 9 for Excel 2007)

    Any advice would be much appreciated!

  5. Joel says:

    Hello, I have been using this function:

    DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "Packet_temp", Fileandpath, False

    where Fileandpath is a previously defined variable for the file location.

    In my code, I am importing over 1600 excel files, and for some of these (about 100) the rows are imported out of order (ie. row 3 is listed as a recorded before row 2).

    Any idea why this could be happening?

    Thank you


Skip to main content