'3704' Operation is not allowed when the object is closed - sql-server

Dim ConnDB As ADODB.Connection
Dim RecSet As ADODB.Recordset
Dim ConnStr As String
Dim SQL_Query As String
Dim iCols As Integer
Const ClaimSheet = "Sheet1"
Set ConnDB = New ADODB.Connection
Set RecSet = New ADODB.Recordset
Const SQLServer = "*****"
Const SQLDB = "*****"
ConnStr = "Provider=SQLOLEDB.1;Data Source=" & SQLServer & ";" & _
"Initial Catalog=" & SQLDB & ";" & _
"Integrated Security=SSPI;"
ConnDB.ConnectionTimeout = 3
ConnDB.Open ConnStr
ConnDB.CommandTimeout = 30
SQL_Query = "EXEC [dbo].[Pivot_Claims]"
Set RecSet = ConnDB.Execute(SQL_Query)
If Not RecSet.EOF Then
ThisWorkbook.Sheets(ClaimSheet).Range("B6").CopyFromRecordset RecSet
RecSet.Close
Else
MsgBox "No Records Found"
End If
I'm trying to run the above VBA code to execute a stored procedure (Pivot_Claims) and paste the results into ClaimSheet. I am getting the error 'Operation is not allowed when the object is closed.' which pointes to the ' If Not RecSet.EOF Then' line.

You need to turn the count off on the stored proc.
SET NOCOUNT ON

Related

How to get a stored procedure as a text and alter it on another server

I would like to know how to get a stored procedure as a text and update its twin(!) on the other server with an excel macro. So I got this stored procedure on the server which has the newest version of the stored procedure:
Declare #Lines Table (Line NVARCHAR(MAX));
Declare #FullText NVARCHAR(max) = '';
INSERT #Lines EXEC sp_helptext 'StoredProcName';
Select #FullText = #FullText + Line From #Lines;
Select #FullText
#Fulltext has the complete code of 'StoredProcName'. I would like to get this code, cut the first 6 letters (CREATE), append it with "ALTER" and run it on the target server/database to update its twin(!). I got this excel macro to realize it:
Sub GetStoredProcedure()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd1 As ADODB.Command
Set cmd1 = New ADODB.Command
'Getting data from local
Set cn = New ADODB.Connection
cn.ConnectionString = _
"Provider=SQLOLEDB;" & _
"Data Source=myDataSource;" & _
"Initial Catalog=myDataBase;" & _
"Integrated Security=SSPI;"
cn.Open 'Connection establishment.
cmd1.ActiveConnection = cn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "UpdateStoredProcedure"
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
Parameter = Cells(i, 1).Value
cmd1.Parameters.Refresh
cmd1.Parameters("#sPName").Value = Parameter
Set rs = cmd1.Execute
rs.Open
Debug.Print rs.State
Range("K2").CopyFromRecordset rs
Next i
rs.Close 'Deactivating the recordset.
cn.Close 'Deactivating the connetion.
End Sub
After running this macro I get the Run-time error '3704': Operation is not allowed when the object is closed.
Thanks in advance for your help.
Try
Option Explicit
Sub GetStoredProcedure()
Dim cn As ADODB.Connection, rs As ADODB.Recordset
Dim cmd1 As ADODB.Command
'Getting data from local
Set cn = New ADODB.Connection
cn.ConnectionString = _
"Provider=SQLOLEDB;" & _
"Data Source=myDataSource;" & _
"Initial Catalog=myDataBase;" & _
"Integrated Security=SSPI;"
cn.Open 'Connection establishment.
Dim sProc As String, sCode As String, n As Long, i As Long
With Range("K:L")
.Font.Name = "Lucida Console"
.Font.Size = 11
.NumberFormat = "#"
.ColumnWidth = 85
End With
Set cmd1 = New ADODB.Command
With cmd1
.ActiveConnection = cn
.CommandType = adCmdText
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
sProc = Cells(i, 1).Value
.CommandText = "EXEC sp_helptext '" & sProc & "';"
Set rs = .Execute
sCode = rs.GetString
sCode = Replace(sCode, vbCrLf & vbCrLf, vbCrLf)
Range("K" & i).Value = sCode
Range("L" & i).Value = Replace(sCode, "CREATE PROCEDURE", "ALTER PROCEDURE")
n = n + 1
Next i
End With
rs.Close 'Deactivating the recordset.
cn.Close 'Deactivating the connetion.
MsgBox n & " procedures", vbInformation
End Sub

Code a Excel SQL into VBA - Connection string issue

I have multiple SQL queries that I build in PowerQuery.
How ever I would like to code those in VBA.
But after internet search, I still can not find my way to connect properly to the SQL tables.
I have problem in my connections string I suppose.
Please advice.
Attached is the PowerQuery querie.
Let me know please.
let
Source = Sql.Databases("EU002VM0353"),
EPV2P9028 = Source{[Name="EPV2P9053"]}[Data],
dbo_vw_pbi_01_fact_inspection_state = EPV2P9053{[Schema="dbo",Item="vw_pbi_01_fact_inspection_state"]}[Data],
#"Filtered Rows" = Table.SelectRows(dbo_vw_pbi_01_fact_inspection_state, each ([QCF Is required] = true) and ([Is NA] = false) and ([WS status] = "Active")),
If you want to get data directly from sql server to your excel sheet, you can use this piece of code:
'Define variables
Public con As Object, rs As Object, cmd As Object
Public Const provider As String = "SQLOLEDB"
Public Const server As String = "ServerName_or_IP_Adress"
Public Const database As String = "Database_Name"
Public Const serverUser As String = "ServerUser_(sa)"
Public Const serverPass As String = "xxx"
Public Const sheetName As String = "Query_Output_Sheet_Name"
' "Microsoft ActiveX Data Objects 2.8 Library" reference must be selected
Private Sub Query()
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim ws As Worksheet
Set ws = Sheets(sheetName)
Set con = New ADODB.Connection
con.ConnectionString = _
"Provider=" & provider & ";" & _
"Data Source=" & server & ";" & _
"Initial Catalog=" & database & ";" & _
"User ID=" & serverUser & ";" & _
"Password=" & serverPass & ";" & _
"Trusted_Connection=yes;" & _
"DataTypeCompatibility=80;"
con.Open
Dim Query As String
Query = "Select * from TableName"
Set cmd = New ADODB.Command
cmd.ActiveConnection = con
cmd.CommandTimeout = 600
cmd.CommandText = Query
Set rs = cmd.Execute(, , adCmdText)
If rs.EOF = False Then ws.Cells(1, 1).CopyFromRecordset rs
rs.Close
con.Close
Set rs = Nothing
Set cmd = Nothing
Set con = Nothing
End Sub
Connection variables defined as public, so you can call them from other modules or userforms. You just need to fill variables and sheet name (which you want to get the data)

VBA SQL Server Query Connecting but not Returning Records

I have this VBA code that issues a SQL Server query after a successful connection but the query returns no records (e.g., -1)
Function invested_funds() As Integer
Dim c As ADODB.Connection
Dim rs As ADODB.Recordset
Dim connectionstring As String
Dim sql As String
connectionstring = "Provider=SQLOLEDB;Data Source=DESKTOP-2TTG3GQ\SQLEXPRESS;" & _
"Initial Catalog=DB;" & _
"Integrated Security=SSPI;"
Set c = New ADODB.Connection
Set rs = New ADODB.Recordset
c.Open connectionstring
sql = "select [DB].[dbo].[db].[CSRoot] " & _
"from [DB].[dbo].[db] "
If c.State = adStateOpen Then
Debug.Print ("Connected") 'This prints!
End If
Set rs = c.Execute(sql)
Debug.Print (rs.RecordCount)
invested_funds = CInt(rs.RecordCount)
End Function
However, I know records exist and the exact same query in SSMS does indeed return records
select [DB].[dbo].[db].[CSRoot]
from [DB].[dbo].[db]
Many records, in fact.
How can this be?
You can get the number of records using the rs.getRows function.
Function invested_funds() As Integer
Dim c As ADODB.Connection
Dim rs As ADODB.Recordset
Dim connectionstring As String
Dim sql As String
connectionstring = "Provider=SQLOLEDB;Data Source=DESKTOP-2TTG3GQ\SQLEXPRESS;" & _
"Initial Catalog=DB;" & _
"Integrated Security=SSPI;"
Set c = New ADODB.Connection
Set rs = New ADODB.Recordset
c.Open connectionstring
sql = "select [DB].[dbo].[db].[CSRoot] " & _
"from [DB].[dbo].[db] "
If c.State = adStateOpen Then
Debug.Print ("Connected") 'This prints!
End If
Set rs = c.Execute(sql)
Dim arr As Variant, n As Integer
arr = rs.GetRows
n = UBound(arr, 2) + 1
'Debug.Print (rs.RecordCount)
Debug.Print n
invested_funds = n
End Function

Update/Upload values from Excel to SQL Server Database

I’ve recently got into SQL Server, trying to build some query to return info (in Excel) from our ERP system (JobBoss) database. I was wondering:
Is there a way to update/change values in the SQL Server database from Excel?
For example, I have established a connection (in Excel) to our SQL Server already, and have a query that SELECTs certain values from specific tables to create a report. However, I was wondering if I can simply change the values in Excel then somehow “upload/synchronize” with the database?
If so, what are the options?
Thanks
Going from Excel to SQL Server? You have several options.
Setup looks link this:
Sub Rectangle1_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
Also, consider this option.
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=Excel-PC\SQLEXPRESS;Database=[Northwind].[dbo].[TBL]]"
nJOIN = " SELECT * from [TempRange]"
cnn.Execute nSQL & nJOIN
MsgBox "Uploaded Successfully"
wbkOpen.Close
Set wbkOpen = Nothing
End Sub
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 = "Excel-PC\SQLEXPRESS;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
See the link below for some additional ideas of how to get this done.
https://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Introduction

I need to insert data into SQL server from Excel using VBA

I need to insert test-vba.xlsx data into SQL server to the particular database
Sub insertion()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
Dim rsstring As String
Dim m, nrows As Integer
Set wkb = Workbooks("test-vba.xlsx").Worksheets("Sheet1").Activate
sConnString = "Provider=SQLOLEDB;Data Source=PRATEEP-PC\SQLEXPRESS;" & _
"Initial Catalog=PPDS_07Dec_V1_Decomposition;" & _
"Integrated Security=SSPI;"
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
conn.Open sConnString
For m = 0 To nrows - 1
Here are a couple ideas.
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=Server_Name;Database=[Database_Name].[dbo].[TBL]]"
nJOIN = " SELECT * from [TempRange]"
cnn.Execute nSQL & nJOIN
MsgBox "Uploaded Successfully"
wbkOpen.Close
Set wbkOpen = Nothing
End Sub
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 = "Server_Name;Database=Database_Name;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
Here is another idea.
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
Also, check out the links below.
http://www.cnblogs.com/anorthwolf/archive/2012/04/25/2470250.html
http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm

Resources