I would like to import a dbf table (FoxPro) into a temporary MS Access table and copy 2 coloumns into a final one before deleting the temp one.
My code looks like this
'read all data into temp table
DoCmd.TransferDatabase acImport, "ODBC Database", DSNCONNECTIONSTRING, acTable, "BEL_PLZ", "Belegungsplaetze_Temp", False
'update table
With CurrentDb
.Execute "INSERT INTO Belegungsplaetze (Belegungsplatznr,Bezeichnung) " & _
"SELECT NR,BEZ FROM Belegungsplaetze_Temp t " & _
"WHERE NOT EXISTS(SELECT 1 FROM Belegungsplaetze s " & _
"WHERE t.NR = s.Belegungsplatznr) "
.Execute "UPDATE Belegungsplaetze SET Belegungsplatznr = Trim([Belegungsplatznr]);"
End With
The problem I'm facing is that the field "NR" from "Belegungsplaetze_Temp" is a string and I would like to have it as an integer in my final table (final table has 2 coloumns Belegungsplatznr = Int and Bezeichnung = short text)
This answer's credit belongs entirely to serakfalcon, as they provide a completely valid anwser in the comments of the question.
Use the Val(NR) function to convert Text values into numbers. Microsoft documentation. And some Type Conversion Functions.
Related
I have an application where I want to import data from a tab/worksheet in an Excel file to a table in MSAccess where the table has the same name as the Excel tab.
This works fine for all tables but one and the only difference I can find is that this table has an hyphen '-' in the middle of its name. The error I get is "Syntax error in the FROM instruction" = the row with DoCmd.RunSQL...
If I rename the table to something without the hyphen it starts working for that table as well.
See code below;
myTab is the name of the Excel worksheet and the MSAccess table.
' check that the table exists
validTable = False
Set rs = DBEngine(0).Databases(0).OpenRecordset(myTableList, dbOpenTable)
rs.MoveFirst
For i = 0 To rs.RecordCount - 1
If rs(0) = myTab Then validTable = True
rs.MoveNext
Next i
' delete old content, import new data
If validTable Then
DoCmd.SetWarnings False
DoCmd.RunSQL ("DELETE * FROM " & myTab & ";")
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, myTab, inputFile, True, myTab
Else
How can I solve this? I guess that it is related to how i use strings
This is just a small part in a bigger application so I cannot just change name of the MSAccess table
//
Re-name of the table
Delimit the table name as below:
"DELETE * FROM [" & myTab & "];"
Delimiting the table name will work even for table names that do not contain the hyphen character.
I am creating a form in an Access database that allows a user to import an Excel workbook into the database, then inserts a column with that day's date as a way to log when the record was imported, with the idea that I can later compare this to a master database and update accordingly.
My code is below:
Private Sub btnImport_Click()
'create a new file system object that will check for conditions and import the file as a new table if a valid name is chosen
Dim FSO As New FileSystemObject
Dim strSQL As String
'Dim curDatabase As Object
Dim tableTest As Object
Dim fieldNew As Object
Dim todayDate As Date
Dim tempTable As String
tempTable = "TempTable" & CStr(Date)
'MsgBox TempTable
'If no file name in box
If Nz(Me.txtFileName, "") = "" Then
MsgBox "Please choose a file."
Exit Sub
End If
'If a file name is in box and the file can be located
If FSO.FileExists(Me.txtFileName) Then
fileImport.ImportExcel Me.txtFileName, tempTable
'once it imports the table, it then adds today's date (the upload date)
todayDate = Date
strSQL = "INSERT INTO tempTable (Upload_Date) Values (#" & Date & "#);"
DoCmd.RunSQL strSQL
'DoCmd.RunSQL ("DROP Table TempTable")
Else
'Error message if file can't be found
MsgBox "File not found."
End If
End Sub
Unfortunately, right now I am getting two problems.
The first is
run-time error 3127: The INSERT INTO statement contains an unknown
field name.
I thought I wanted to insert a new field, so I'm a little perplexed by this error.
I'm also getting another error; the compiler doesn't seem to like when I use tempTable for the table name. I'm trying to use a reference to the table name, rather than the actual name of the table itself, because this will end up being a daily upload, so the name of the table that is having this column inserted into it will change every day.
I appreciate any guidance that you can give; I'm fairly new to VBA.
UPDATE: I ended up solving this issue by A. using an UPDATE statement and using CurrentDb.Execute to add the date. I found that this worked for me:
strSQL = "ALTER TABLE TempTable ADD COLUMN Upload_Date DATE;"
strSQL2 = "UPDATE TempTable SET Upload_Date = '" & Date & "'"
DoCmd.RunSQL strSQL
CurrentDb.Execute strSQL2
INSERT INTO doesn't add columns, it just adds rows (with data in existing columns). Look into ALTER TABLE ( https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/alter-table-statement-microsoft-access-sql )
I'm not sure if it's related, but the table name you use in strSQL is "tempTable", yet the table name you pass to fileImport.ImportExcel is "TempTable" (i.e. the capitalization of the first letter is inconsistent).
If the variable "tempTable" is meant to hold the name of the table (so it can be used for different table names) then it should be outside of the SQL strings:
strSQL= "ALTER TABLE " & tempTable " & " ADD COLUMN Upload_Date DATE;"
strSQL2 = "UPDATE " & tempTable & " SET Upload_Date = '" & Date & "';"
Otherwise you are amending and updating a table called "TempTable" rather than inserting the calculated table name from the variable into the SQL string.
Also note that there should be a semi-colon at the end of strSQL2 as well.
I have 2 tables, one of them as been imported from an Excel file and therefore i created the 2nd one in order to gather some info from the imported and generate in the end a new Excel Sheet to be imported in another place.
My question here is:
I have table a with ID's, names, account status, etc.
The second table has the ID's imported from table a, and now i want to generate a commentary (a value with the concatenation from the several columns in table a) like this:
DATE: 20/12/2017 | FirstName LastName | ID: 123456
For this i prepared by table b with the ID's already and my code in MS ACCESS VBA at the moment is:
CurrentDb.Execute "UPDATE a " _
& " SET a.Commentary = 'Date: ' + CONVERT(nvarchar,GETDATE(),103) + ' | FirstName LastName | ID: ' + b.ID " _
& " FROM tableA a " _
& " INNER JOIN tableB b " _
& " ON a.IdNum = b.ID"
I don't know why this gives me the error of:
Run-time error '3075': Syntax error (missing operator) in query
expression
....(the above code)
Tried to modify the code to more VBA language, more MS-Access language but with no luck.
Thank you,
Diogo
Your syntax looks like T-SQL, if you're going to use CurrentDb.Execute, you need to use Jet/ACE SQL. That means: specifying ALL tables directly after UPDATE, no CONVERT, no GETDATE(), and & as the preferred concatenation operator.
CurrentDb.Execute "UPDATE tableA a INNER JOIN tableB b ON a.IdNum = b.ID" _
& " SET a.Commentary = 'Date: ' & Date() & ' | FirstName LastName | ID: ' & b.ID "
Note that I assume you're using linked tables, since I don't see a schema specified anywhere.
No. You will need a connection string and a saved or created pass-through query that uses this connection.
Then set the SQL property of this query to your SQL string and execute the query.
Or - if you have the tables linked - do as Erik suggests.
You could also use an ADODB command to pass the query directly to the SQL server.
You'd want to add some error handling, but something like this will work as a starting point:
Public Sub ExecuteStatementOnSqlServer(sql As String)
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = bf_sqlServerConnection
.CommandType = adCmdText
.CommandText = sql
.Execute
End With
Set cmd = Nothing
End Sub
I know that there is a similar question already posed. Since the answers are more than 6 years old, I started a new thread.
I have a Access DB and a copy of that DB. The plan is to write data to the copy and then automatically the new data to the original. So basically both DBs are the same.
I found and answer here: How Do I Copy a table from one Access DB to another Access DB. Now I want to adapt this to my purpose but I fail.
I have attached the SQL string
strSQL = "INSERT INTO [maintblKeyFinancials].* " & _
"IN '" & destination_DB & "' " & _
"SELECT * FROM [maintblKeyFinancials] " & _
" WHERE [Company_ID] = " & identifier & _
" AND [Reference_year] = " & Chr$(34) & Year & Chr$(34) & ";"
Yes, [Reference_year] is a string. I also attached the Output
INSERT INTO [maintblKeyFinancials].* IN 'C:\destination.accdb'
SELECT * FROM [maintblKeyFinancials] IN 'C:\source.accdb'
WHERE [Company_ID] = 899 AND [Reference_year] = "2015";
When I execute the string, I get "syntax error in query. incomplete query clause". And I don't know what to correct. Hope you can help me. Thx!
INSERT INTO [maintblKeyFinancials].*
Remove the .* at the end, this gives the syntax error. It's either
INSERT INTO [maintblKeyFinancials] (column1, column2)
SELECT column1, column2 FROM ...
or if the columns are completely identical
INSERT INTO [maintblKeyFinancials]
SELECT * FROM ...
write [YourServer].[yourSchema].[YourTable]
SELECT * FROM [YourServer].[YourSchema].[maintblKeyFinancials]
i am inserting values into a table
if the record exists already replace it, and if it does not exist then add a new one.
so far i have this code:
INSERT INTO table_name
VALUES (value1, value2, value3,...) where pk="some_id";
but i need something like this
if not pk="some_id" exists then INSERT INTO table_name
VALUES (value1, value2, value3,...) where pk="some_id"; else update table_name where pk="some_id"
what would be the correct SQL syntax for this?
please note that i am using sql access and that i guess it can be a combination of vba and sql
First update rows which match between your import table and master table.
UPDATE table_name AS m
INNER JOIN tblImport AS i
ON m.pk = i.pk
SET
m.field2 = i.field2,
m.field3 = i.field3,
m.field4 = i.field4;
Then add any imported records which don't exist in the master table.
INSERT INTO table_name (
pk,
field2,
field3,
field4)
SELECT
i.pk,
i.field2,
i.field3,
i.field4
FROM
tblImport AS i
LEFT JOIN table_name AS m
ON i.pk = m.pk
WHERE
(((m.pk) Is Null));
This could be done easily with recordsets. The code would then look like that (for an ADODB recordset):
myRecordset.find ....
if myRecordset.EOF then
myRecordset.addNew
endif
....
myRecordset.fields(...) = ...
....
myRecordset.update
I have posted about my approach to this problem many, many times in many different forums, but I'll just recapitulate the basic structure of the approach I use. There is no way to do it in one step, though.
update the existing records from the external data source.
insert records that don't already exist.
This assumes a common primary key that can be used to link the existing table with the external data source.
Task #2 is pretty trivial, just an outer join for the records that don't already exist.
One can use brute force for #1, writing an UPDATE statement with a SET for each field other than the primary key, but I consider that to be messy and unnecessary. Also, since I have a lot of replicated applications, I can't do that, as it would result in false conflicts (when a field is updated to the same value as it started with).
So, for that purpose, I use DAO and write an on-the-fly SQL statement to update COLUMN-BY-COLUMN. The basic structure is something like this:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim fld As DAO.Field
Dim strField As String
Dim strSet As String
Dim strWhere As String
Dim strSQL As String
Set db = CurrentDB
Set rs = db.OpenRecordset("DestinationTable")
For Each fld in rs.Fields
strField = fld.Name
If strField <> "PKField" Then
strSet = "DestinationTable." & strField & " = ExternalTable." & strField
strWhere = "Nz(DestinationTable." & strField & ",'') = Nz(ExternalTable." & strField & ", '')"
strSQL = "UPDATE DestinationTable "
strSQL = strSQL & " SET " & strSet
strSQL = strSQL & " WHERE " & strWhere
db.Execute strSQL, dbFailOnError
Debug.Print strField & ": " & db.RecordsAffected
End If
Next fld
Now, the complicated part is handling numeric vs. date vs. string fields, so you have to have some logic to write the WHERE clauses to use proper quotes and other delimiters according to the field type. Rather than test the field type, I generally just use a CASE SELECT like this, making string fields the default:
Dim strValueIfNull As String
Select Case strField
Case "DateField1", "DateField2", "NumericField2", "NumericField2", "NumericField3"
strValueIfNull = "0"
Case Else
strValueIfNull = "''"
strWhere = "Nz(DestinationTable." & strField & ", '') = Nz(ExternalTable." & strField & ", '')"
End Select
strWhere = "Nz(DestinationTable." & strField & ", " & strValueIfNull & ") = Nz(ExternalTable." & strField & ", " & strValueIfNull & ")"
I could have the details there wrong, but you get the idea, I think.
This means you'll run only as many SQL updates as there are updatable fields, and that you'll only update records that need updating. If you're also stamping your records with a "last updated" date, you'd do that in the UPDATE SQL and you'd only want to do that on the records that really had different values.