How to update MSSQL from Excel using excel VBA - sql-server

Current Situation
I have a database in MSSQL and currently it is able to link to excel the following way.
Excel table which is connected to MSSQL as follows
MSSQL table as below
Currently if I update my MSSQL table, excel table will update accordingly
What I need
I want the vice versa operation. Means whenever I update the excel table, MSSQL also needs to update. Is this possible?

I am able to do it correctly by using following code
Sub updateSqlFromExcel()
Dim cnn As ADODB.connection
Dim uSQL As String
Set cnn = New connection
cnnstr = "Provider=SQLOLEDB; " & _
"Data Source=myServer; " & _
"Initial Catalog=myDatabaseName;" & _
"User ID=username;" & _
"Password=password;" & _
"Trusted_Connection=No"
Set rngName = ActiveCell
cnn.Open cnnstr
excelId = ActiveCell.Value 'This is just an example
excelSeq = ActiveCell.Offset(0, 1).Value 'This is just an example
excelName = ActiveCell.Offset(0, 2).Value 'This is just an example
uSQL = "UPDATE myTableName SET Name = '" & excelName & "', Seq = '" & excelSeq & "' WHERE ID= '" & excelId & "' "
cnn.Execute uSQL
ActiveWorkbook.RefreshAll
MsgBox "Updated successfully. But please wait until background refresh finish before close excel", vbInformation, "Success"
cnn.Close
Set cnn = Nothing
End Sub
Please change myServer, myDatabaseName, username, passwordand myTableNameaccording to your settings in order for this macro to work. Also please add reference library Microsoft ActiveX Data Objects 2.8 Library. In order to add, press Alt+F11 and then goto Tools --> References. Scroll to Microsoft ActiveX Data Objects 2.8 Library and tick the checkbox. Press ok and you are ready to go.

Related

How to overcome resource limitation of IN operator in Microsoft SQL Server

I am trying to pass over 37K values in the WHERE clause using IN operator through Excel VBA macro. However, due to resource limitation in Microsoft SQL Server, the query won't execute. I have tried to pass the values in an array in VBA as well as tried creating a list in in SQL. Neither are able to accommodate these many values. Can somebody help? Sharing the code I have tried below.
Dim i as Long
Dim str As String
Dim dict_pn
Set dict_pn = CreateObject("Scripting.Dictionary")
i = 1
With InputS
For i = 1 to 50000
str = Trim(.Cells(i, PN_Col).Value)
dict_pn.Add str, 0
Next
With rsPubs
' Assign the Connection object.
.ActiveConnection = cnPubs
.Open Worksheets("SQL Script").Range("A1") & "('" & Join(dict_pn.keys, "','") & "') " & Worksheets("SQL Script").Range("A2") & "('" & Join(dict_pn.keys, "','") & "') " & Worksheets("SQL Script").Range("A3") & "('" & Join(dict_pn.keys, "','") & "') "
ActiveWorkbook.Worksheets("SQL Results").Range("A3").CopyFromRecordset rsPubs
You should transmit data to SQL Server like in related post
Sub UpdateTable()
Dim cnn As Object
Dim wbkOpen As Workbook
Dim objfl As Variant
Dim rngName As Range
Workbooks.Open "C:\your_path_here\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=Server_Name;Database=[Your_Database].[dbo].[TBL]]"
nJOIN = " SELECT * from [TempRange]"
cnn.Execute nSQL & nJOIN
MsgBox "Uploaded Successfully"
wbkOpen.Close
Set wbkOpen = Nothing
End Sub
and then you can do any you want - use operator IN or LEFT JOIN whith check for null on SQL server side.
You can use temporary table if you will not close connection - temp table exists only in session level.
This is way from VBA code.
Second way - you can use SSIS package to work with excel files. In package you will have same steps - data frlow to transmit data from excel to server and then run sql code to join data. Or you can use join block inside SSIS package.
Third way that you can implement if data in SQL server less than excel row count limit. You can import data from SQL into Excel sheet, and than use VLOOKUP() function to join tables and find related data.

Connect to SQL Server local database

I'm writing a macro in Microsoft Excel that makes an update in a table of my local SQL Server database,.
My connection string:
sConnect = "Driver={SQL Server};Data Source=(localdb)\MSSQLLocalDB;Database=Scrape;"
I get this error:
Data source name not found and no default driver specific
How do I write the connection string?
Ok, this should be pretty simple. See the link below.
https://www.erpsoftwareblog.com/2017/01/microsoft-excel-connections-sql-databases/
Also, check this out.
https://www.connectionstrings.com/sql-server/
Finally, to update a SQL Server table with Excel/VBA code, do the following.
Sub UpdateMyTable()
Dim cnn As ADODB.Connection
Dim uSQL As String
Dim rngName As Range
Set cnn = New Connection
cnnstr = "Provider=SQLOLEDB; " & _
"Data Source=MyServer; " & _
"Initial Catalog=MyDB;" & _
"User ID=User;" & _
"Password=Pwd;" & _
"Trusted_Connection=No"
Set rngName = ActiveCell
cnn.Open cnnstr
uSQL = "UPDATE MyTable SET Field = 1 WHERE Field = ' " & rngName & " ' "
'Debug.Print (uSQL)
cnn.Execute uSQL
cnn.Close
Set cnn = Nothing
Exit Sub
End Sub
Post back, with specific details, if you have issues with this code. Thanks.

runtime error 3704 on a opened object

I am struggling with this situation
I have a query that when i run in MSSQL server management studio it gives me 18 rows, it it stored in a cell. The database is connected to a live server and we would like to create Excel dashboards out of them so it get refreshed with live data and create graph etc....
***** EDIT *****
I tried a very simple query and it works i can get for example
select max(datetime)from table and i do have the latest sync.
The thing is: my query has
1) A Declared table for validation
2) A temporary table "with table as( ) ;" that sorts all data and rank them with some filtering "RowNumber" that is called later in with a where statement that take only some row numbers to avoid repeats
I think that in between the connection must close, can it be?
Normally this code works out but for this server i get:
"runtime error 3704 operation is not allowed when the object is closed"
I've searched the forum and the google with no luck
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Dim query As String
Set con = New ADODB.Connection
Set rs = New ADODB.Recordset
strCon = "Provider=SQLOLEDB.1;" _
& "Password=*******;" _
& "Persist Security Info=True;" _
& "User ID=********;" _
& "Initial Catalog=*******;" _
& "Data Source=***.**.**.**;" _
& "Use Procedure for Prepare=1;" _
& "Auto Translate=True;Packet Size=4096;" _
& "Use Encryption for Data=False;" _
& "Tag with column collation when possible=False"
con.Open (strCon)
rs.ActiveConnection = Con 'modified with suggestion below
strSQLQuery = Worksheets("Query").Range("B2").Value
rs.Open strSQLQuery
For i = 0 To rs.Fields.Count - 1
Sheet2.Cells(1, i + 1) = rs.Fields(i).Name
Next i
Worksheets("Result").Range("A2").CopyFromRecordset rs
rs.Close
Set rs = Nothing
con.Close
Set cn = Nothing
Can a magician help me out? because now im doing it with excel VBA as a demo but i would like to promote it to a VB tool and want to make sure it is not a server related issue.
Thank you in advance
con.Open (strCon)
rs.ActiveConnection = strCon
should be
con.Open strCon
rs.ActiveConnection = con
ie. you should set ActiveConnection to the Connection object you just opened, not to the connection string.

Import Excel Data into SQL using VB6

I'm completely new to Visual Basic and I now need to take a program that is entirely constructed in VB6 and add the ability to import a large set of records in bulk from an excel file into the current SQL Database. all of the examples I have found online are confusing and require hard-coding of the file name (ex. Using document As New Spreadsheet() document.LoadFromFile("SimpleReport.xls")) yet this needs to be called by a user anytime they get a new set of records so I need the excel file name to be specified at time of import.
How do I import from excel to SQL using VB6? Can I make a variable for the excel filename or does the string value of the filename have to be hard coded? If I can make a variable can/should I add set and get to it in order to specify the filename? Thanks
With a 32 bit Machine (O/S):
Dim cn As ADODB.Connection
Dim strSQL As String
Dim lngRecsAff As Long
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\test\myfile.xls;" & _
"Extended Properties=Excel 8.0"
'Import by using Jet Provider.
strSQL = "SELECT * INTO [odbc;Driver={SQL Server};" & _
"Server=<server>;Database=<database>;" & _
"UID=<user>;PWD=<password>].MyTable " & _
"FROM [MySheet$]"
Debug.Print strSQL
cn.Execute strSQL, lngRecsAff, adExecuteNoRecords
Debug.Print "Records affected: " & lngRecsAff
cn.Close
Set cn = Nothing
Microsoft KB : 321686 has more ideas.

Updating SQL SERVER Database from EXCEL

I have an excel sheet with some data:
1. Inventory item number
2. Description
3. Inventory Database ID (PRIMARY KEY)
I have about 1000 rows. I want to delete the item numbers in the database that match the item number in my excel list. I can write an application to do that in .NET, but that just seems overly complicated.
Is there an easy way through excel or SQL Server to run a sql statement to delete item numbers in my excel sheet with out the trouble of creating an application?
For quick updates. I find this to be the best method.
Add a column to Excel and construct your update statement as a formula, ie:
="DELETE Table1 WHERE ItemNumber='"&A1&"' AND InventoryId = "&C1
Copy the formula down, and copy/paste the result into an SQL window and run it.
Pro tip, if you have a lot of apostrophes to deal with, it might be worth it to do a global find/replace beforehand. Or you can deal with them from the formula. ie:
="DELETE Table1 WHERE ItemNumber='"&SUBSTITUTE(A1,"'","''")&"' AND InventoryId = "&C1
If you do not want to go through a SQL interface, you can run the attached code from excel, after updating the connection string obviously.
Sub ExecuteSQLCommand()
'Execute the SQL string passed through
Dim conn As ADODB.Connection, strConn As String, sSQLCommand As String
Dim cmd As ADODB.Command, lLoop As Long, lLastRow As Long
Set conn = New ADODB.Connection
conn.ConnectionString = "Provider=SQLOLEDB;" & _
"Data Source=DCC08SQL;" & _
"Initial Catalog=HarvestPress;" & _
"Integrated Security=SSPI;" & _
"Database=HarvestPress;" & _
"Trusted_Connection=True;"
conn.Open
Set cmd = New ADODB.Command
lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
With cmd
.ActiveConnection = conn
.CommandType = adCmdText
For lLoop = 1 To lLastRow
sSQLCommand = "DELETE FROM Table1 WHERE ItemNumber='" & Cells(lLoop, 1) & "' AND InventoryId = " & Cells(lLoop, 1)
.CommandText = sSQLCommand
.Execute
Next lLoop
End With
conn.Close
Set conn = Nothing
Set cmd = Nothing
End Sub

Resources