VBA ADODB recordset is closed - sql-server

I am trying to query a database using Excel VBA and write to a sheet. The VBA code I have works fine for one server/database, but when I try to pull from a different database it messes up.
When I run this on this database, I get an error stating "Operation is not allowed when object is closed." on With mrs line. I don't understand why the object is closed when I opened it two lines before.
SQL query has nocount on and ansi_warnings off.
Here is the associated VBA Code:
Dim strFileContent As String
Dim massiveString As String
Sub runSelectedQueries()
Call runQuery(Sheet3, "dbp07", "OLBRET", "C:\Queries\query.sql")
End Sub
Private Sub runQuery(outputSheet As Worksheet, serverVar As String, databaseVar As String, queryLoc As String)
Dim sSQLQry As String
Dim ReturnArray
Dim Conn As New ADODB.Connection
Dim mrs As New ADODB.Recordset
Dim DBPath As String, sconnect As String
sconnect = "Provider=SQLOLEDB;driver={SQL Server}; server=" & serverVar & "; Integrated Security=SSPI; database=" & databaseVar & ";"
MsgBox (sconnect)
'run readFile sub
readAnyFile (queryLoc)
'parse SQL file into string
sSQLString = massiveString
Conn.Open sconnect
mrs.Open sSQLString, Conn
'write in the master record set (mrs) into a sheet
With mrs
For i = 1 To .Fields.Count
outputSheet.Cells(1, i) = .Fields(i - 1).Name
Next i
End With
outputSheet.Range("A2").CopyFromRecordset mrs
'Close Recordset
mrs.Close
'Close Connection
Conn.Close
End Sub
'reads any file as input (text) not binary using EOF, stripping the metadata at begining of a file
Sub readAnyFile(queryLoc As String)
Dim FileNum As Integer
Dim DataLine As String
massiveString = ""
FileNum = FreeFile()
Open queryLoc For Input As #FileNum
While Not EOF(FileNum)
Line Input #FileNum, DataLine ' read in data 1 line at a time
massiveString = massiveString + DataLine
Wend
massiveString = Right(massiveString, Len(massiveString) - 2)
MsgBox ("Read Successfully")
MsgBox (massiveString)
End Sub
When I debug and push out the SQL code that is read from a file, I get exactly what is in SQL Server Management Studio. The SQL statement runs fine in MS Query, Python and SQL Server Management Studio as parsed by VBA so I don't think that's the issue but I could post it.

Related

How can I solve the error for connecting to SQL Server

I am getting an error for connecting to the sql error is named pipes provider could not open a connection to SQL Server 1265. Here is the code and it worked yesterday and when I check it today it is not working and I get the error.
Here is the vb code:
'Require all variables to be defined
'to prevent rogue variables and limit
'debugging time
Option Explicit
'====================================================================================
' GLOBAL VARIABLES
'====================================================================================
Private Const g_sqlServer = "EWNVM-2017U3"
Private g_lStartDate As Long
Private g_nDaysInMonth As Integer
Public Enum mrReportType
mrDailyReport
mrMonthlyReport
mrYearlyReport
End Enum
'====================================================================================
' GetData(nYear, nMonth)
'====================================================================================
Public Sub GetData(ByVal eReportType As mrReportType, ByVal nYear As Integer, Optional ByVal nMonth As Integer = 1, Optional ByVal nDay As Integer)
' On Error GoTo ErrorHandler
Dim cMRReport As New MRReport
Dim adoConn As New ADODB.Connection
Dim adoRS As New ADODB.Recordset
Dim sSqlQuery As String
Dim sStartDateFmt As String
Dim i, k As Integer
Dim sLink As String
'Get Start Date
g_lStartDate = cMRReport.GetStartDate(nYear, nMonth, nDay)
'Write report Date to RawData sheet to use on other sheets
RawData.Range("A1") = Format(g_lStartDate, "mm/yyyy")
'Show Progress Bar Form
cMRReport.ShowProgressBar
'===========================================================================================================================================
'Historian Database Queries
'===========================================================================================================================================
adoConn.ConnectionString = "Provider='SQLNCLI11';Data Source='" & g_sqlServer & "';Initial Catalog='MR_Carrolton_DB';User ID='mrsystems';Password='Reggie#123';"
adoConn.CursorLocation = adUseClient
adoConn.Open
'Daily Report Type
RawData.Range("B4", "AZ39").ClearContents
cMRReport.SetHeader Sheet2, Positioncenter, "Monthly WAS Tank Blower Runtimes Report" & vbCr & Format(g_lStartDate, "mmmm yyyy")
cMRReport.SetHeader Sheet2, PositionRight, "Pee Dee River WWTP" & vbCr & "City of Florence, SC"
QueryRuntimesDaily adoConn, adoRS, cMRReport
'Close Historian DB Connection
adoConn.Close
'-------------------------------------------------------------------------------------------------------------------------------------------
'Cleanup memory by closing
'classes we initialized
Set adoRS = Nothing
Set adoConn = Nothing
Set cMRReport = Nothing
Exit Sub
ErrorHandler:
'Clean Up
If Not adoConn Is Nothing Then
If adoConn.State = adStateOpen Then adoConn.Close
End If
Set adoConn = Nothing
cMRReport.HandleError err, "Report", "GetData"
End Sub
'===========================================================================================================================================
'Historian Database Queries Functions
'===========================================================================================================================================
'-----------------------------------------
'Query for Flow Totals Daily
'-----------------------------------------
Private Sub QueryRuntimesDaily(ByVal adoConn As ADODB.Connection, ByRef adoRS As ADODB.Recordset, cMRReport As MRReport)
' On Error GoTo ErrorHandler
Dim sSqlQuery As String
Dim i As Integer
Dim startDateSerial
Dim endDateSerial
startDateSerial = CDec(DateAdd("n", 1 * i, g_lStartDate))
' MsgBox startDateSerial
endDateSerial = CDec(DateAdd("n", 1 * i + 15, g_lStartDate))
' MsgBox endDateSerial
For i = 0 To 95
' sSqlQuery = "SELECT LogDateTime, CL2_RESIDUAL,ZW1_TURBIDITY,ZW2_TURBIDITY,ZW3_TURBIDITY,ZW4_TURBIDITY FROM MR_Carrolton_DB.dbo.DailyRuntimes ORDER BY LogDateTime"
sSqlQuery = "SELECT LogDateTime, CL2_RESIDUAL " & _
" FROM MR_Carrolton_DB.dbo.DailyRuntimes" & _
" WHERE LogDateTime >= " & startDateSerial & _
" AND LogDateTime < " & endDateSerial & _
" ORDER BY LogDateTime"
'Copy sSqlQuery value to RawData worksheet for troubleshooting
RawData.Range("B2").Value = sSqlQuery
'Open recordset (executes SQL query)
adoRS.Open sSqlQuery, adoConn, 0, 1, 1
'If recordset is not empty then copy data to raw sheet
If adoRS.BOF = False And adoRS.EOF = False Then
RawData.Cells((i + 4), 2).CopyFromRecordset adoRS
End If
'Close recordset after each query
adoRS.Close
'Update Progress Bar
cMRReport.UpdateProgressBar i, 96, "Querying for Daily Runtimes..."
'Prevent VBA from locking up Excel
'while running through loops
DoEvents
Next i
Exit Sub
ErrorHandler:
'Clean Up
If Not adoConn Is Nothing Then
If adoConn.State = adStateOpen Then adoConn.Close
End If
Set adoConn = Nothing
cMRReport.HandleError err, "Report", "QueryRuntimesMonthly"
End Sub
'-----------------------------------------
' Lock/Unlock Worksheets
'-----------------------------------------
Public Sub LockWorksheets()
Dim ws As Worksheet
Dim i As Integer
For Each ws In Worksheets
ws.Protect "reggie"
Next
End Sub
Public Sub UnLockWorksheets()
Dim ws As Worksheet
Dim i As Integer
For Each ws In Worksheets
ws.Unprotect "reggie"
Next
End Sub
it seems it is more of server administration issue than a coding one. Ping your server to check if there is connectivity problem. Your connection does not persist so you must check your "hosts" file and Sql Server settings if they are properly set.
Visit this page for step by step troubleshooting:
Resolving could not open a connection to sql server errors

ADO Connection fails to open to UPDATE an SQL database

I have an SQL database and I want to update a specific table and specific fields.
I insert records from an Excel spreadsheet into another database I created that uses the dbo schema.
I wrote a stored procedure with an UPDATE in my play database that updates a table in the erp schema. If I execute the sp in SSMS it works. If I execute the sp from Excel it fails.
I update the Play database table is by executing a SELECT sp, returning the recordset to a spreadsheet and then creating and executing an UPDATE for each row. Of course, this take longer to accomplish.
Here is the code for the UPDATE stored procedure. For testing purposes, my procedure now returns the following line from SQL
SELECT #Rows AS i_Rows, DATEDIFF(MS,#Start, #End) / 1000 AS i_Seconds, (DATEDIFF(MS,#Start, #End) - (DATEDIFF(MS,#Start, #End)/1000)) AS i_Miliseconds
Sub ExecuteProc()
Dim o_Connection As ADODB.Connection, o_Recordset As ADODB.Recordset
Dim o_Command As ADODB.Command
Dim s_ConnString As String, s_StoredProcName As String, s_ProjectID, s_Name, s_SQL1 As String
Dim b_ProjHours, b_JobHours, b_Dates As Boolean
Dim ws As Worksheet
Dim l_row, l_count As Long
Dim t_Start, t_End As Date
Dim i_Seconds As Integer
' Determine the values of certain variables
With ActiveSheet
s_Name = .Name
b_JobHours = .chkHours.Value
b_Dates = .chkDates.Value
s_ProjectID = .Cells(15, "B").Value
End With
DataWS
' Make UpdateJobOper the selected sheet
With Worksheets("DATA")
.Select
.Cells.ClearContents
End With
' Create new Connection, Recordset, Command, and Connection String
Set o_Connection = New ADODB.Connection
Set o_Recordset = New ADODB.Recordset
Set o_Command = New ADODB.Command
s_ConnString = "Driver={SQL Server};SERVER=SQLSERVER;DATABASE=Play;UID=BIExcel;PWD=BIExcel;WSID=;"
On Error GoTo CloseConnection
' Open the Connection using the connection string
o_Connection.Open s_ConnString
' Stored Procedure Name and Project ID parameter
s_StoredProcName = "Play.dbo.BIspUpateJobOper"
' Define the command used to open the stored procedure
With o_Command
.ActiveConnection = o_Connection
.CommandType = adCmdStoredProc
.CommandText = s_StoredProcName
.Parameters.Append .CreateParameter("#ProjectID", adVarChar, adParamInput, 25, s_ProjectID)
End With
' Return the recordset using the command and paste it into the DATA worksheet starting at cell A2
Set o_Recordset = o_Command.Execute
Sheets("DATA").Range("A1").CopyFromRecordset o_Recordset
' Close the recordset and connection to the SQL Server
o_Recordset.Close
o_Connection.Close
On Error GoTo 0
On Error GoTo 0
DeleteDataWS
Exit Sub
CloseConnection:
Application.ScreenUpdating = True
DeleteDataWS
MsgBox "Failed to open SQL Connection", vbCritical, "SQL Error"
o_Connection.Close
End Sub
Public Function last_row_with_data(ByVal lng_column_number As Long, shCurrent As Variant) As Long
last_row_with_data = shCurrent.Cells(Rows.Count, lng_column_number).End(xlUp).Row
End Function
Sub DataWS()
' Add a new worksheet called DATA
' If the worksheet already exists, clear it
On Error GoTo AddSheet
With Sheets("DATA")
.Select
.Cells.ClearContents
End With
Exit Sub
' If it does not exist add it
AddSheet:
ActiveWorkbook.Sheets.Add.Name = "DATA"
End Sub
Sub DeleteDataWS()
On Error GoTo GetOutOfHere
Application.DisplayAlerts = False
Worksheets("DATA").Delete
Application.DisplayAlerts = True
GetOutOfHere:
End Sub

Excel VBA Recordset is empty

i have an ADODB recordset to load data from a view in an Excel sheet. The view is located in a MS SQL database. It runs perfectly for months, but since a few days the recordset is always empty, so i did not get any results. After a long day searching the www for any reasons i found, that it can happen because i use a x32 Excel and there is so much data in the view. So i separated the procedure in two queries. This helped a lot and the macro run perfectly again. Yesterday the same error appears again, so i began to split the procedure again. But now the recordset is still empty. I don't know any reason for this. I tested it with a selection of only ten rows of the view and this runs but if i want to get 1000 rows the recordset is empty again. Does anybody know a reason for this problem? All queries give the result i want to have in the database so they are ok.
Here is my code:
Sub doStuff()
Dim sqlStatement(9) As String
Dim lrow As Long
'... other variables
sqlStatement(1) = "Select * from db.View1 where location like 'forest'"
'... other sqlStatements
For i = 0 To UBound(sqlStatement)
Call loadData(sqlStatement, lrow)
Next i
End Sub
Sub loadData(sqlStatement As String, lastrow As Long)
Dim sqlServer As String
Dim dbName As String
sqlServer = "MSSQLSERVER"
dbName = "database"
On Error Resume Next
Dim con As Object
Set con = CreateObject("ADODB.Connection")
con.Open _
"Provider = sqloledb;" & _
"Data Source=" & sqlServer & ";" & _
"Initial Catalog=" & dbName & ";" & _
"User ID=user1;" & _
"Password=abcde;"
Dim rst As Object
Set rst = CreateObject("ADODB.Recordset")
With rst
.ActiveConnection = con
.Open sqlStatement , con, adLockReadOnly
ws.Activate
If lastrow = 1 Then
For col = 0 To .Fields.Count - 1
ws.Cells(1, col + 1).Value = .Fields(col).Name
Next
End If
ws.Activate
ws.Cells(lastrow+1,1).CopyFromRecordset rst
.Close
End With
con.Close
Set rst = Nothing
Set con = Nothing
End Sub

Access VBA - method or data member not found error

I'm new to Access and thank you for reading this first.
I'm exporting a query in Access to a pipe delimited CSV file. The query is from a table which is ODBCed from SQL.
I've been getting for the line dbs.Recordset : Method or data member not found error.
Huge thanks for any suggestion to fix this.
Option Compare Database
Option Explicit
Sub Command12_Click()
Dim dbs As DAO.database
Dim rst As DAO.Recordset
Dim intFile As Integer
Dim strFilePath As String
Dim intCount As Integer
Dim strHold
strFilePath = "C:\temp\TEST.csv"
Set dbs = CurrentDb
Set rst = db.OpenRecordset("T_Export_CSV", dbOpenForwardOnly)
intFile = FreeFile
Open strFilePath For Output As #intFile
Do Until rst.EOF
For intCount = 0 To rst.Fields.Count - 1
strHold = strHold & rst(intCount).Value & "|"
Next
If Right(strHold, 1) = "|" Then
strHold = Left(strHold, Len(strHold) - 1)
End If
Print #intFile, strHold
rst.MoveNext
strHold = vbNullString
Loop
Close intFile
rst.Close
Set rst = Nothing
MsgBox ("Export Completed Successfully")
End Sub
Thank you so so much for your time and please leave any comment below for any clarification if needed. I will try my best to be responsive!
Office 15.0 object library is the one you need to include in the references for O365 objects or Office 2013 Access VBA

"Application Defined or Object Defined" error in VBA-SQL connection

I am trying to write an Exce-Vba code for SQL connection. The code, first will open the connection to the server, then it will copy a 4 columns of table (Range("C22:G81")) from my Excel-sheet to the SQL-server (I am only trying to send numerical table now as a test, I don't send any column name)
I have been trying to solve a "Application Defined or Object Defined" error quite long time. I get the error for the connection string strCon = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & strName & ";Extended Properties=""Excel 12.0;"
I even tried with another version with password option like strCon = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & strName & ";Extended Properties=""Excel 12.0; Jet OLEDB:Database Password='passwd';"
But I get the same error. I am quite new in SQL-coding. I wonder if I am missing something important.
Lasly, I don't know if it is related to this error, but I manually created 4 columns in the SQL server for my 4 columns in the Excel. Do I need to write something specific that those 4 columns in the Excel-sheet will find the right columns in the SQL-server?
Thanks in advance...
The code:
Private Sub inlasning()
Dim MyWorkBook As Workbook
Dim rs As New ADODB.Recordset
Dim conn As New ADODB.Connection
Dim ServerName As String, DataBaseName As String, strSQL As String
Set conn = New ADODB.Connection
ServerName = "E45c7642"
DataBaseName = "Tables"
' Specify the OLE DB provider
conn.Provider = "sqloledb"
' Set SQLOLEDB connection properties
conn.Properties("Data Source").Value = ServerName
conn.Properties("Initial Catalog").Value = DataBaseName
' Windows NT authentication.
conn.Properties("Integrated Security").Value = "SSPI"
conn.Open
Dim ValidSheet As Worksheet
Dim HeaderRange As Range
Dim DataRange As Range
Dim ColRange As Range
Dim LastRange As Range
Dim strName As String, strCon As String
strName = ThisWorkbook.FullName
Application.ScreenUpdating = False
Set ValidSheet = ThisWorkbook.Sheets("Sheet2") '
Set HeaderRange = ValidSheet.Range("C20:G21")
Set ColRange = HeaderRange.Find(TheHeader, , , xlWhole)
Set LastRange = ColRange.End(xlDown)
Set DataRange = ValidSheet.Range("C22:G81") ' This is what I am trying to transfer, only numeric values without column names
strCon = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & strName _
& ";Extended Properties=""Excel 12.0;"
conn.Open strCon
strSQL = "SELECT * FROM [" & ValidSheet.Name & "$" & Replace(DataRange, "$", "") & "];"
rs.Open strSQL, dbclass, adOpenStatic, adLockReadOnly
arrData = rs.GetRows
rs.Close
conn.Close
Set rs = Nothing
Set conn= Nothing
Set ValidSheet = Nothing
End Sub
After getting the same error for the "connection string", I changed the strategy, and I used dbclass procedure to open a connection. So the new code is like below. (I found this coding from a guy, but he is on vacation now, so I can't ask him).
It gets connection (dbclass) properties automatically, which are saved in the main ThisWorkbook. This code doesn't give any error at all, but it doesn't copy the column from the Excel to the database. I tried different versions for the sql-query, like SQL = .... VALUES('result') or SQL = .... VALUES(result), but there is no result again, without error.
Private Sub Testing_Click()
Dim FindColValues() As Double
Dim ValidBook As Workbook
Dim ValidSheet As Worksheet
Dim DataRange As Range
Dim dataa As Range
Application.ScreenUpdating = False
TheSheet = "Sheet2"
Set ValidSheet = Worksheets(TheSheet)
Set DataRange = ValidSheet.Range("C21:C81")
' Below creating an array "result(it)" from the seleced range.
For Each dataa In DataRange
ReDim Preserve result(it)
result(it) = dataa.Value
it = it + 1
Next
' Below is just an alternative array for "in case"
arrData = ValidSheet.Range("C22:G81").Value
SQL = "INSERT INTO Table_test (Column1) VALUES ('result()');"
dbclass.ExecuteSQL SQL
End Sub
Below is dbclass connection properties which is read automatically by the other function:
Private Sub Workbook_Open()
Dim connOk As Boolean
Dim rs As New ADODB.Recordset
Dim MyWorkBook As Workbook
Dim CurSheet As Worksheet
Set dbclass = New clsDB
dbclass.Database = "Tables"
dbclass.ConnectionType = SqlServer
dbclass.DataSource = "E45c7642"
dbclass.UserId = Application.UserName
connOk = dbclass.OpenConnection(False, True)
If connOk = False Then
MsgBox "Cannot connect"
Else
MsgBox "The server is connected"
End If
End Sub
Finally I found the problem for my second code. As I wrote before, in my alternative code (second code), I didn't get any error at all in VBA, but it didn't save my table into the server.
Now I know the reason, because my real value was in "comma" format, but the server saved the value in "dot" format. So I added Str(value) to convert the "comma" value to the "dot" value, and it works now:
....
SQL = "INSERT INTO Table_test (Column1) VALUES (" & Str(result(1)) & ")"
dbclass.ExecuteSQL SQL
End Sub

Resources