At a loss, I have an import module used to help my less technically proficient coworkers to import data to an access database for processing. I use the following code for 8 difference text imports, they all work except for one. I can manually import using the import specification so that is not the issue, I have triple checked the table and import spec name, also not the issue, can anyone tell me why access is throwing the error?
Function import_Headcount()
Set fd = Application.FileDialog(msoFileDialogFilePicker)
Set db = CurrentDb
Dim path As Variant
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM [tbl_Headcount]"
With fd
.AllowMultiSelect = False
If .Show = -1 Then
For Each path In .SelectedItems
DoCmd.TransferText acImportDelim, "National Headcount", "tbl_Headcount", path, False
Next path
Else
MsgBox ("Import for Headcount cancelled")
Exit Function
End If
End With
Set fd = Nothing
db.Execute "qry_Update_Headcount_Fields"
DoCmd.SetWarnings True
MsgBox ("Import of Headcount complete")
End Function
It is throwing a "3001" error on the DoCmd.TransferText line, as I have said I have copy and pasted this small function 8 times with different tables and import specs and cannot see why this one is not working. Thanks for the help!
Have you tried to use square brackets in specification name?
DoCmd.TransferText acImportDelim, "[National Headcount]", "tbl_Headcount", path, False
Sounds like you are on the right track on the troubleshooting side... Keep ruling out the variables until you can pinpoint the issue.
I would suggest installing V-Tools, a freeware Access add-in. This has a utility for managing/editing import specs. This would be the first tool I would reach for in debugging the import issue. It includes a number of other helpful tools, but for the project at hand, I think you will find the Import/Export Specifications form very helpful.
Here is a screen shot of an import spec we use on a daily basis:
As you can see, this utility exposes far more options than the built-in wizards when it comes to importing and exporting data.
Hope that helps!
Related
I have a table called "Tk20F7_agg" that I am trying to export as a .txt file with custom specifications. The code is below but when I run it, I get this error:
"The Microsoft Access database engine could not find the object 'Tk2020181903#txt.'"
TempName01 = "Tk20" & Format(Date, "yyyyddmm")
ExportPath = DLookup("Export_Path", "OmniDB_system01")
Application.FileDialog(msoFileDialogSaveAs).Title = "Export Tk20 File7 (Testing)"
Application.FileDialog(msoFileDialogSaveAs).InitialFileName = TempName01 & ".txt"
intChoice = Application.FileDialog(msoFileDialogSaveAs).Show
If intChoice <> 0 Then
strPath = Application.FileDialog(msoFileDialogSaveAs).SelectedItems(1)
End If
DoCmd.TransferText acExportDelim, "Tk20_File7_spec", "Tk20F7_Agg", TempName01 & ".txt", True
Any help on fixing this would be greatly appreciated!
In my experience, I've found that this particular (and rather misleading) error message can be produced when the structure of a query or table is modified and the associated Export Specification is not updated to reflect the changes.
To resolve the error, I would suggest exporting the target object 'manually' using the Export Text File wizard, and re-save the Export Specification.
I will also add for other readers - the key here is "with custom specifications".
Without those - - one can reconfigure a table/query and a saved export will work because it is just called by the object name.
I am using the VBA DoCmd.TransferText command to import data from a CSV text file into a new table in my Access database. I have run into an issue where the text data in the first three columns in some of the files is imported as currency. I cannot figure out what is happening.
Here is a test database along with one CSV that imports correctly (VollintineLines.csv) ...
PipeID,UpstreamMH,DownstreamMH,Diameter,GISLength,Status
WS010353S,WS010353,WS010163,36,227.1984614,Fully Surveyed as Phase Work
WS011155S,WS011155,WS011154,8,418.5435318,Not Surveyed
WS011154S,WS011154,WS011153,8,303.9618911,Fully Surveyed as Phase Work
... and one that doesn't (CourtLines.csv).
PipeID,UpstreamMH,DownstreamMH,Diameter,GISLength,Status
FS020628S,FS020628,FS020462,10,278.72,Not Surveyed
FS020463S-1,FS020463,FS020462,12,248.39,Not Surveyed
FS020216S,FS020216,FS020215,12,227.53,Fully Surveyed as Phase Work
(Please ignore the unnamed objects in the database, it was just to figure out what is going on here and I didn't bother naming things.)
Here is the import code, you have to enable the Microsoft Office 16.0 Object Library Reference.
Private Sub Command0_Click()
Dim Path As FileDialog
Dim FileName As Variant
DoCmd.SetWarnings False
DoCmd.Hourglass True
Set Path = Application.FileDialog(msoFileDialogFilePicker)
With Path
.AllowMultiSelect = False
.Title = "Select your File"
.Filters.Add "All Files", "*.*"
If .Show = -1 Then
For Each FileName In .SelectedItems
DoCmd.TransferText acImportDelim, , "TempPipeData", FileName, True
Next FileName
Else
MsgBox "No File Selected to Import."
End If
End With
DoCmd.SetWarnings True
DoCmd.Hourglass False
End Sub
You have apparently encountered a rather obscure bug affecting TransferText calls that do not use an Import Specification. (It is also discussed on another site here.)
Workarounds include:
Use an Import Specification as described in this answer.
Create the table first, specifying the desired column types (Text in this case), and then import from the CSV file into the existing (empty) table.
If neither of the above options is desirable, then you could use COM Automation to
launch an instance of Excel,
have Excel open the CSV file,
save it to XLS or XLSX,
use TransferSpreadsheet in Access VBA to import the Excel data, then
delete the temporary XLS[X] file.
I'm trying to run a simple access program that exports data from a select query. However I keep getting the error:
Run-time error '3625'
The text file specification 'Deposits Link Specification' does not exist. You cannot import, export, or link using the specification.
I didn't set up a text file specification, mainly because I haven't had to do this before. How would I go about fixing this?
My simple code, is below:
'*************************************************************************
Public Function startupdate()
'*************************************************************************
DoCmd.SetWarnings False
DoCmd.TransferText acExportDelim, , "DepositsToChecklist", "X:\InHouseApps\SummerCamps\TMS\EEChecklistImport.csv", True
DoCmd.OpenQuery "qryAppendDepositsToChecklist"
DoCmd.Quit
End Function
how to create an access form which has import excel file button. and after selecting excel file it automatically creates a table in the database with collumn headers as excel first row and data as excel other rows. if you think i am not putting any effort please give me suggestion or reference and ill do it on my own.
For versions of Access since 2003, you can use the File Dialog to allow the user to browse for the file they want, prior to that, you can use API calls. If this is overkill for you, you can have the user type in the file name and path, but you will have to check that it exists using code (Dir may suit).
It would be best to use TransferSpreadsheet method of the DoCmd object (available in any version of Access from, AFAIK, 1997 onward) to import the spreadsheet. This can be run as VBA (code) or a macro.
If we assume that you are able to create a form and wire up a button you have two issues:
The file open dialog.
Triggering the import.
For 1 you should be able to use the standard Microsoft file dialogs - my VB.OLD and Access are spectacularly rusty (no access 2007) but you can reference the appropriate COM assemblies from Access after which it becomes fairly easy.
2 is a bit more interesting - I beleive you can pretty much do this by menu selection from within access in which case, at least as a first step, you should be able to automate the same steps - pretty much anything you can do from a menu you can also do by calling the relevant command from VBA. The more complex solution would be to create VBA logic to create a linked table that links to the Excel file and then do a create table query and then drop the link.
In terms of effort, the form is something one would expect you to be able to do without much help - however automating something like an import from excel is not necessarily obvious.
An example using Access 2003 would be as follows for selecting a file:
Dim fDialog As Office.FileDialog
Dim strFile As String
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.InitialFileName = "C:\temp\*.xls"
.Filters.Clear
.Filters.Add "Excel file", "*.xls"
.Filters.Add "All Files", "*.*"
If .Show = True Then
strFile = .SelectedItems(1)
End If
End With
Debug.Print strFile
Note you would need to add a Reference to the Office 12 Object Library
To Import the file you can use the TransferSpreadsheet Function of the DoCmd Object. For E.g.
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "ExcelImport", strFile, True
The Access table called ExcelImport would have to already exist in the database.
Does anyone know how to modify an existing import specification in Microsoft Access 2007 or 2010? In older versions there used to be an Advanced button presented during the import wizard that allowed you to select and edit an existing specification. I no longer see this feature but hope that it still exists and has just been moved somewhere else.
I am able to use this feature on my machine using MS Access 2007.
On the Ribbon, select External Data
Select the "Text File" option
This displays the Get External Data Wizard
Specify the location of the file you wish to import
Click OK. This displays the "Import Text Wizard"
On the bottom of this dialog screen is the Advanced button you referenced
Clicking on this button should display the Import Specification screen and allow you to select and modify an existing import spec.
For what its worth, I'm using Access 2007 SP1
I don't believe there is a direct supported way. However, if you are desparate, then under navigation options, select to show system objects. Then in your table list, system tables will appear. Two tables are of interest here: MSysIMEXspecs and MSysIMEXColumns. You'll be able edit import and export information. Good luck!
Tim Lentine's answer seems to be true even in the full release. There is just one other thing I would like to mention.
If you complete your import without going into "Advanced..." and saving the spec, but you do save the import for reuse at the end of the wizard (new feature AFAIK), you will not be able to go back and edit that spec. It is built into the "Saved Import". This may be what Knox was referring to.
You can, however, do a partial work around:
Import a new file (or the same one all over again) but,
This time choose to append, instead of making a new
Click OK.
Go into "advanced" All your column heading and data-types will be there.
Now you can make the changes you need and save the spec inside that dialog. Then cancel out of that import (that is not what you wanted anyway, right?)
You can then use that spec for any further imports. It's not a full solution, but saves some of the work.
Below are three functions you can use to alter and use the MS Access 2010 Import Specification. The third sub changes the name of an existing import specification. The second sub allows you to change any xml text in the import spec. This is useful if you need to change column names, data types, add columns, change the import file location, etc.. In essence anything you want modify for an existing spec. The first Sub is a routine that allows you to call an existing import spec, modify it for a specific file you are attempting to import, importing that file, and then deleting the modified spec, keeping the import spec "template" unaltered and intact. Enjoy.
Public Sub MyExcelTransfer(myTempTable As String, myPath As String)
On Error GoTo ERR_Handler:
Dim mySpec As ImportExportSpecification
Dim myNewSpec As ImportExportSpecification
Dim x As Integer
For x = 0 To CurrentProject.ImportExportSpecifications.Count - 1
If CurrentProject.ImportExportSpecifications.Item(x).Name = "TemporaryImport" Then
CurrentProject.ImportExportSpecifications.Item("TemporaryImport").Delete
x = CurrentProject.ImportExportSpecifications.Count
End If
Next x
Set mySpec = CurrentProject.ImportExportSpecifications.Item(myTempTable)
CurrentProject.ImportExportSpecifications.Add "TemporaryImport", mySpec.XML
Set myNewSpec = CurrentProject.ImportExportSpecifications.Item("TemporaryImport")
myNewSpec.XML = Replace(myNewSpec.XML, "\\MyComputer\ChangeThis", myPath)
myNewSpec.Execute
myNewSpec.Delete
Set mySpec = Nothing
Set myNewSpec = Nothing
exit_ErrHandler:
For x = 0 To CurrentProject.ImportExportSpecifications.Count - 1
If CurrentProject.ImportExportSpecifications.Item(x).Name = "TemporaryImport" Then
CurrentProject.ImportExportSpecifications.Item("TemporaryImport").Delete
x = CurrentProject.ImportExportSpecifications.Count
End If
Next x
Exit Sub
ERR_Handler:
MsgBox Err.Description
Resume exit_ErrHandler
End Sub
Public Sub fixImportSpecs(myTable As String, strFind As String, strRepl As String)
Dim mySpec As ImportExportSpecification
Set mySpec = CurrentProject.ImportExportSpecifications.Item(myTable)
mySpec.XML = Replace(mySpec.XML, strFind, strRepl)
Set mySpec = Nothing
End Sub
Public Sub MyExcelChangeName(OldName As String, NewName As String)
Dim mySpec As ImportExportSpecification
Dim myNewSpec As ImportExportSpecification
Set mySpec = CurrentProject.ImportExportSpecifications.Item(OldName)
CurrentProject.ImportExportSpecifications.Add NewName, mySpec.XML
mySpec.Delete
Set mySpec = Nothing
Set myNewSpec = Nothing
End Sub
When I want to examine or change an import / export specification I query the tables in MS Access where the specification is defined.
SELECT
MSysIMEXSpecs.SpecName,
MSysIMexColumns.*
FROM
MSysIMEXSpecs
LEFT JOIN MSysIMEXColumns
ON MSysIMEXSpecs.SpecID = MSysIMEXColumns.SpecID
WHERE
SpecName = 'MySpecName'
ORDER BY
MSysIMEXSpecs.SpecID, MSysIMEXColumns.Start;
You can also use an UPDATE or INSERT statement to alter existing columns or insert and append new columns to an existing specification. You can create entirely new specifications using this methodology.
Another great option is the free V-Tools addin for Microsoft Access. Among other helpful tools it has a form to edit and save the Import/Export specifications.
Note: As of version 1.83, there is a bug in enumerating the code pages on Windows 10. (Apparently due to a missing/changed API function in Windows 10) The tools still works great, you just need to comment out a few lines of code or step past it in the debug window.
This has been a real life-saver for me in editing a complex import spec for our online orders.
Why so complicated?
Just check System Objects in Access-Options/Current Database/Navigation Options/Show System Objects
Open Table "MSysIMEXSpecs" and change according to your needs - its easy to read...
Tim Lentine's answer works IF you have yours specs saved. Your question did not specify that, it only stated you had imported the data. His method would not save your specs that way.
The way to save the spec of that current import is to re-open the import, hit "apend" and that will allow you to use your current import settings that MS Access picked up. (This is useful if your want to keep the import specs from an Excel format you worked on prior to importing into MS ACCESS.)
Once you're in the apend option, use Tim's instructions, which is using the advanced option and "Save As." From there, simply click cancel, and you can now import any other similar data to various tables, etc.
I have just discovered an apparent bug in the whole Saved Import/XML setup in Access. Also frustrated by the rigidity of the Saved Import system, I created forms and wrote code to pick apart the XML in which the Saved Import specs are stored, to the point that I could use this tool to actually create a Saved Import from scratch via coded examination of a source Excel workbook.
What I've found out is that, while Access correctly imports a worksheet per modifications of default settings by the user (for example, it likes to take any column with a header name ending with "ID" and make it an indexed field in the resulting table, but you can cancel this during the import process), and while it also correctly creates XML in accordance to the user changes, if you then drop the table and use the Saved Import to re-import the worksheet, it ignores the XML import spec and reverts back to using its own invented defaults, at least in the case of the "ID" columns.
You can try this on your own: import an worksheet Excel with at least one column header name ending with "ID" ("OrderID", "User ID", or just plain "ID"). During the process, be sure to set "Indexed" to No for those columns. Execute the import and check "Save import steps" in the final dialog window. If you inspect the resulting table design, you will see there is no index on the field(s) in question. Then delete the table, find the saved import and execute it again. This time, those fields will be set as Indexed in the table design, even though the XML still says no index.
I was pulling my hair out until I discovered what was going on, comparing the XML I built from scratch with examples created through the Access tool.
I used Mike Hansen's solution, it is great. I modified his solution in one point, instead of replacing parts of the string I modified the XML-attribute. Maybe it is too much of an effort when you can modify the string but anyway, here is my solution for that.
This could easily be further modified to change the table etc. too, which is very nice imho.
What was helpful for me was a helper sub to write the XML to a file so I could check the structure and content of it:
Sub writeStringToFile(strPath As String, strText As String)
'#### writes a given string into a given filePath, overwriting a document if it already exists
Dim objStream
Set objStream = CreateObject("ADODB.Stream")
objStream.Charset = "utf-8"
objStream.Open
objStream.WriteText strText
objStream.SaveToFile strPath, 2
End Sub
The XML of an/my ImportExportSpecification for a table with 2 columns looks like this:
<?xml version="1.0"?>
<ImportExportSpecification Path="mypath\mydocument.xlsx" xmlns="urn:www.microsoft.com/office/access/imexspec">
<ImportExcel FirstRowHasNames="true" AppendToTable="myTableName" Range="myExcelWorksheetName">
<Columns PrimaryKey="{Auto}">
<Column Name="Col1" FieldName="SomeFieldName" Indexed="NO" SkipColumn="false" DataType="Double"/>
<Column Name="Col2" FieldName="SomeFieldName" Indexed="NO" SkipColumn="false" DataType="Text"/>
</Columns>
</ImportExcel>
</ImportExportSpecification>
Then I wrote a function to modify the path. I left out error-handling here:
Function modifyDataSourcePath(strNewPath As String, strXMLSpec As String) As String
'#### Changes the path-name of an import-export specification
Dim xDoc As MSXML2.DOMDocument60
Dim childNodes As IXMLDOMNodeList
Dim nodeImExSpec As MSXML2.IXMLDOMNode
Dim childNode As MSXML2.IXMLDOMNode
Dim attributesImExSpec As IXMLDOMNamedNodeMap
Dim attributeImExSpec As IXMLDOMAttribute
Set xDoc = New MSXML2.DOMDocument60
xDoc.async = False: xDoc.validateOnParse = False
xDoc.LoadXML (strXMLSpec)
Set childNodes = xDoc.childNodes
For Each childNode In childNodes
If childNode.nodeName = "ImportExportSpecification" Then
Set nodeImExSpec = childNode
Exit For
End If
Next childNode
Set attributesImExSpec = nodeImExSpec.Attributes
For Each attributeImExSpec In attributesImExSpec
If attributeImExSpec.nodeName = "Path" Then
attributeImExSpec.Value = strNewPath
Exit For
End If
Next attributeImExSpec
modifyDataSourcePath = xDoc.XML
End Function
I use this in Mike's code before the newSpec is executed and instead of the replace statement. Also I write the XML-string into an XML-file in a location relative to the database but that line is optional:
Set myNewSpec = CurrentProject.ImportExportSpecifications.item("TemporaryImport")
myNewSpec.XML = modifyDataSourcePath(myPath, myNewSpec.XML)
Call writeStringToFile(Application.CurrentProject.Path & "\impExpSpec.xml", myNewSpec.XML)
myNewSpec.Execute