Access VBA: SQL delete does not work with table including a -? - vba

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.

Related

Problem importing an excel workbook into Access and adding a column; error 3127

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.

Convert string to int in VBA SQL query

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.

Index and match a field name based off another table in Access SQL code

I am using access to update some data values. I need to associate a number 1 to 50 to a numeric value associated with a trait from another table. The problem I am having is I need to index and match the two tables to match the two values then index the trait associated with the value. I can do this in Microsoft Excel with the following code...I would like to automate this process in access with a button but not sure how to index and match in Access.
=INDEX(B:B,MATCH(K:K,A:A))
In Access I've tried using an update query but index the trait value with the associated value is difficult without going into VBA code. The shd-50 and slk_50 have matching values to the Days after July 1st. I would like to update these values with the Daily HU value which are equivalent to Days after July 1st field. The GDUs_afterJuly1st are fixed values ranging from 1-50 and have a trait assigned to each number so 1=551, 2=638 ... 49 = 1440. While the tblFieldBook table I want to update the GDU_shd50 and GDU_slk50 with the 551, 638, and 1440.
So the Yellow rows mean the GDUs_afterJuly1st and the Orange rows are the tblFieldBook. I would like to update the GDU_shd50 and GDU_slk50.
I found this code was able to get the data I need. I just have some renaming that I would like to do of field names and table names. I will post this in the code when I figure that out.
Option Compare Database
Option Explicit
Private Sub Calculate_GDUs_Click()
Dim StrSql As String
Dim db As Database
Dim fld As Object
DoCmd.SetWarnings False
'run query to match and index GDUs to days after july
StrSql = "SELECT * INTO GDU_slk_50 FROM tblFieldBook LEFT JOIN GDUs_afterJuly1st ON tblFieldBook.[slk_50] = GDUs_afterJuly1st.[Days after July 1st]"
DoCmd.RunSQL (StrSql)
StrSql = "SELECT * INTO GDU_shd_50 FROM tblFieldBook LEFT JOIN GDUs_afterJuly1st ON tblFieldBook.[shd_50] = GDUs_afterJuly1st.[Days after July 1st]"
DoCmd.RunSQL (StrSql)
StrSql = "SELECT GDU_shd_50.[Daily HU], tblFieldBook.* INTO [tblFieldBookwshd50] FROM GDU_shd_50 INNER JOIN tblFieldBook ON GDU_shd_50.recID = tblFieldBook.recID"
DoCmd.RunSQL (StrSql)
StrSql = "SELECT GDU_slk_50.[Daily HU], [tblFieldBookwshd50].* INTO [tblSlkShdGDUs] FROM GDU_slk_50 INNER JOIN [tblFieldBookwshd50] ON GDU_slk_50.recID = [tblFieldBookwshd50].recID"
DoCmd.RunSQL (StrSql)
StrSql = "DELETE tblSlkShdGDUs.[GDU_slk_50_Daily HU] FROM tblSlkShdGDUs WHERE (((tblSlkShdGDUs.[GDU_slk_50_Daily HU]) Is Null))"
DoCmd.RunSQL (StrSql)
'delete tables not needed anymore
DoCmd.DeleteObject acTable, "GDU_shd_50"
DoCmd.DeleteObject acTable, "GDU_slk_50"
DoCmd.DeleteObject acTable, "tblFieldBookwshd50"
'rename columns
Set db = CurrentDb
Set fld = db.TableDefs("tblSlkShdGDUs").Fields("GDU_slk_50_Daily HU")
fld.Name = "GDU_slk50"
Set fld = db.TableDefs("tblSlkShdGDUs").Fields("tblFieldBookwshd50_Daily HU")
fld.Name = "GDU_shd50"
Set db = Nothing
Set fld = Nothing
'run export macro
xlsxExport
DoCmd.SetWarnings True
End Sub

ms access vba unique table naming method datestamp

I want to make the created table name unique, possibly by using hh:mm:ss in the table name so that if the macro is played time after time, it won't be telling me "table name already exists".
There are two parts to the query. One for creating the table, and one for refreshing access data objects so that the new table becomes visible.
Sub SelectIntoX()
Dim dbs As Database
Set dbs = CurrentDb
' Part 1 Select all records in the scheme table
' and copy them into a new table
dbs.Execute "SELECT * INTO " _
& Format(Date, "yymmdd") & "_Scheme" & " FROM dbo_scheme;"
'Part 2 refresh Access data objects to see new table appear
DBEngine(0)(0).TableDefs.Refresh
DoCmd.SelectObject acTable, Format(Date, "yymmdd") & "_Scheme", True
End Sub
The problem I have is that yymmdd is not unique and I am running it a lot each day.
I have also tried this hhmmss, but it only adds on zeroes.
This should be a good alternative:
Format(Now(), "yyyymmddhhmmss")

ms access query with loop to create multiple tables

I have one table in oracle database - which will have two columns (project name, view name). In that table when you filter project name, we will get all view names related to that project, based on those view names again we need to write query like select * from projectname$viewaname; to fetch that view related data.
Doing this manually is taking long time for each project. So my idea is to create MS ACCESS database to create tables for selected project and export them as excel files to C:\temp folder.
I need your help to create multiple tables in one go (using query/passthrough query or any other option) in MS Access fetching data from oracle database.
For that I have created MS access file, created one linked table (in which i have project and view names).
After that I have created one form, using project field as combo box from linked table and updated settings like, this form should be opened at start-up.
When I open access file, automatically this form is opening and asking me to enter oracle database user id and password - after entering credentials, combo box is updating and I can select my project in that list.
After that, I have created one query using main table and applied filter condition based on the selection in the form. Now I got results like project and view name for the end user selected project.
I need your help like,
now we have data in table like below.
Project | Viewname
A | A1
A | A2
A | A3
A | A4
A | A5
SQL query to see individual view data is :
select * from projectname$view_name;
ex: select * from A$A1;
project name, view name and no of rows(views), columns in views are dynamic - will change based on project.
I need your help to create multiple tables(one per one view) dynamically - Please suggest me the best option.
Regards,
Murali
Consider iteratively looping through the project/view name query in a recordset and creating the pass-through query that then exports to an Excel spreadsheet.
Public Sub ImportOracleProjectViews()
Dim db As Database, rst As Recordset, qdef As QueryDef
Dim constr As String, strSQL As String, mkTBL As String
Set db = CurrentDb
' ENTER QUERY HOLDING PROJECT AND VIEW NAMES '
Set rst = db.OpenRecordset("QUERYNAME")
' DELETE TEMP QUERYDEF IF EXISTS '
For Each qdef In db.QueryDefs
If qdef.Name = "temp" Then
db.QueryDefs.Delete ("temp")
End If
Next qdef
If rst.RecordCount = 0 Then Exit Sub
rst.MoveLast: rst.MoveFirst
' LOOP THROUGH EACH RECORD OF RECORDSET '
Do While Not rst.EOF
' SQL STATEMENTS '
strSQL = "SELECT * FROM " & rst!projectname & "$" & rst!viewname
' ORACLE CONNECTION STRING '
constr = "ODBC;Driver={Microsoft ODBC for Oracle};Server=myServerAddress;" _
& "Uid=myUsername;Pwd=myPassword;"
' PASS THRU QUERY '
Set qdef = db.CreateQueryDef("temp")
qdef.Connect = constr
qdef.SQL = strSQL
qdef.Close
' EXPORT TO MS EXCEL SPREADSHEET '
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, temp, _
"C:\Path\To\Output\Folder\" & rst!projectname & "_" & rst!viewname & ".xlsx", _
True
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set qdef = Nothing
Set db = Nothing
MsgBox "Successfully imported views to local tables and " _
& "Excel spreadsheets!", vbInformation
End Sub
Resources
Open Recordset VBA
Method
Oracle Connections
Strings
Creating Pass-Through Query in VBA Code
You have asked multiple questions, so the answer is structured correspondingly:
In order to create MS Access Table using VBA refer to the following sample code snippet:
Public Sub CreateTableVBA()
Dim SQL As String
SQL = "CREATE TABLE ThisTable " & "(FirstName CHAR, LastName CHAR);"
DoCmd.RunSQL SQL
End Sub
In order to create multiple Tables you should have an array of Table names and corresponding array of SQL statements, like the one shown above. Then you can loop through the array using VBA For-Next code block, running DoCmd.RunSQL command.
Alternatively, instead of DoCmd.RunSQL you may use Execute() function on VBA Database object, like shown below:
Sub CreateTableXSQL()
Dim dbs As Database
' include the path to MyDb.mdb on your computer.
Set dbs = OpenDatabase([Path to MyDb.mdb])
' create a table SQL with two text fields.
dbs.Execute "CREATE TABLE ThisTable " & "(FirstName CHAR, LastName CHAR);"
dbs.Close
End Sub
Hope this may help.