I have some problem when I deal with MS Access. I am using SQL Server and MS Access together.
I try to insert data into a new table.
First, this program asks me to add an item to the list (it is like temporary table). And then, there is another submit button which confirms the data (this step is needed and it is not inefficient one. Please do not ask about this step).
To add data to the list, I use a stored procedure. But I do not know what do I need to do to submit the data again.
Here is my code:
Dim rs As ADODB.Recordset
strConn = "DRIVER=SQL Server;SERVER=CHU-AS-0004;DATABASE=RTC_LaplaceD_DEV;Trusted_Connection=Yes;"
Set conn = New ADODB.Connection
conn.Open strConn
cmd.ActiveConnection = conn
Set rs = New ADODB.Recordset
rs.Open "Insert into dbo.Blend values(List731.Column(1, introw),List731.Column(2, introw),TextRequestNo.Value, List731.Column(3, introw),List731.Column(4, introw),List731.Column(5, introw))"
conn.Close
Set rs = Nothing
MsgBox "Done"
When I run with this code, I get this error:
I think there is some missing in my code but I do not know how to proceed.
Is there anyone who can give me some information about this?
There are many ways to do this kind of thing. Something like this should get the job done.
Sub MoveDateFromAccessToSQLServer()
Dim adoCN As ADODB.Connection
Dim sConnString As String
Dim sSQL As String
Dim lRow As Long, lCol As Long
sConnString = "Provider=sqloledb;Server=servername;Database=NORTHWIND;User Id=xx;Password=password"
Set adoCN = CreateObject("ADODB.Connection")
'adoCN.Open sConnString
'Assumes that you have Field1, Field2 and Field3 in columns A, B and C
'Text values must be enclosed in apostrophes whereas numeric values should not.
sSQL = "INSERT INTO YOUR_TABLE (FIELD1, FIELD2, FIELD3) " & _
" VALUES (" & _
"'" & Column(1, introw) & "', " & _
"'" & Column(2, introw) & "', " & _
"'" & Column(3, introw) & "')"
adoCN.Execute sSQL
adoCN.Close
Set adoCN = Nothing
End Sub
Related
I'm using the VBA code below to import data from my Excel table to SQL server. The code is inserting one row at a time and my tables contains thousands of rows.
To improve the speed of the import I want to import 1.000 rows at a time. How can I modify the code to insert 1.000 rows for each excecution?
I am not very skilled within VBA and found the code on this URL: http://tomaslind.net/2013/12/26/export-data-excel-to-sql-server/
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sCustomerId, sFirstName, sLastName As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=MSI\SQL2016;Initial Catalog=ExcelDemo;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
sCustomerId = .Cells(iRowNo, 1)
sFirstName = .Cells(iRowNo, 2)
sLastName = .Cells(iRowNo, 3)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.CustomersStage (CustomerId, FirstName, LastName) values ('" & sCustomerId & "', '" & sFirstName & "', '" & sLastName & "')"
iRowNo = iRowNo + 1
Loop
conn.Execute "EXEC dbo.MergeCustomers"
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
End Sub
Great point! Bulk Insert is the fastest option out there. You can use Excel for this, of course, but that's a very, very, very sub-optimal solution. If you just want to get it done quickly, and easily, save the Excel file as a CSV file, and run the code below.
BULK
INSERT listcustomer
FROM 'c:\your_file.csv'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
GO
If Bulk Insert is not an option for you, consider the two solutions below.
Either.
Sub UpdateTable()
Dim cnn As Object
Dim wbkOpen As Workbook
Dim objfl As Variant
Dim rngName As Range
Workbooks.Open "C:\Users\Excel\Desktop\Excel_to_SQL_Server.xls"
Set wbkOpen = ActiveWorkbook
Sheets("Sheet1").Select
Set rngName = Range(Range("A1"), Range("A1").End(xlToLeft).End(xlDown))
rngName.Name = "TempRange"
strFileName = wbkOpen.FullName
Set cnn = CreateObject("ADODB.Connection")
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFileName & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes"";"
nSQL = "INSERT INTO [odbc;Driver={SQL Server};Server=Your_Server_Name;Database=[Northwind].[dbo].[TBL]]"
nJOIN = " SELECT * from [TempRange]"
cnn.Execute nSQL & nJOIN
MsgBox "Uploaded Successfully"
wbkOpen.Close
Set wbkOpen = Nothing
End Sub
Or.
Sub InsertInto()
'Declare some variables
Dim cnn As adodb.Connection
Dim cmd As adodb.Command
Dim strSQL As String
'Create a new Connection object
Set cnn = New adodb.Connection
'Set the connection string
cnn.ConnectionString = "Your_Server_Name;Database=Northwind;Trusted_Connection=True;"
'Create a new Command object
Set cmd = New adodb.Command
'Open the connection
cnn.Open
'Associate the command with the connection
cmd.ActiveConnection = cnn
'Tell the Command we are giving it a bit of SQL to run, not a stored procedure
cmd.CommandType = adCmdText
'Create the SQL
strSQL = "UPDATE TBL SET JOIN_DT = 2013-01-13 WHERE EMPID = 2"
'Pass the SQL to the Command object
cmd.CommandText = strSQL
'Open the Connection to the database
cnn.Open
'Execute the bit of SQL to update the database
cmd.Execute
'Close the connection again
cnn.Close
'Remove the objects
Set cmd = Nothing
Set cnn = Nothing
End Sub
To improve the speed of the import I want to import 1.000 rows at a time. How can I modify the code to insert 1.000 rows for each excecution?
Lots of ways, but none easy from VBA. Start by just using a transaction, or loading into a temp table. The way you're currently doing it requires the log file to be flushed after each insert, which is probably most of your elapsed time. Something like:
conn.Execute "begin transaction"
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
sCustomerId = .Cells(iRowNo, 1)
sFirstName = .Cells(iRowNo, 2)
sLastName = .Cells(iRowNo, 3)
'Generate and execute sql statement to import the excel rows to SQL Server table
'... set parameter values
conn.Execute "insert into dbo.CustomersStage (CustomerId, FirstName, LastName) values (#CustomerId, #FirstName, #LastName)"
iRowNo = iRowNo + 1
Loop
conn.Execute "commit transaction"
I have the table and fields created on the SQL end. The debugger points to the cnn.Execute uSQL being the issue. I am trying to write the user and computer name of who is accessing the sheet to SQL.
Sub UpdateTable()
Dim cnn As ADODB.Connection
Dim uSQL As String
Dim strText As String
Dim strDate As Date
Dim strUsername As String
Dim strComputerName As String
strUsername = Environ("username")
strComputerName = Environ("Computername")
Set cnn = New Connection
cnnstr = "Provider=SQLOLEDB; " & _
"Data Source=icl-analive; " & _
"Initial Catalog=DW_ALL;" & _
"User ID=dw_all_readonlyuser;" & _
"Trusted_Connection=Yes;"
cnn.Open cnnstr
uSQL = "INSERT INTO Audit (UN,CN) VALUES StrUsername , strComputer"
Debug.Print uSQL
cnn.Execute uSQL
cnn.Close
Set cnn = Nothing
Exit Sub
End Sub
Your uSQL should be like this:
uSQL = "INSERT INTO Audit (UN,CN) VALUES " & StrUsername & "," & strComputer
Edit:
Actually like this:
INSERT INTO Audit (UN,CN) VALUES '" & StrUsername & "','" & strComputer & "'"
The difference is that we should set the strings in inverted commas for the SQL. Thanks #Tony Dong in the comments.
This answer is a classic example of a vulnerable code for SQL injection.In order to prevent it, consider using parameterized queries as in this example:
VBA, ADO.Connection and query parameters
I have an Excel table and want to update SQL Server table records' date value (with getdate function) which referred by 12th column of Excel.
My code is as below, but I'm seeing:
Run-time error 3001 Arguments are of the wrong type or out of acceptable range or are in conflict with one another.
In SQL table MODIFIEDDATE field is datetime type, and MAINREF field is integer type.
Private Sub CommandButton2_Click()
Dim conn2 As New ADODB.Connection
Dim rst2 As New ADODB.Recordset
Dim j As Integer
conn2.ConnectionString = "Provider=SQLOLEDB.1;Password=abc;Persist Security Info=True;User ID=sa;Initial Catalog=logodb;Data Source=A3650;Use Procedure for Prepare=1;Auto"
conn2.Open
For j = 0 To 1900
If Sayfa1.Cells(j + 4, 12) = "" Then
Sayfa1.Cells(j + 4, 13) = "empty"
Else
rst2.Open "UPDATE T_015 SET MODIFIEDDATE=GETDATE() WHERE MAINREF='" & Sayfa1.Cells(j + 4, 12) & "'", conn, 1, 3
rst2.Close
End If
Next j
End Sub
I've tried to change the SQL query like, (CInt(cell.value))
rst2.Open "UPDATE T_015 SET MODIFIEDDATE=GETDATE() WHERE MAINREF='" & CInt(Sayfa1.Cells(j + 4, 12)) & "'", conn, 1, 3
but, it didn't work.
The ADODB.Recordset object should not be used for an UPDATE query. Execute the SQL statement directly from the ADODB.Connection
Dim conn2 As New ADODB.Connection
conn2.ConnectionString = "Provider=SQLNCLI11;Server=MYSERVER;Database=TMP;UID=sa;password=abc;"
conn2.Open
conn2.Execute "UPDATE T_015 SET MODIFIEDDATE=GETDATE() WHERE MAINREF=1"
There are a couple of ways you can fulfil your requirements and it seems that you are mixing the two.
One way is to update records one at a time, and to do this you would use the Connection object or, more preferably, the Command object. I say preferably because parameterised commands are a far more robust way of executing your SQL. If you intend to use SQL then it's something you probably ought to read about. The way you would do that is as follows:
Public Sub ParameterisedProcedure()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Dim v As Variant
Dim j As Integer
'Read the sheet data
v = Sayfa1.Range("L4", "M1904").Value2
'Open the database connection
Set conn = New ADODB.Connection
conn.ConnectionString = "Provider=SQLOLEDB.1;" & _
"Password=abc;" & _
"Persist Security Info=True;" & _
"User ID=sa;" & _
"Initial Catalog=logodb;" & _
"Data Source=A3650;" & _
"Use Procedure for Prepare=1;" & _
"Auto"
conn.Open
'Loop through the values to update records
For j = 1 To UBound(v, 1)
If IsEmpty(v(j, 1)) Then
v(j, 2) = "empty"
Else
'Create the parameterised command
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = "UPDATE T_015 " & _
"SET MODIFIEDDATE=? " & _
"WHERE MAINREF=?"
prm = cmd.CreateParameter(Type:=adDate, Value:=Now)
cmd.Parameters.Append prm
prm = cmd.CreateParameter(Type:=adInteger, Value:=v(j, 1))
cmd.Parameters.Append prm
cmd.Execute
End If
Next
'Write the updated values
Sayfa1.Range("L4", "M1904").Value = v
'Close the database
Set prm = Nothing
Set cmd = Nothing
conn.Close
End Sub
The other way is to use Transactions and you would indeed use a Recordset for that (ie similar to what you have already done). In this case I'd suggest it is the better way to do it because executing one command at a time (as in the above code) is very slow. A vastly quicker way would be to commit all your updates in one transaction. Like a parameterised command, it's also safe from rogue strings entering your SQL command text. The code would look like this:
Public Sub TransactionProcedure()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmdText As String
Dim v As Variant
Dim j As Integer
'Read the sheet data
v = Sayfa1.Range("L4", "M1904").Value2
'Open the database connection
Set conn = New ADODB.Connection
conn.ConnectionString = "Provider=SQLOLEDB.1;" & _
"Password=abc;" & _
"Persist Security Info=True;" & _
"User ID=sa;" & _
"Initial Catalog=logodb;" & _
"Data Source=A3650;" & _
"Use Procedure for Prepare=1;" & _
"Auto"
conn.Open
'Retrieve the data
Set rs = New ADODB.Recordset
cmdText = "SELECT * FROM T_015"
rs.Open cmdText, conn, adOpenStatic, adLockReadOnly, adCmdText
'Loop through the values to update the recordset
On Error GoTo EH
conn.BeginTrans
For j = 1 To UBound(v, 1)
If IsEmpty(v(j, 1)) Then
v(j, 2) = "empty"
Else
'Find and update the record
rs.Find "MAINREF=" & CStr(v(j, 1))
If Not rs.EOF Then
rs!ModifiedDate = Now
rs.Update
End If
End If
Next
conn.CommitTrans
'Write the updated values
Sayfa1.Range("L4", "M1904").Value = v
'Close the database
rs.Close
conn.Close
Exit Sub
EH:
conn.RollbackTrans
Sayfa1.Range("L4", "M1904").Value = v
rs.Close
conn.Close
MsgBox Err.Description
End Sub
I'm trying to export data from Excel 2010 to Access 2010 with a VBA code on my excel file when I press a button. I just want to export the data from "Water Quality" sheet to the "Water Quality" table on my database (In the excel file and access file are other sheets and tables).
My actual code is:
Sub Button14_Click()
' Exports data from the active worksheet to a table in an Access database
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim r As Long
Dim LastRow As Long
' Set cn = New ADODB.Connection
'cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; " & _
"Data Source=C:\Documents and Settings\Administrador\Mis documentos\MonEAU\modelEAU Database V.2.accdb; " & _
"Persist Security Info=False;"
strCon = "Provider=Microsoft.ACE.OLEDB.12.0; " & _
"Data Source=C:\Documents and Settings\Administrador\Mis documentos\MonEAU\modelEAU Database V.2.accdb"
' Late binding, so no reference is needed
Set cn = CreateObject("ADODB.Connection")
cn.Open strCon
' Find LastRow in Col A into the Sheet1
LastRow = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
' Insert unto a table called Water_Quality
scn = "[Excel 8.0;HDR=YES;DATABASE=" & ActiveWorkbook.FullName & "]"
strSQL = "INSERT INTO Water_Quality " _
& "SELECT * FROM " & scn & ".[Sheet1$A5:L" & LastRow & "]"
' Execute the statement
cn.Execute strSQL
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
I can debug without any problem the code but when I run it, a run error appears: "The Microsoft Office Access database engine could not find the object 'Sheet1$A5:L10'. Make sure the object exists and that you spell its name and the path name correctly." It seems that there's a problem with the line cn.Execute strSQL.
I've checked the names and the path name as well, and I can't find where the problem is.
Any help to solve it would be greatly appreciated.
Here are a few examples for inserting all the data at once:
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=z:\docs\test.accdb"
''Late binding, so no reference is needed
Set cn = CreateObject("ADODB.Connection")
cn.Open strCon
''Create a table called ATable
scn = "[Excel 8.0;HDR=YES;DATABASE=" & ActiveWorkbook.FullName & "]"
strSQL = "SELECT * INTO ATable " _
& "FROM " & scn & ".[Sheet7$A1:C4]"
''Execute the statement
cn.Execute strSQL
''Insert into a table called ATable
scn = "[Excel 8.0;HDR=YES;DATABASE=" & ActiveWorkbook.FullName & "]"
strSQL = "INSERT INTO ATable " _
& "SELECT * FROM " & scn & ".[Sheet7$A1:C4]"
''Execute the statement
cn.Execute strSQL
''Insert into a table with no column header in Excel,
''the fields are [afield],[atext],[another]
scn = "[Excel 8.0;HDR=NO;DATABASE=" & ActiveWorkbook.FullName & "]"
strSQL = "INSERT INTO ATable ([afield],[atext],[another]) " _
& "SELECT F1 As afield, F2 As AText, F3 As another FROM " _
& scn & ".[Sheet7$A1:C4]"
''Execute the statement
cn.Execute strSQL
i find this code, when trying to create db, using adodb and adox.
Here you can check original, it is the same. Thanks for author
Private Sub Command1_Click()
Dim db_file As String
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim num_records As Integer
' Get the database name.
db_file = App.Path
If Right$(db_file, 1) <> "\" Then db_file = db_file & _
"\"
db_file = db_file & "People.mdb"
' Open a connection.
Set conn = New ADODB.Connection
conn.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & db_file & ";" & _
"Persist Security Info=False"
conn.Open
' Drop the Employees table if it already exists.
On Error Resume Next
conn.Execute "DROP TABLE Employees"
On Error GoTo 0
' Create the Employees table.
conn.Execute _
"CREATE TABLE Employees(" & _
"EmployeeId INTEGER NOT NULL," & _
"LastName VARCHAR(40) NOT NULL," & _
"FirstName VARCHAR(40) NOT NULL)"
' Populate the table.
conn.Execute "INSERT INTO Employees VALUES (1, " & _
"'Anderson', 'Amy')"
conn.Execute "INSERT INTO Employees VALUES (1, 'Baker', " & _
" 'Betty')"
conn.Execute "INSERT INTO Employees VALUES (1, 'Cover', " & _
" 'Chauncey')"
' Add more records ...
' See how many records the table contains.
Set rs = conn.Execute("SELECT COUNT (*) FROM Employees")
num_records = rs.Fields(0)
conn.Close
MsgBox "Created " & num_records & " records", _
vbInformation, "Done"
End Sub
But how to make it more robust, so, i don't want to delete db.
How to check, if db exists and if db.tables contains my table?
additional question: am i right, that this code create db for ms-access 2007?
Thanks for help!
Your question includes these two:
How to check, if db exists and if db.tables contains my table?
am i right, that this code create db for ms-access 2007?
For the first part of #1, use the Dir() function.
If Len(Dir("C:\SomeFolder\YourDb.mdb")) > 0 Then
Debug.Print "db exists"
Else
Debug.Print "db not found"
End If
For the second part of #1, try this function. pTable is the name of the table you're checking for. pDbPath is the full path, including the file name, for the db file you want to examine. The path can be one which begins with a drive letter, or it can be a UNC path ( \\Server\Share\YourDb.mdb ).
Public Function TableExists(ByVal pTable As String, _
Optional ByVal pDbPath As String) As Boolean
'return True if pTable exists as either a native or linked table '
'pass any error to caller '
Dim blnReturn As Boolean
Dim db As DAO.Database
Dim tdf As DAO.TableDef
If Len(Trim(pDbPath)) > 0 Then
Set db = OpenDatabase(pDbPath)
Else
Set db = CurrentDb
End If
For Each tdf In db.TableDefs
If tdf.Name = pTable Then
blnReturn = True
Exit For
End If
Next tdf
Set tdf = Nothing
If Len(Trim(pDbPath)) > 0 Then
db.Close
End If
Set db = Nothing
TableExists = blnReturn
End Function
Regarding your second question, no that code you showed us does not create a db file for any Access version. If db_file is not the path to an existing db file, that code will throw an error at conn.Open. It does not create the missing db file.
However I doubt that code will compile as VBA, despite the fact you included VBA in your title and tagged your question as vba. Really you should have at least tried it first before including it in a question on Stack Overflow.
For creating a MDB file from VB6/VBA code you could use ADOX. Here's a sample function to create an MDB file.
Public Function CreateMDB(strDBPath As String) As Boolean
'To make code compile add a reference to Microsoft ADO Ext 2.x for DDL and Security
'(msADOX.dll)
Dim catDB As ADOX.Catalog
Dim tblNew As ADOX.Table
Dim keyPrim As New ADOX.Key
Set catDB = New ADOX.Catalog
If Dir(strDBPath) = "" Then
CreateMDB = False
End If
With catDB
.Create "Provider=Microsoft.Jet.OLEDB.4.0;Locale Identifier=" & _
1033 & ";Data Source=" & strDBPath
.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strDBPath
End With
Set tblNew = New ADOX.Table
With tblNew
.Name = "data"
With .Columns
.Append "Field_0", adVarWChar
.Append "Field_1", adVarWChar
.Append "Field_2", adVarWChar
.Append "Field_3", adVarWChar
End With
End With
catDB.Tables.Append tblNew
Set keyPrim = New ADOX.Key
With keyPrim
.Name = "Field_0"
.Type = adKeyPrimary
.RelatedTable = "data"
.Columns.Append "Field_0"
End With
catDB.Tables("data").Keys.Append keyPrim
Set catDB = Nothing
Set tblNew = Nothing
End Function