I am transferring from text files to access DB table using DoCmd.TransferText. Just that for each record created in my access DB table, apart from the text file lines, i would like to add one more field to each record, but for DoCmd it seems to be a constraint. Is there any way i can do that?
You can import the text file into a staging table then
run a make table query or Append Table Query into your finished table. In the query add the needed field(s) via calculation in the Query Design:
Myfield:Null or MyField:IIF(SomeOtherField="M", ...) etc. Then save the query.
In your VBA (Assuming that "StagingTable is where you import the file and
AppendStagingTableToWorkTable is your appendquery:
DoCmd.TransferText acImportFixed, "My Import Spec", "StagingTable", _
"C:\TextFile.txt", False
DoCmd.OpenQuery "AppendStagingTableToWorkTable"
Related
What I'm doing is:
I have designed a form in order to importing data to my tables from excel.
I've made a vba code on a command botton click event, which allows user to select their .xls file with filedialog method, and after clicking import, The VBA code is :
cbotablename is the table that user selects to import data into it:
i = forms![frm_import-export]![cbotablename]
Strsql = "delete " & i & " .* from" & i
Docmd.RunSQL strsql
This code works normaly
After deleting old data I wanna import the new data by this code :
Docmd.transferspreadsheet acimport, 10, i ,
selected item, true
And I get this error:
Microsoft database engine could not find the
object tblname. Make sure the object exists!!
But all tables are exitst.
I found another solution for this problem.
I've used a linked table which is being updated by an Excel file selected by users, a delete query and an append query.
So when users click on the import button, VBA code relinks the linked table to excel file and then runs delete query to remove previous data from main table and then runs the append query to import new data from linked table to main table.
As a result, I don't need those linked excel files and I'll be able to transfer database wherever i want.
Problem Background:
I have a Powershell script that I can execute from my Microsoft Access Form that scans through file folders that contain information on different facilities, and produces a CSV that looks something like:
SiteCode FacilityNumber DocumentType HyperlinkPath
DKFZ 10 DD1400 C:\FACILITIES DATABASE\path
DKFZ 10 FLRPLN C:\FACILITIES DATABASE\path
SMQL 17 P1 C:\FACILITIES DATABASE\path
SMQL 17 P2 C:\FACILITIES DATABASE\path
So that way every time new files are added to those folders, I can just run this script and produce an updated list of everything I have:
C:\...\Output\scanResults.csv
All I need now is to take that CSV file and update (or even overwrite) a Table that I have in an Access database, which has relationships to other tables and is used by various Queries and Forms in the database. The CSV columns are already named and formatted in the same way as the Access Table.
I've looked at and tried to replicate the following threads:
VBA procedure to import csv file into access
Access Data Project Importing CSV File In VBA
VBA Import CSV file
The closest answer I found is:
Sub Import()
Dim conn as new ADODB.Connection
Dim rs as new ADODB.Recordset
Dim f as ADODB.field
conn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=c:\temp;"
rs.Open "SELECT * FROM [test.txt]", conn, adOpenStatic, adLockReadOnly, adCmdText
While Not rs.EOF
For Each f In rs.Fields
Debug.Print f.name & "=" & f.Value
Next
Wend
End Sub
But this obviously won't write the data into the table, and I could not understand what the author was trying to say with respect to changing Select to Insert.
I've also found:
DoCmd.TransferText acImportDelim, "YourCustomSpecificationName", _
"tblImport", "C:\SomeFolder\DataFile.csv", False
Since both of these are from 2010, I wonder if there isn't a better way to accomplish this in Access 2013. And while I can do this all manually, I would like to incorporate it into the VBA code I use to tell Powershell to produce the CSV, that way I can make it and then upload it immediately.
Any help or suggestions are greatly appreciated. I'm still very green to Access, VBA, and SQL statements in general, so this has been very much a "learning as I go" process.
I prefer to use SQL clauses and queries to import such data. The details depend on your exact configuration, but it tends to look something like this:
SELECT *
INTO MyTable
FROM [Text;FMT=CSVDelimited;HDR=No;DATABASE=C:\...\Output].[scanResults#csv]
Or append the information to the table instead:
INSERT INTO MyTable
(SiteCode, FacilityNumber, DocumentType, HyperlinkPath)
SELECT *
FROM [Text;FMT=CSVDelimited;HDR=No;DATABASE=C:\...\Output].[scanResults#csv]
This allows you to do checks before importing (using a WHERE clause), import only specific values, and allows you to customize a lot without using external files.
DATABASE= is followed by your folder name (use {} if there are characters that need escaping in there), and then followed by your file name with . replaced with #.
You can execute it by either saving it as a query, or using it as a string in either VBA or a macro. Note that I rarely recommend macro's, but you can execute them using a scheduled task and close Access after importing.
To backup and restore a relation before and after updating, you can use the following functions:
Public Function DeleteRelationsGiveBackup(strTablename As String) As Collection
Dim ReturnCollection As Collection
Set ReturnCollection = New Collection
Dim i As Integer
Dim o As Integer
Do While i <= (CurrentDb.Relations.Count - 1)
Select Case strTablename
Case Is = CurrentDb.Relations(i).Table
ReturnCollection.Add DuplicateRelation(CurrentDb.Relations(i))
o = o + 1
CurrentDb.Relations.Delete CurrentDb.Relations(i).NAME
Case Is = CurrentDb.Relations(i).ForeignTable
ReturnCollection.Add DuplicateRelation(CurrentDb.Relations(i))
o = o + 1
CurrentDb.Relations.Delete CurrentDb.Relations(i).NAME
Case Else
i = i + 1
End Select
Loop
Set DeleteRelationsGiveBackup = ReturnCollection
End Function
Public Sub RestoreRelationBackup(collRelationBackup As Collection)
Dim relBackup As Variant
If collRelationBackup.Count = 0 Then Exit Sub
For Each relBackup In collRelationBackup
CurrentDb.Relations.Append relBackup
Next relBackup
End Sub
Public Function DuplicateRelation(SourceRelation As Relation) As Relation
Set DuplicateRelation = CurrentDb.CreateRelation(SourceRelation.NAME, SourceRelation.Table, SourceRelation.ForeignTable)
DuplicateRelation.Attributes = SourceRelation.Attributes
Dim i As Integer
Dim fldLoop As Field
Do While i < SourceRelation.Fields.Count
Set fldLoop = DuplicateRelation.CreateField(SourceRelation.Fields(i).NAME)
fldLoop.ForeignName = SourceRelation.Fields(i).ForeignName
DuplicateRelation.Fields.Append fldLoop
i = i + 1
Loop
End Function
And then, when importing:
Dim colRelBackup As Collection
Set colRelBackup = DeleteRelationsGiveBackup("MyTable")
'Delete MyTable
'Import new version
RestoreRelationBackup colRelBackup
(Note that the code is quite long, developed for a project several years ago, and not extensively tested. If a field name/type is not exactly like how it was before the import, the restore of the backup might fail and the relations will be permanently lost).
So some high level architect advice: replacing data versus replacing table
It is easier replacing data - - the new incoming data must be the exact same structure as the existing table (i.e. same field names and no new fields).
just fire a Delete Query to the existing table that clears out all records
then fire an Append Query to the linked CSV file that writes all those records into the existing table
very simple really.
You can replace the tables if you must - and you are already down this path. You can delete those table relationships entirely. That table relationship feature is useful - but not mandatory. You can create relationships at the query level as an alternative. Essentially the table relationships just auto create the query level relationships. If you delete the table relationships then one must simply create the table relationships at the query level manually - they don't automatically appear. Note however that if one is relying on cascade deletes or referential integrity, then removing table relationships will undo that - so you should check these points.
Deleting Table Relationships will not break any existing queries. Their table relationship join lines will remain intact.
In a VB6 program, with an Access 2000 database, I want to read a .CSV file, with table field names in the first record, into a new Access table.
Here is my VB6 code:
With CreateObject("Access.Application")
.OpenCurrentDatabase "C:\Database1.accdb"
.DoCmd.TransferText , , newTable, importFile, True
.Quit
End With
The DoCmd.TransferText command gives me the following error:
Error # 3107 (MSAccess: Record(s) cannot be added; no insert permission on 'Table Name'.)
Any ideas what I'm doing wrong?
Seeking clarification - are you running this with block from the database you are also opening through .OpenCurrentDatabase? If so, it is my understanding that call is for opening Access from another application (MSDN), so you may be blocking yourself from editing the records. DoCmd.TransferText by itself should suffice to import the records if this scenario's assumption is true.
For future purposes note you can insert code with greater legibility by clicking the Code Sample icon or pressing Ctrl + K when writing your submission.
I have my database split into a backend containing the data tables and a frontend containing forms, queries, reports, and modules, with the tables linked. One of the tables gets its data from an excel sheet; normally I'd use a linked table but if any queries are open then the excel sheet cannot be opened, so instead I use a saved import to pull all the data from the excel sheet into the table.
Now, I'd like to add a button to the menu on my frontend that runs DoCmd.RunSavedImportExport "savedimportnamehere" except the saved import is on the backend, so I'd have to send that command to the backend... and I'm not quite sure how to do that. If anyone could point me in the right direction I'd appreciate it.
You can run a command against an instance of MS Access, so:
Dim apAccess As New Access.Application
apAccess.OpenCurrentDatabase ("c:\docs\backend.mdb")
apAccess.DoCmd.RunSavedImportExport "savedimportnamehere"
You can also run a query against an instance of the db or a connection:
sSQL="INSERT INTO Table1 ( ADate ) " _
& "SELECT SomeDate " _
& "FROM [Excel 8.0;HDR=YES;DATABASE=Z:\Docs\Test.xls].[Sheet1$a1:a4]"
I have a 'accdb' file and it has some queries.
Now I want use the query's output to be redirected to a text file and each of the fields are delimited by tabs.
I might have to do this multiple times over the course of the month, so I would like a button and on-clicking it it takes the queries 1 by 1 and create a new file for every query. How can I do this?
BTW the 1st row would be the field names.
Here is the code, first you have to create specification like here and replace name YourName with it's name and Query1 with your query name:
DoCmd.TransferText TransferType:=acExportFixed, _
SpecificationName:="YourName", _
TableNAme:="Query1", _
FileName:="d:\test.txt", _
HasFieldNames:=-1
You can use the TransferText method to export it as type acLinkDelim. You can write this into a bit of code behind the click event of a button or put it into a public function that takes a query name and an output path and does the rest for you