Access File Dialog Import- Import multiple excel tabs/sheets - database

I have the following code that will allow me to select a specific spreadsheet and import it inside my table. The issue I have is that there are a total of 4 tabs (With all the same column headings, just different types of data).
Is it possible to have this import function, import the data in each tab (total of 4 tabs), into my table with a single import?
Module:
Function selectFile()
Dim fd As FileDialog, fileName As String
On Error GoTo ErrorHandler
Set fd = Application.FileDialog(msoFileDialogFilePicker)
fd.AllowMultiSelect = False
If fd.Show = True Then
If fd.SelectedItems(1) <> vbNullString Then
fileName = fd.SelectedItems(1)
End If
Else
'Exit code if no file is selected
End
End If
'Return Selected FileName
selectFile = fileName
Set fd = Nothing
Exit Function
ErrorHandler:
Set fd = Nothing
MsgBox "Error " & Err & ": " & Error(Err)
End Function
Form:
Private Sub cmdImport_Click()
'Unset warnings
DoCmd.SetWarnings False
'Import spreadsheet
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "Table123", selectFile, True
DoCmd.SetWarnings True
End Sub
Added the following range (4 times due to 4 tabs/worksheets):
Private Sub cmdImport_Click()
Dim selectFile() As String
'Unset warnings
DoCmd.SetWarnings False
'Import spreadsheet
DoCmd.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Producer Pro Inquiries", _
fileName:=selectFile, _
HasFieldNames:=True, _
Range:="Medicare$"
DoCmd.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Producer Pro Inquiries", _
fileName:=selectFile, _
HasFieldNames:=True, _
Range:="Centene Medicare$"
DoCmd.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Producer Pro Inquiries", _
fileName:=selectFile, _
HasFieldNames:=True, _
Range:="Medsupp$"
DoCmd.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Producer Pro Inquiries", _
fileName:=selectFile, _
HasFieldNames:=True, _
Range:="Commercial$"
DoCmd.SetWarnings True
End Sub
When trying to import, when I select the file, the File Dialog box re-opens asking me to select the file again (keeps doing it).

The TransferSpreadsheet method provides an additional field to set imported Range. You need to provide the range (sheet name) to the method.
DoCmd.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Table123", _
FileName:=selectFile, _
HasFieldNames:=True, _
Range:="Sheet1$"
Note: If the FileDialog's Show is not 0, a selection has been made - no need to check for vbNullString.
If fd.Show <> 0 Then selectFile = fd.SelectedItems(1)
Edit:
In you case it would be something like this:
Private Sub cmdImport_Click()
Dim filepath As String
filepath = selectFile()
If Len(filepath) = 0 Then Exit Sub
With DoCmd
.SetWarnings False
.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Table123", _
FileName:=filepath, _
HasFieldNames:=True, _
Range:="ZZ$"
.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Table123", _
FileName:=filepath, _
HasFieldNames:=True, _
Range:="YY$"
.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="Table123", _
FileName:=filepath, _
HasFieldNames:=True, _
Range:="XX$"
.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:="filepath", _
FileName:=selectFile, _
HasFieldNames:=True, _
Range:="WW$"
.SetWarnings True
End With
End Sub

You can import multiple excel sheets, or even multiple files, in one go, by using SQL to query the Excel sheets and a union query.
You can, of course, use dynamic SQL to modify the file location and sheet names
SELECT *
INTO MyTable
FROM (
SELECT *
FROM [Sheet1$A:C]
IN 'C:\MyFile.xlsx'[Excel 12.0 XML;HDR=Yes;]
UNION ALL
SELECT *
FROM [Sheet2$A:C]
IN 'C:\MyFile.xlsx'[Excel 12.0 XML;HDR=Yes;]
UNION ALL
SELECT *
FROM [Sheet3$A:C]
IN 'C:\MyFile.xlsx'[Excel 12.0 XML;HDR=Yes;]
) u
Or, when using dynamic SQL:
Dim fileLocation As String
fileLocation = selectFile
Dim Range1 As String
Range1 = "ZZ$"
'Other ranges here
Dim strSQL As String
strSQL = "SELECT * INTO MyTable FROM (" & _
" SELECT * FROM [" & Range1 & "] " & _
" IN '" & fileLocation & "'[Excel 12.0 XML;HDR=Yes;]" & _
" UNION ALL" & _
" SELECT * FROM [" & Range2 & "] " & _
" IN '" & fileLocation & "'[Excel 12.0 XML;HDR=Yes;]" & _
" UNION ALL" & _
" SELECT * FROM [" & Range2 & "] " & _
" IN '" & fileLocation & "'[Excel 12.0 XML;HDR=Yes;]" & _
" ) u"
CurrentDb.Execute strSQL

Related

Form Button will not run OpenRecordSet VBA

I am trying to use the following VBA code to run a select query in MS Access.
Private Sub ManuReport_Click()
Dim dbs As DAO.Database
Dim rsSQL As DAO.Recordset
Dim StrSQL As String
Set dbs = CurrentDb
strSQL = "SELECT " & _
"dbo_VENDOR1.ITEM_NO," & _
"dbo_VENDOR1.ITEM_PRICE," & _
"dbo_VENDOR2.ITEM_NO," & _
"dbo_VENDOR2.ITEM_PRICE," & _
"dbo_VENDOR1.MANUFACTURER_ITEM_NO," & _
"dbo_VENDOR1.MANUFACTURER," & _
"dbo_VENDOR1.ITEM_NAME " & _
"From dbo_VENDOR2 " & _
"INNER JOIN dbo_VENDOR1 " & _
"ON dbo_VENDOR2.MANUFACTURER_ITEM_NO = dbo_VENDOR1.MANUFACTURER_ITEM_NO " & _
"WHERE dbo_VENDOR1.MANUFACTURER IN ('MANUFACTURER CODE') " & _
"And dbo_VENDOR1.ITEM_PRICE > dbo_VENDOR2.ITEM_PRICE "
Set rsSQL = dbs.OpenRecordset(strSQL, dbOpenDynaset)
End Sub
I have added this to a button in MSACCES to pull this information from a linked SQL database. I have also been having issues with adding references to form text boxes but I may submit that as a separate question. Whenever I press the button, nothing happens. I don't even get an error screen. I have seen other answers where the issue seems to be how the OpenRecordSet is being used but I am having trouble understanding how I can apply it to this code.
The query itself does work when I create a separate query in Access so I am not sure where the problem is. I reformatted the SQL portion of the code to make it easier to read here, but I have it formatted as a single line in the actual VBA code.
It looks like you want to open a query in Access for display based on a SQL string
The following function will create a query based on the SQL string
Function createQry(qryName As String, sSQL As String)
Dim qdf As QueryDef
' Delete existing query
On Error Resume Next
CurrentDb.QueryDefs.Delete (qryName)
On Error GoTo 0
Set qdf = CurrentDb.CreateQueryDef(qryName, sSQL)
End Function
If you use this code in your posted code like that
Private Sub ManuReport_Click()
Dim dbs As DAO.Database
Dim rsSQL As DAO.Recordset
Dim StrSQL As String
Set dbs = CurrentDb
StrSQL = "SELECT " & _
"dbo_VENDOR1.ITEM_NO," & _
"dbo_VENDOR1.ITEM_PRICE," & _
"dbo_VENDOR2.ITEM_NO," & _
"dbo_VENDOR2.ITEM_PRICE," & _
"dbo_VENDOR1.MANUFACTURER_ITEM_NO," & _
"dbo_VENDOR1.MANUFACTURER," & _
"dbo_VENDOR1.ITEM_NAME " & _
"From dbo_VENDOR2 " & _
"INNER JOIN dbo_VENDOR1 " & _
"ON dbo_VENDOR2.MANUFACTURER_ITEM_NO = dbo_VENDOR1.MANUFACTURER_ITEM_NO " & _
"WHERE dbo_VENDOR1.MANUFACTURER IN ('MANUFACTURER CODE') " & _
"And dbo_VENDOR1.ITEM_PRICE > dbo_VENDOR2.ITEM_PRICE "
'Set rsSQL = dbs.OpenRecordset(StrSQL, dbOpenDynaset)
Dim qryName As String
qryName = "qryTest"
' close the query in case it is open in Access
DoCmd.SetWarnings False
DoCmd.Close acQuery, qryName
DoCmd.SetWarnings True
' Create the query based on the SQL string
createQry qryName, StrSQL
' Open the query in Access for display
DoCmd.OpenQuery qryName, acNormal, acReadOnly
End Sub

Join Excel-Table with SQL Server

My excel-sheet is connected with the data of the sql-server. My clients shall be able to write some columns back to the sql server. The excel-filenames are variable, but the sheeetname and the columns are always static. I tried it with a button and vba but it ends up in error:
Syntaxerror (missing operator) in queryexpression 'UPDATE hbs SET lieferinfo_prio_neu = xlsx.liefer_prio_neu FROM [Provider=SQLOLEDB;Data Source=myserver;Database=mydb;UID=myuser;PWD=mypass;].[tbl_haka_base_size] hbs JOIN [Tabelle3$] xlsx ON xlsx.Artikelnummer'
The internal excel-sheetname is 'Tabelle3', the custom-name is 'Hakabase':
I tried both names without any result.
My code:
Dim excelConn As String
Dim sqlServerConn As String
Dim sqlCommand As String
Dim conn As ADODB.Connection
excelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& ThisWorkbook.FullName _
& ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;IMEX=1"";"
sqlServerConn = "[Provider=SQLOLEDB;" _
& "Data Source=myserver;" _
& "Database=mydb;" _
& "UID=ymuser;PWD=mypass;]"
sqlCommand = "UPDATE hbs " _
& " SET lieferinfo_prio_neu = xlsx.liefer_prio_neu " _
& " FROM " & sqlServerConn & ".[tbl_haka_base_size] hbs " _
& " JOIN [Tabelle3$] xlsx " _
& " ON xlsx.Artikelnummer=hbs.artikelnummer"
Set conn = New ADODB.Connection
conn.Open excelConn
conn.Execute sqlCommand
I've also tried to connect to the sqlserver + join the excel-data via openrowset but the server disallowed that:
& " JOIN OPENROWSET('MSDASQL', " _
& " 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" _
& ThisWorkbook.FullName & "', 'SELECT * FROM [Tabelle3$]') xlsx" _
Installable ISAM not found
I think I have to create a linked server for each file and enable 'InProcess' for those files. This is not possible because the files are variable.
I've found an alternative solution which is a little bit slow so I still hope someone else is able to answer my question.
The alternative solution is to iterate through each row.. The file got about 150.000 rows and just for 10.000 rows I am waiting about 10 minutes..
Here is the part of iterating
For Each range In sheet.rows: Do
'Continue on headline
If range.Row = 1 Or range.EntireRow.Hidden = True Then
Exit Do
End If
If Len(sheet.Cells(range.Row, lieferInfoColumnIndex)) > 0 Then
articleNumber = sheet.Cells(range.Row, artNoColumnIndex)
UpdateDatabase (articleNumber)
savings = savings + 1
End If
Loop While False: Next range
Here is the slow update function for each row:
Private Sub UpdateDatabase(articleNumber As String)
Dim sqlServerConn As String
Dim sqlCommand As String
Dim conn As ADODB.Connection
sqlServerConn = "Provider=SQLOLEDB;" _
& "Data Source=myserver;" _
& "Database=mydb;" _
& "UID=myuser;PWD=mypass;"
sqlCommand = "UPDATE hbs " _
& "SET lieferinfo_prio_neu=NULL " _
& "FROM [TBL_HAKA_BASE] hbs " _
& "WHERE Artikelnummer=" + articleNumber
Set conn = New ADODB.Connection
conn.Open sqlServerConn
conn.Execute sqlCommand
End Sub

How to fix error "SQLexception was unhandled by user code incorrect syntax near 'FROM'

Anyone can help me on where the 'FROM' error is would be greatly
Here my code vb is problem
Imports System.Data
Imports System.Data.SqlClient
Private Sub ButtonOK_Click() Handles ButtonOK.Click
sql = "SELECT Drug.DrugID, Drug.DrugName, Categories.CategoryName, " & _
"Suppliers.CompanyName, Drug.UnitPrice, Drug.UnitsInstock, " & _
"FROM Drug " & _
"LEFT JOIN Categories " & _
"ON (Drug.CategoryID = Categories.CategoryID) " & _
"LEFT JOIN Suppliers " & _
"ON (Drug.SupplierID = Suppliers.SupplierID) " & _
"WHERE Drug.ExpireDate BETWEEN #dt1 AND #dt2"
command = New SqlCommand(sql, connection)
Dim dt1 As String = GetDateTime(DateTimePicker1)
Dim dt2 As String = GetDateTime(DateTimePicker2)
command.Parameters.AddWithValue("dt1", dt1)
command.Parameters.AddWithValue("dt2", dt2)
adapter = New SqlDataAdapter(command)
dataSt = New DataSet()
adapter.Fill(dataSt, "expire")
DataGridView1.DataSource = dataSt.Tables("expire")
DataGridView1.RowsDefaultCellStyle.BackColor = Color.White
DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = _
Color.PowderBlue
For i = 0 To headerText.Length - 1
DataGridView1.Columns(i).HeaderText = headerText(i)
Next
ButtonToExcel.Enabled = True
End Sub
Here's the error:
Incorrect syntax near the keyword 'FROM'.
This may work, Just remove the extra ',' from the end of second line.
sql = "SELECT Drug.DrugID, Drug.DrugName, Categories.CategoryName, " & _
"Suppliers.CompanyName, Drug.UnitPrice, Drug.UnitsInstock " & _
"FROM Drug " & _
"LEFT JOIN Categories " & _
"ON (Drug.CategoryID = Categories.CategoryID) " & _
"LEFT JOIN Suppliers " & _
"ON (Drug.SupplierID = Suppliers.SupplierID) " & _
"WHERE Drug.ExpireDate BETWEEN #dt1 AND #dt2"

Run-time error 3061 Too few Parameters. Expected 2

Can someone please let me know what is wrong with this code? I have checked all lines for misspellings - this isnt the issue. All tables and queries are written as they exist in the db. Any help is appreciated.
Private Sub LoadArray()
'---------------------------
'---------------------------
'This procedure loads text into the 3rd column of the array
'---------------------------
'---------------------------
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsFiltered As DAO.Recordset
Dim strSQL As String
Dim i As Integer
strSQL = "SELECT tblProperties.Name, tbl1OpportuniyType.Type, qryPropertiesALLTypesALLTbls.TotalUnits, " _
& "qryPropertiesALLTypesALLTbls.EventStartTimeEachDay, qryPropertiesALLTypesALLTbls.EventEndTimeEachDay, " _
& "qryPropertiesALLTypesALLTbls.EventStartDate, qryPropertiesALLTypesALLTbls.EventStopDate, " _
& "qryPropertiesALLTypesALLTbls.TechOpsGroup, qryPropertiesALLTypesALLTbls.TechOpsResource " _
& "FROM tbl1OpportuniyType RIGHT JOIN (qryPropertiesALLTypesALLTbls INNER JOIN tblProperties ON qryPropertiesALLTypesALLTbls.[PropertyComplex_ID] = tblProperties.[PropertyComplex_ID]) ON tbl1OpportuniyType.[OpportunityType_ID] = tblProperties.OpportunityType " _
& "WHERE (((qryPropertiesALLTypesALLTbls.EventStartDate) Is Not Null));"
'Debug.Print strSQL
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL)
'This line ensures that the recordset is populated
If Not rs.BOF And Not rs.EOF Then
'Loops through the Array using dates for the filter
For i = LBound(myArray) To UBound(myArray)
If myArray(i, 1) Then
'Filters recordset with array dates
rs.Filter = "[EventStartDate]= " & myArray(i, 0)
'Open up new recordset based on filter
Set rsFiltered = rs.OpenRecordset
'Loop through new recordset
Do While (Not rsFiltered.EOF)
'Adds text to the 3rd column of the array
myArray(i, 2) = myArray(i, 2) & vbNewLine _
& rsFiltered!Type & " - " & vbNewLine _
& rsFiltered!Name & " " _
& rsFiltered!EventStartDate & " - " _
& rsFiltered!EventStopDate & " " _
& rsFiltered!EventStartTimeEachDay & " - " _
& rsFiltered!TechOpsGroup & " " _
& rsFiltered!TechOpsResource & " " _
& vbNewLine
rsFiltered.MoveNext
Loop
End If
Next i
End If
rsFiltered.Close
rs.Close
'Sets objects to nothing
Set rsFiltered = Nothing
Set rs = Nothing
Set db = Nothing
End Sub
It isn't clear where myArray comes from, but the filter needs an adjustment to convert the date value to a string expression:
rs.Filter = "[EventStartDate] = #" & Format(myArray(i, 0), "yyyy\/mm\/dd") & "#"

Replacing SQL Data Table with New Data

I have the following code, which uploads data from access to a SQL Server table. The problem is it wont overwrite/replace the table when I try to update it. I get an error saying the table already exists. I need to either add some code to delete the table so the new one can be uploaded or a way to append the new/edited records to the table.
Public Function Update()
DoCmd.TransferDatabase _
acExport, _
"ODBC Database", _
"ODBC;" & _
"Driver={SQL Server Native Client 10.0};" & _
"Server=SERVER;" & _
"Database=DB;" & _
"UID=ID;" & _
"PWD=PW;", _
acTable, _
"CDData", _
"AC_CDData", _
False
End Function
So the AC_CDData table is the one that needs to be replaced
If you want to DROP the existing destination table before transferring the new one then the code would be more like this:
Option Compare Database
Option Explicit
Public Function TransferTableToSqlServer()
Dim cdb As dao.Database, qdf As dao.QueryDef
Dim err As dao.Error
Const DestinationTableName = "AC_CDData"
Const ConnectionString = _
"ODBC;" & _
"Driver={SQL Server Native Client 10.0};" & _
"Server=(local)\SQLEXPRESS;" & _
"Database=YourDatabaseName;" & _
"UID=YourSqlUserId;" & _
"PWD=YourSqlPassword;"
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
qdf.Connect = ConnectionString
qdf.sql = _
"IF EXISTS " & _
"(" & _
"SELECT * FROM INFORMATION_SCHEMA.TABLES " & _
"WHERE TABLE_NAME='" & DestinationTableName & " '" & _
") " & _
"DROP TABLE [" & DestinationTableName & "]"
qdf.ReturnsRecords = False
On Error GoTo TransferTableToSqlServer_qdfError
qdf.Execute dbFailOnError
On Error GoTo 0
Set qdf = Nothing
Set cdb = Nothing
DoCmd.TransferDatabase _
acExport, _
"ODBC Database", _
ConnectionString, _
acTable, _
"CDData", _
DestinationTableName, _
False
Exit Function
TransferTableToSqlServer_qdfError:
For Each err In dao.Errors
MsgBox err.Description, vbCritical, "Error " & err.Number
Next
End Function

Resources