Replacing SQL Data Table with New Data - sql-server

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

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

Access File Dialog Import- Import multiple excel tabs/sheets

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

Connecting to SQL Sever From Access Forms Using OleDb

I am working on a project to migrate a Microsoft access backend to a SQL Server backend and my customer insists on using Access to create forms to do any Insert, updates, and deletes. The problem is that he has SQL data tools on his machine and others on his team (without data tools) need to be able to use the forms too. I thought the best way to go about this is to use and OleDb connection through access to connect to the forms so his team can use it and my access knowledge is very limited. All I have so far is what is below
“Driver=SQLOLEDB;Data Source=SomeServer;Initial Catalog=SomeDatabase;Integrated Security=SSPI”
I know the user has creds on the SQL box and can connect through ODBC. We are just having trouble getting the OleDb to work. Any help on how to deploy an OleDB connection in an access form for be greatly appreciated.
Here is the connection we used for SQL Server. It supported using either Trusted Connection, or SQL Server authentication.
Call GetConnection(gvstr_SQLServer_Name, gvstr_SQLServer_Database, _
cnConn, adUseServer, False, False)
If GetConnection(gvstr_SQLServer_Name, gvstr_SQLServer_Database, _
gv_DBS_SQLServer, adUseServer, True, False) = True Then
gvbln_UsingSQLServer = True
DoCmd.Hourglass True
ReLink_SQLSERVER_Tables
Else
gvbln_UsingSQLServer = False
End If
Public Function GetConnection(ByVal strDSN As String, _
ByVal strDatabase As String, _
ByRef cnLocal As ADODB.Connection, _
ByVal CursorLoc As CursorLocationEnum, _
ByVal UsePassword As Boolean, _
ByVal blnTrusted As Boolean) As Boolean
Dim intWaitDuration As Integer
Dim strConnectString As String
Dim strDisplay As String
Const CURRENT_METHOD As String = "GetConnection"
On Error GoTo ERROR_HANDLER
GetConnection = False
intWaitDuration = 60
Retry_Connection:
If cnLocal Is Nothing Then Set cnLocal = New ADODB.Connection
If cnLocal.State = adStateOpen Then
Write_To_Log "Connection already open -- -will not reopen!!"
GetConnection = True
GoTo Proc_Exit
End If
With cnLocal
Debug.Print "Use TRUSTED CONNECTION (ABOVE)"
If gvstr_Workstation = "my-pc" Then
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"Trusted_Connection=yes"
Else
If blnTrusted = True Then
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"Trusted_Connection=yes"
Else
strConnectString = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"User Id=Sql_myuid;Password=ppppp"
strDisplay = "Driver={SQL Server};" & _
"Server=" & strDSN & ";" & _
"Database=" & strDatabase & ";" & _
"User Id=S*********t;Password=****************"
End If
End If
Write_To_Log "Will use Conn String: " & strDisplay
.ConnectionString = strConnectString
.CursorLocation = CursorLoc
.Open
End With
GetConnection = True
Proc_Exit:
Exit Function
ERROR_HANDLER:
Debug.Print Err.Number & vbCrLf & Err.Description
Err.Source = "Module_Utilities: GetConnection at Line: " & Erl
DocAndShowError
Resume Proc_Exit
Resume Next
Resume
End Function

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") & "#"

Resources