Was hoping if someone could help re-script this for me. I have asked this question before but did not receive the help needed.
I am trying to create a excel file with a macro attached to a button that will export the data to SQL.
While creating the macro in Visual Basic for Applications my code is as follows:
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sRecordedPeriod, sEventDate, sID, sDeptCode, sOpCode, sStartTime, sFinishTime, sUnits As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=db1\db1;Initial Catalog=ProdTrack;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in FirstName
Do Until .Cells(iRowNo, 1) = ""
sRecordedPeriod = .Cells(iRowNo, 1)
sEventDate = .Cells(iRowNo, 2)
sID = .Cells(iRowNo, 3)
sDeptCode = .Cells(iRowNo, 4)
sOpCode = .Cells(iRowNo, 5)
sStartTime = .Cells(iRowNo, 6)
sFinishTime = .Cells(iRowNo, 7)
sUnits = .Cells(iRowNo, 8)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.TimeLog (RecordedPeriod, EventDate, ID, DeptCode, Opcode, StartTime, FinishTime, Units) values ('" & sRecordedPeriod & "', '" & sEventDate & "', '" & sID & "', '" & sDeptCode & "', '" & sOpCode & "', '" & sStartTime & "', '" & sFinishTime & "', '" & sUnits & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Data Successfully Exported."
conn.Close
Set conn = Nothing
End With
End Sub
I receive this error message when exporting.
Run-time error '2147217913 (80040e07)':
Conversion failed when converting date and/or time from character string.
The table I am trying to export to in SQL looks like this. I don't think I am getting an error on the EventTime as the data type is varchar(8) not a date/time data type...
My SQL table is as follows:
RecordedPeriod DATETIME NOT NULL DEFAULT (GETDATE()),
EventDate (varchar(8), not null)
ID (int, not null)
DeptCode (varchar(2), not null)
OpCode (varchar(2), not null)
StartTime (time(0), not null)
FinishTime (time(0), not null)
Units (int, not null)
This is what my Excel table looks like:
RecordedPeriod EventDate ID DeptCode OpCode StartTime FinishTime Units
null 6/22/17 45318 DC DC 8:00:00 8:15:00 250
Here's the parameter approach:
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim strSQL As String
strSQL = "INSERT INTO dbo.TimeLog " & _
"(RecordedPeriod, EventDate, ID, DeptCode, Opcode, StartTime, FinishTime, Units) " & _
"VALUES (?,?,?,?,?,?,?,?);"
Set conn = New ADODB.Connection
conn.Open ""Provider=SQLOLEDB;Data Source=db1\db1;Initial Catalog=ProdTrack;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2"
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = strSQL
iRowNo = 2
With Sheets("Sheet1")
'Loop until empty cell in FirstName
Do Until .Cells(iRowNo, 1) = ""
cmd.Parameters.Append _
cmd.CreateParameter("pRecordedPeriod", adDBTimeStamp, adParamInput, 8, .Cells(iRowNo, 1))
cmd.Parameters.Append _
cmd.CreateParameter("pEventDate", adVarChar, adParamInput, 8, .Cells(iRowNo, 2))
cmd.Parameters.Append _
cmd.CreateParameter("pID", adInteger, adParamInput, , .Cells(iRowNo, 3))
cmd.Parameters.Append _
cmd.CreateParameter("pDeptCode", adVarChar, adParamInput, 2, .Cells(iRowNo, 4))
cmd.Parameters.Append _
cmd.CreateParameter("pOpCode", adVarChar, adParamInput, 2, .Cells(iRowNo, 5))
cmd.Parameters.Append _
cmd.CreateParameter("pStartTime", adDBTime, adParamInput, 0, .Cells(iRowNo, 6))
cmd.Parameters.Append _
cmd.CreateParameter("pFinishTime", adDBTime, adParamInput, 0, .Cells(iRowNo, 7))
cmd.Parameters.Append _
cmd.CreateParameter("pUnits", adInteger, adParamInput, , .Cells(iRowNo, 8))
cmd.Execute
iRowNo = iRowNo + 1
Loop
End With
conn.Close
Set conn = Nothing
the DataTypeEnum
But this is not nice to code, compared to a DAO parameter-query. No named parameters, five parameters to configure. This is for Stored Procedures? For CRUDthis is no fun.
ADO to the rescue.
Dim cn As New ADODB.Connection
''You should probably change Activeworkbook.Fullname to the
''name of your workbook
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
& ActiveWorkbook.FullName _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
cn.Open strCon
s = "INSERT INTO [ODBC;Description=TEST;DRIVER=SQL Server;" _
& "SERVER=Server;Trusted_Connection=Yes;" _
& "DATABASE=test].SomeTable ( Col1, Col2, Col3, Col4 ) " _
& "SELECT a.Col1, a.Col2, a.Col3, a.Col4 " _
& "FROM [Sheet2$] a " _
& "LEFT JOIN [ODBC;Description=TEST;DRIVER=SQL Server;" _
& "SERVER=Server;Trusted_Connection=Yes;" _
& "DATABASE=test].SomeTable b ON a.Col1 = b.Col1 " _
& "WHERE b.Col1 Is Null"
cn.Execute s
Also, check out these links.
https://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm
http://tomaslind.net/2013/12/26/export-data-excel-to-sql-server/
Here is another way to do it. Maybe this is easier to follow...
Add a reference to: Microsoft ActiveX Data Objects 2.8 Library
Sub Button_Click()
'TRUSTED CONNECTION
On Error GoTo errH
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strPath As String
Dim intImportRow As Integer
Dim strFirstName, strLastName As String
Dim server, username, password, table, database As String
With Sheets("Sheet1")
server = .TextBox1.Text
table = .TextBox4.Text
database = .TextBox5.Text
If con.State <> 1 Then
con.Open "Provider=SQLOLEDB;Data Source=" & server & ";Initial Catalog=" & database & ";Integrated Security=SSPI;"
'con.Open
End If
'this is the TRUSTED connection string
Set rs.ActiveConnection = con
'delete all records first if checkbox checked
If .CheckBox1 Then
con.Execute "delete from tbl_demo"
End If
'set first row with records to import
'you could also just loop thru a range if you want.
intImportRow = 10
Do Until .Cells(intImportRow, 1) = ""
strFirstName = .Cells(intImportRow, 1)
strLastName = .Cells(intImportRow, 2)
'insert row into database
con.Execute "insert into tbl_demo (firstname, lastname) values ('" & strFirstName & "', '" & strLastName & "')"
intImportRow = intImportRow + 1
Loop
MsgBox "Done importing", vbInformation
con.Close
Set con = Nothing
End With
Exit Sub
errH:
MsgBox Err.Description
End Sub
In mssql, it recognise value of datetime at Excel as text , so you have to cast text as datetime.
cast('8:00' as datetime)
apply to your code with upper cast method .
also cells(i,1) catch numeric value.
Your sEventDate is string, so sEventDate = .Cells(iRowNo, 2).Text
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sRecordedPeriod, sEventDate, sID, sDeptCode, sOpCode, sStartTime, sFinishTime, sUnits As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=db1\db1;Initial Catalog=ProdTrack;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in FirstName
Do Until .Cells(iRowNo, 1) = ""
sRecordedPeriod = .Cells(iRowNo, 1)
sEventDate = .Cells(iRowNo, 2).Text
sID = .Cells(iRowNo, 3)
sDeptCode = .Cells(iRowNo, 4)
sOpCode = .Cells(iRowNo, 5)
sStartTime = .Cells(iRowNo, 6)
sFinishTime = .Cells(iRowNo, 7)
sUnits = .Cells(iRowNo, 8)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.TimeLog (RecordedPeriod, EventDate, ID, DeptCode, Opcode, StartTime, FinishTime, Units) values ( '" & sRecordedPeriod & "' , '" & sEventDate & "' , '" & sID & "', '" & sDeptCode & "', '" & sOpCode & "', cast('" & sStartTime & "' as datetime) , cast('" & sFinishTime & "' as datetime), '" & sUnits & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Data Successfully Exported."
conn.Close
Set conn = Nothing
End With
End Sub
Related
I have a data table that has just a few columns: GLID, Metric Category, Amount, and Metric Date. The way the data is organized on the excel file I need to use is like a matrix as so:
The date columns are the metric date and the numbers below them are the amounts. As you can see for each date there is some amount that pertains to a particular metric category and in some cases a GLID. Now what I need to do in VBA is push the data into the format as so
GLID Metric Category Amount Metric Date
5500 Property Tax-5500 -8 3/31/2020
5500 Property Tax-5500 -8 4/30/2020
So on and so forth. I am completely new to VBA so this particular task is daunting and challenging for me and thus why I made a post here. If anyone has some suggestions I would greatly appreciate it.
So far this is the setup I have in VBA:
Sub second_export()
Dim sSQL As String, sCnn As String, sServer As String
Dim db As Object, rs As Object
sServer = "CATHCART"
sCnn = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=Portfolio_Analytics;Data Source=" & sServer & ";" & _
"Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;"
Set db = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
If db.State = 0 Then db.Open sCnn
End Sub
Note For Further Clarification:
The number of columns is 36 and the number of rows is 46 in the excel file. For the categories that do not have a GLID then we can push NULL if needed.
I can push data into the database when its simply and insert but I have to pivot the data such that the GLID and Metric category are repeated for their associated dates and amounts.
First create a sheet of data to upload
Option Explicit
Sub CreateDataSheet()
Dim wb As Workbook, ws As Worksheet, wsData As Worksheet, header As Variant
Dim iLastRow, iLastCol, dt As Variant, iOutRow
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1") ' the matrix sheet
Set wsData = wb.Sheets("Sheet2") ' sheet to hold table data
wsData.Cells.Clear
wsData.Range("A1:D1") = Array("GLID", "Metric Category", "Amount", "Metric Date")
' get header
iLastCol = ws.Cells(1, Columns.Count).End(xlToLeft).Column
iLastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
header = ws.Range(ws.Cells(1, 3), ws.Cells(1, iLastCol))
'Debug.Print iLastRow, iLastCol, UBound(header, 2)
Dim r, c
iOutRow = 2
For r = 2 To iLastRow
For c = 1 To UBound(header, 2)
'Debug.Print r, header(1, c), ws.Cells(r, c + 2)
With wsData.Cells(iOutRow, 1)
.Offset(0, 0) = ws.Cells(r, 1)
.Offset(0, 1) = ws.Cells(r, 2)
.Offset(0, 2) = ws.Cells(r, c + 2)
.Offset(0, 3) = header(1, c)
End With
iOutRow = iOutRow + 1
Next
Next
wsData.Range("A1").Select
MsgBox iOutRow - 2 & " Rows created on " & wsData.Name, vbInformation
End Sub
Then create a table in the database
Sub CreateTable()
Const TABLE_NAME = "dbo.GL_TEST"
Dim SQL As String, con As Object
SQL = "CREATE TABLE " & TABLE_NAME & "( " & vbCr & _
"RECNO int NOT NULL," & vbCr & _
"GLID nchar(10)," & vbCr & _
"METRICNAME nvarchar(255)," & vbCr & _
"AMOUNT money," & vbCr & _
"METRICDATE date," & vbCr & _
"PRIMARY KEY (RECNO))"
'Debug.Print sql
Set con = mydbConnect()
'con.Execute ("DROP TABLE " & TABLE_NAME) ' use during testing
con.Execute SQL
con.Close
Set con = Nothing
MsgBox "Table " & TABLE_NAME & " created"
End Sub
using data connection.
Function mydbConnect() As Object
Dim sConStr As String
Const sServer = "CATHCART"
sConStr = "Provider=SQLOLEDB.1;" & _
"Integrated Security=SSPI;" & _
"Persist Security Info=True;" & _
"Initial Catalog=Portfolio_Analytics;" & _
"Data Source=" & sServer & ";" & _
"Use Procedure for Prepare=1;" & _
"Auto Translate=True;Packet Size=4096;"
Set mydbConnect = CreateObject("ADODB.Connection")
mydbConnect.Open sConStr
End Function
Then load the data from the sheet one record at a time with auto-commit off.
Sub LoadData()
Const TABLE_NAME = "dbo.GL_TEST"
Dim SQL As String
SQL = " INSERT INTO " & TABLE_NAME & _
" (RECNO,GLID,METRICNAME,AMOUNT,METRICDATE) VALUES (?,?,?,?,?) "
Dim con As Object, cmd As Object, rs As Variant
Set con = mydbConnect()
Set cmd = CreateObject("ADODB.Command")
With cmd
.ActiveConnection = con
.CommandType = adCmdText
.CommandText = SQL
.Parameters.Append .CreateParameter("P1", adInteger, adParamInput)
.Parameters.Append .CreateParameter("P2", adVarWChar, adParamInput, 10)
.Parameters.Append .CreateParameter("P3", adVarWChar, adParamInput, 255)
.Parameters.Append .CreateParameter("P4", adCurrency, adParamInput)
.Parameters.Append .CreateParameter("P5", adDate, adParamInput)
End With
con.Execute "SET IMPLICIT_TRANSACTIONS ON"
Dim ws As Worksheet, iLastRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet2") ' sheet were table data is
iLastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To iLastRow
cmd.Parameters(0).Value = i
cmd.Parameters(1).Value = ws.Cells(i, 1)
cmd.Parameters(2).Value = ws.Cells(i, 2)
cmd.Parameters(3).Value = ws.Cells(i, 3)
cmd.Parameters(4).Value = ws.Cells(i, 4)
cmd.Execute
Next
con.Execute "COMMIT"
con.Execute "SET IMPLICIT_TRANSACTIONS OFF"
rs = con.Execute("SELECT COUNT(*) FROM " & TABLE_NAME)
MsgBox rs(0) & " Rows are in " & TABLE_NAME, vbInformation
con.Close
Set con = Nothing
End Sub
Here's how you can loop over your data:
Sub Tester()
Dim rw As Range, n As Long
Dim GLID, category, dt, amount
For Each rw In ActiveSheet.Range("H2:AS47").Rows
'fixed per-row
GLID = Trim(rw.Cells(1).Value)
category = Trim(rw.Cells(2).Value)
'loopover the date columns
For n = 3 To rw.Cells.Count
dt = rw.Cells(n).EntireColumn.Cells(1).Value 'date from Row 1
amount = rw.Cells(n).Value
Debug.Print rw.Cells(n).Address, GLID, category, amount, dt
'insert a record using your 4 values
'switch GLID to null if empty
Next n
Next rw
End Sub
I have success making a connection between Excel and SQL with managing to add records from Excel cells to SQL database table and this is the tutorial i did:
Export data from Excel to SQL Server
a (Sign up form) i made in excel Sign up form i made , and i manage to make a Macro to (Sign Up) button to transfer the data into the SQL database and this is the code for a reference :
Sub connect()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
' Dim sCustomerId, sFirstName, sLastName As String
With Sheets("Sheet2")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=seshbones\bones;Initial Catalog=fadi;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
Name = .Cells(iRowNo, 1)
Location = .Cells(iRowNo, 2)
Age = .Cells(iRowNo, 3)
ID = .Cells(iRowNo, 4)
Mobile = .Cells(iRowNo, 5)
Email = .Cells(iRowNo, 6)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.test (Name, Location, Age, ID, Mobile, Email) values ('" & Name & "', '" & Location & "', '" & Age & "', '" & ID & "', '" & Mobile & "', '" & Email & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
me in the table
End Sub
I want to make a restriction code to not duplicate the same Username in the table, for example if the customer enters a (Username) in excel cell and pressed (SignUP) there must have a function that check the SQL database and check the Username is already taken and refuse to make the exporting and message box appears "User is already taken" i hope you got my point.
Thank you for your help guys i added the error handler code to my project, so if there a duplicate records in my database it will prevent my program from shutting down and simply warn the user "Username Already taken" this is my how i fix the code :
Sub Connect()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
' Dim sCustomerId, sFirstName, sLastName As String
'Error handler
On Error GoTo ErrHandler:
With Sheets("Sheet2")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=seshbones\bones;Initial Catalog=fadi;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
Name = .Cells(iRowNo, 1)
Location = .Cells(iRowNo, 2)
Age = .Cells(iRowNo, 3)
ID = .Cells(iRowNo, 4)
Mobile = .Cells(iRowNo, 5)
Email = .Cells(iRowNo, 6)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.test (Name, Location, Age, ID, Mobile, Email) values ('" & Name & "', '" & Location & "', '" & Age & "', '" & ID & "', '" & Mobile & "', '" & Email & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
Exit Sub
ErrHandler:MsgBox "Username Already taken" End Sub
having issue sending entire sheet to sql table. I have tried 2 different ways as shown below. both work in different ways. Ultimately I am struggling with exporting multiple rows of data to sql DB
this 1st way I can import multiple rows to sql table successfully with one click of the button, only problem is that the StartTime and FinishTime come to sql table as 00:00:00 even if I enter a normal time in excel
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sEventDate, sID, sDeptCode, sOpCode, sStartTime, sFinishTime, sUnits As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=db\db1;Initial Catalog=PTW;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in FirstName
Do Until .Cells(iRowNo, 1) = ""
sEventDate = .Cells(iRowNo, 1)
sID = .Cells(iRowNo, 2)
sDeptCode = .Cells(iRowNo, 3)
sOpCode = .Cells(iRowNo, 4)
sStartTime = .Cells(iRowNo, 5).Text
sFinishTime = .Cells(iRowNo, 6).Text
sUnits = .Cells(iRowNo, 7)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.TimeLog (EventDate, ID, DeptCode, Opcode, StartTime, FinishTime, Units) values ('" & sEventDate & "', '" & sID & "', '" & sDeptCode & "', '" & sOpCode & "', cast('" & dStartTime & "' as datetime), cast('" & dFinishTime & "' as datetime), '" & sUnits & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Data Successfully Exported."
conn.Close
Set conn = Nothing
End With
End Sub
this 2nd way works and sends the StartTime and FinishTime exactly as it is in excel table, but it only allows me to send one row to sql table at a time
Sub Button1_Click()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim strSQL As String
strSQL = "INSERT INTO dbo.TimeLog" & _
"(EventDate, ID, DeptCode, Opcode, StartTime, FinishTime, Units) " & _
"VALUES (?,?,?,?,?,?,?)"
Set conn = New ADODB.Connection
conn.Open "Provider=SQLOLEDB;Data Source=db\db1;Initial Catalog=PTW;Integrated Security=SSPI;"
iRowNo = 1
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = strSQL
With Sheets("Sheet1")
'Loop until empty cell in FirstName
Do Until .Cells(iRowNo, 1) = ""
cmd.Parameters.Append _
cmd.CreateParameter("pEventDate", adVarChar, adParamInput, 8, .Cells(iRowNo, 1))
cmd.Parameters.Append _
cmd.CreateParameter("pID", adInteger, adParamInput, , .Cells(iRowNo, 2))
cmd.Parameters.Append _
cmd.CreateParameter("pDeptCode", adVarChar, adParamInput, 2, .Cells(iRowNo, 3))
cmd.Parameters.Append _
cmd.CreateParameter("pOpCode", adVarChar, adParamInput, 2, .Cells(iRowNo, 4))
cmd.Parameters.Append _
cmd.CreateParameter("pStartTime", adDBTime, adParamInput, 0, .Cells(iRowNo, 5))
cmd.Parameters.Append _
cmd.CreateParameter("pFinishTime", adDBTime, adParamInput, 0, .Cells(iRowNo, 6))
cmd.Parameters.Append _
cmd.CreateParameter("pUnits", adInteger, adParamInput, , .Cells(iRowNo, 7))
cmd.Execute
iRowNo = iRowNo + 1
Loop
MsgBox "Data Successfully Exported"
End With
conn.Close
Set conn = Nothing
End Sub
you must cast the value. In mssql, yourt time value is recognized as string.
cast('8:00:00' as datetime)
conn.Execute "insert into dbo.TimeLog (EventDate, ID, DeptCode, Opcode, StartTime, FinishTime, Units) values ('" & sEventDate & "', '" & sID & "', '" & sDeptCode & "', '" & sOpCode & "', cast('" & dStartTime & "' as datetime), cast('" & dFinishTime & "' as datetime), '" & sUnits & "')"
Adding this inside the loop of the first script was the result I was looking for...
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = strSQL
I have some data in an Excel form and I want to import it into database. I also want to retrieve some data from database. I am using VBA for connecting to database it my code is giving me an error.
Here is the code:
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
'Open a connection to SQL Server
conn.Provider = "sqloledb"
conn.Properties("Prompt") = adPromptAlways
conn.Open "Data Source=localhost;Initial Catalog=bank;"
'conn.Open "Provider=SQLOLEDB;Data Source=ASUSBOOK\SQL2012;Initial Catalog=ExcelDemo;Integrated Security=SSPI;"
Set rs.ActiveConnection = conn
rs.Open "select code from info"
startrow = 2
Do Until rs.EOF
Cells(startrow, 5) = rs.Fields(0).Value
rs.MoveNext
startrow = startrow + 1
Loop
rs.Close
Set rs = Nothing
Dim iRowNo As Integer
Dim accountno, Amount, code As String
Dim Rowcount As Integer
Rowcount = 1
With Sheets("Sheet1")
iRowNo = 2
Do Until .Cells(iRowNo, 1) = ""
accountno = .Cells(iRowNo, 1)
Amount = .Cells(iRowNo, 2)
.Cells(iRowNo, 3) = "OK"
.Cells(iRowNo, 4) = Rowcount
.Cells(iRowNo, 5) = Post_Date
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Provider = "sqloledb"
conn.Properties("Prompt") = adPromptAlways
conn.Open "Data Source=localhost;Initial Catalog=bank;"
conn.Execute "insert into dbo.Customers (AccountNo,Amount,code) values ('" & accountno & "', '" & Amount & "', '" & code & "')"
iRowNo = iRowNo + 1
Rowcount = Rowcount + 1
DoEvents
Loop
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
End Sub
Set the CursorLocation property of the ADO Recordset to adUseClient:
conn.CursorLocation = adUseClient
I have an Excel workbook with the below code -
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sFirstName, sLastName As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;" & _
"Data Source=server1;" & _
"Initial Catalog=table1;" & _
"User ID=user1; Password=pass1"
'Skip the header row
iRowNo = 2
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
sFirstName = .Cells(iRowNo, 1)
sLastName = .Cells(iRowNo, 2)
'Generate and execute sql statement
' to import the excel rows to SQL Server table
conn.Execute "Insert into dbo.Customers (FirstName, LastName) " & _
"values ('" & sFirstName & "', '" & sLastName & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
End Sub
This opens up a connection to my database and inputs the values from the stated columns.
The primary key is an incremental key on the database. The problem is it will copy ALL values.
I'd like to add new rows of data into the Excel Sheet and only insert those rows that don't already exist.
I've tried different methods ('merge', 'if exist', if not exist', etc.) but I can't get it right.
The solution has to be through VBA. Setting up a link using SSMS is not an option.
I understand that it may be possible to use temporary tables and then trigger a procedure which performs the merge but I want to look into that as a last resort. Haven't read up on it yet (making my way through my MS SQL bible book) but I'm hoping it won't be necessary.
---Update from #Kannan's answer---
New portion of VBA -
conn.Execute "IF EXISTS (SELECT 1 FROM dbo.Customers WHERE FirstName = '" & sFirstName & "' and LastName = '" & sLastName & "') " & _
"THEN UPDATE dbo.customers SET WHERE Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "' " & _
"ELSE INSERT INTO dbo.Customers (FirstName, LastName) " & _
"VALUES ('" & sFirstName & "', '" & sLastName & "')"
This returns error 'Incorrect syntax near the keyword 'THEN'.
Your SQL query isn't quite right - there is no THEN in a SQL IF.
Also, you don't need to do anything if it does exist, so just use if not exists.
"IF NOT EXISTS (SELECT 1 FROM dbo.Customers WHERE FirstName = '" & sFirstName & "' and LastName = '" & sLastName & "') " & _
"INSERT INTO dbo.Customers (FirstName, LastName) " & _
"VALUES ('" & sFirstName & "', '" & sLastName & "')"
This should do it for you.
Sub Button_Click()
'TRUSTED CONNECTION
On Error GoTo errH
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strPath As String
Dim intImportRow As Integer
Dim strFirstName, strLastName As String
Dim server, username, password, table, database As String
With Sheets("Sheet1")
server = .TextBox1.Text
table = .TextBox4.Text
database = .TextBox5.Text
If con.State <> 1 Then
con.Open "Provider=SQLOLEDB;Data Source=" & server & ";Initial Catalog=" & database & ";Integrated Security=SSPI;"
'con.Open
End If
'this is the TRUSTED connection string
Set rs.ActiveConnection = con
'delete all records first if checkbox checked
If .CheckBox1 Then
con.Execute "delete from tbl_demo"
End If
'set first row with records to import
'you could also just loop thru a range if you want.
intImportRow = 10
Do Until .Cells(intImportRow, 1) = ""
strFirstName = .Cells(intImportRow, 1)
strLastName = .Cells(intImportRow, 2)
'insert row into database
con.Execute "insert into tbl_demo (firstname, lastname) values ('" & strFirstName & "', '" & strLastName & "')"
intImportRow = intImportRow + 1
Loop
MsgBox "Done importing", vbInformation
con.Close
Set con = Nothing
End With
Exit Sub
errH:
MsgBox Err.Description
End Sub
Add a reference to:
Microsoft ActiveX Data Objects 2.8 Library
FYI, my sheet looks like this.
You can use sql query like this:
IF Exists ( Select 1 from dbo.customers where Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "' THEN Update dbo.customers set --other columns where Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "'
ELSE Insert into dbo.Customers (FirstName, LastName) " & _
"values ('" & sFirstName & "', '" & sLastName & "')"
Not sure about the syntax for excel and C#, you can correct that similar to this query