Closing an OLE DB connection opened from within a function - vb.net

Backed myself in a corner....
Used a piece of code I found on the web and can't figure out how to close this connection. The returned OleDbcommand objCommand remains open after processing. I need to it close so I can delete the file after I have pulled the data from it. (Don't want them hanging around on the server.)
This has to be easier than the 100 of lines of code that I have tried to do this. This function opens the connection.
Protected Function ExcelConnection() As OleDbCommand
Dim fileName As String = Session("newUploadedFile")
' Connect to the Excel Spreadsheet
Dim xConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & Server.MapPath(String.Format("~/Upload/{0}", fileName)) & ";" & _
"Extended Properties=Excel 8.0;"
' create your excel connection object using the connection string
Dim objXConn As New OleDbConnection(xConnStr)
objXConn.Open()
' use a SQL Select command to retrieve the data from the Excel Spreadsheet
' the "table name" is the name of the worksheet within the spreadsheet
' in this case, the worksheet name is "Sheet1" and is expressed as: [Sheet1$]
Dim objCommand As New OleDbCommand("SELECT Name FROM [Sheet1$]", objXConn)
Return objCommand
End Function
I have tried...
ExcelConnection.connection.close()
along with about 40 other attempts to recreate the Command and then close it.
Could really use some help on this one.

This is probably not the best way to do this, but if you really must do it this way consider defining and opening the connection in the calling routine and passing it into this routine as a parameter. It can then be closed in the calling routing, thus...
Sub Main()
Dim xConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & Server.MapPath(String.Format("~/Upload/{0}", fileName)) & ";" & _
"Extended Properties=Excel 8.0;"
Dim objXConn As New OleDbConnection(xConnStr)
objXConn.Open()
Dim ObjCommand As New OleDbCommand = ExcelConnection(objXConn)
'Whatever other operations you want to do with your returned OleDbCommand
...
objXConn.Close()
End Sub
Function ExcelConnection(PassedConnection As OleDbConnection) As OleDbCommand
Dim fileName As String = Session("newUploadedFile")
Dim objCommand As New OleDbCommand("SELECT Name FROM [Sheet1$]", PassedConnection)
Return objCommand
End Function
I posted something similar to this here... Best fastest way to read an Excel sheet

Related

Trying to create a table in excel via VBA and OLEDB

I am trying to create a table (tab) in Excel using VBA with ADODB. Could you tell me where I am going wrong?
I get an error at comm.Execute after the comm.CommandText = "create table [temptable]([AA] VARCHAR(40));" line:
Microsoft Access database engine could not find the object 'temptable'.
Adding a $ at the end of the table name or a # at the beginning does not seem to help.
Sub sqlquery2()
Dim rs As ADODB.Recordset
Dim conn As String
Dim conObj As ADODB.Connection
Dim comm As ADODB.Command
Dim fileName As String
Set conObj = New ADODB.Connection
Set comm = New ADODB.Command
fileName = ThisWorkbook.FullName
conn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & fileName & ";" & _
"Extended Properties=Excel 12.0 XML"
conObj.ConnectionString = conn
conObj.Open
comm.ActiveConnection = conObj
comm.CommandType = adCmdText
On Error Resume Next
comm.CommandText = "DROP TABLE [temptable];"
comm.Execute
On Error GoTo 0
comm.CommandText = "create table [temptable]([AA] VARCHAR(40));"
comm.Execute
comm.CommandText = "insert into [temptable] select [A] from [SQL_Test$];"
comm.Execute
conObj.Close
End Sub
Thank you very much in advance!
Try doing it on a closed workbook.
I've had this problem with an open workbook. It disappeared when I did it on a closed workbook. It was also crashing telling me the table (worksheet) did not exist when the wbk was open. The worksheet did exist. This problem also disappeared when I queried a closed wb.

Excel VBA ADO SQL connection error - Could not find the object

I got a brilliant answer to my previous question from #Ryan Wildry but I thought I'd ask a different question regarding the same code: here goes.
Background Info
I have a shared (network/server) Excel template file which is both the input file and the data source (although on different sheets). Let's call that Input.xltm.
The code basically picks up a input in a range on Input Sheet, takes the first two letters and finds the closest code from Code Sheet, then populates a UserForm ListBox with the top five results.
The problem
The problem comes when users set off the UserForm and the error usually returns:
Run-time error '-2147467259'
The Microsoft Access database engine could not find the object 'C:\Users\user.name\Documents\Input1'. Make sure the object exists and that you spell its name and the path name correctly.......etc
I think it may have something to do with the fact Excel puts a number after the filename because it's a template file although I don't actually know!
The code
And here's the code:
Public MyConnection As New ADODB.Connection
Public MyRecordset As New ADODB.Recordset
Private Sub UserForm_Initialize()
Dim ColumnName As String: ColumnName = "[Variant code]"
Dim SearchStr As String: SearchStr = Left(Sheets("Input Sheet").Range("B4").Value2, 2)
Dim dbstring As String
dbstring = ThisWorkbook.FullName
Application.ScreenUpdating = False
If MyConnection.State <> adStateOpen Then
With MyConnection
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbstring & _
";Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';"
.Open
End With
End If
If MyRecordset.State = adStateOpen Then MyRecordset.Close
MyRecordset.Open "Select top 5 " & ColumnName & " from [Code Sheet$] where " & ColumnName & _
" like '%" & SearchStr & "%'", MyConnection, adOpenForwardOnly, adLockReadOnly
Me.ListBox1.Clear
If Not MyRecordset.EOF Then MyRecordset.MoveFirst
Application.ScreenUpdating = True
Do Until MyRecordset.EOF
Me.ListBox1.AddItem MyRecordset.Fields(0).Value
MyRecordset.MoveNext
Loop
End Sub
I just need everyone who accesses the file through the server to be able to pick up the correct data source (which is only in the next sheet) and populate the ListBox.
I'd be thankful for any suggestions! Thanks
#UPDATE
I have checked, now if you open (and then save) the actual template file so there's no '1' after the file name, then the code works as expected. It's only when the template is opened normally and the number automatically appended that it stops working.
It seems that you do not make early-binding for MyConnection and MyRecordset first.
You can make a late-binding by
step 1.
Change
Public MyConnection As New ADODB.Connection
Public MyRecordset As New ADODB.Recordset
to
Public MyConnection As object
Public MyRecordset As object
.
step 2.
Add
Set MyConnection = createobject("adodb.connection")
Set MyRecordset = createobject("adodb.recordset")
before If MyConnection.State <> adStateOpen Then

VBA / ADO QUERY Runs on my computer and fails on coworkers computer

The following code works perfectly fine on my computer. I cannot understand why it's not working on another persons computer. Can someone lead me towards ideas that may help trouble shoot this?
The error (with on error commented out) is that the array isn't being loaded with data. Get an error like "either bof or eof is true for the current record"
Also I can tell you if the on error GoTo NEXTT is left on.. it goes there and tries to erase the array and returns a wrong data type error. Makes me think the array is empty.
I checked Conn.State and I can confirm that the connection is open.
Function sbADO(ban_id, upc_id, div_id)
'Must add Activex data objects libaray 2.8
Dim sSQLSting As String
On Error GoTo nextt
Dim Conn As New ADODB.Connection
Dim mrs As New ADODB.Recordset
Dim DBPath As String, sconnect As String
DBPath = ThisWorkbook.FullName
'You can provide the full path of your external file as shown below
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DBPath _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
Conn.Open sconnect
sSQLSting = "SELECT * From [data$] where BANNER_ID IN (" & ban_id & ") AND UPC_ID IN (" & upc_id & ") AND DIVISION_ID IN (" & div_id & ") " 'Your SQL Statemnt (Table Name= Sheet Name=[DataSheet$])
mrs.Open sSQLSting, Conn
'=>Load the Data into an array
ReturnArray = mrs.GetRows
''OR''
'=>Paste the data into a sheet
'Sheets("Sheet1").Range("A2").CopyFromRecordset mrs
'Close Recordset
mrs.Close
'Close Connection
Conn.Close
'
Exit Function
nextt:
Erase ReturnArray
'mrs.Close
Conn.Close
'MsgBox (ReturnArray(6, 2)) '(feild, row)
End Function
The problem is because
DBPath = ThisWorkbook.FullName <-- the workbook is set to read only.
Removing read only status fixes the issue.
It seems like you're using ADO to query data in the same workbook? That might be for the purposes of simplifying this problem for SO, but it would be easier and faster to get the array you need by referring to the range directly. But in this answer, I'll assume that you really do want to use ADO.
You're trying to use ADO to open the workbook, but you're not specifying the ConnectionString or Open methods with any read-only arguments. Try making these adjustments:
'Add Mode=Read
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DBPath & _
";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";Mode=Read;"
'Add adLockReadOnly
mrs.Open sSQLSting, Conn, , adLockReadOnly

Getting data from an Excel datatable using OLEDB

I have an excel 2007 xlsm file, where on one of the tabs I have several data tables. Using VB.NET, I'm trying to read one table at a time as a named range like so:
Public Function OpeDataFromRange(ByVal Filename as string, ByVal RangeName As String, ByVal bColumnNames As Boolean) as DataTable
' Returns a DataSet containing information from a named range
' in the passed Excel worksheet
Dim sHDR As String
Dim strConn As String
If bColumnNames Then
sHDR = "Yes"
Else
sHDR = "No"
End If
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Filename & ";Extended Properties=""Excel 12.0 Macro;HDR=" & sHDR & """;"
Dim objConn _
As New System.Data.OleDb.OleDbConnection(strConn)
objConn.Open()
' Create objects ready to grab data
Dim objCmd As New System.Data.OleDb.OleDbCommand( _
"SELECT * FROM [" & RangeName & "]", objConn)
Dim objDA As New System.Data.OleDb.OleDbDataAdapter()
objDA.SelectCommand = objCmd
' Fill DataSet
Dim objDS As New System.Data.DataSet()
objDA.Fill(objDS)
' Clean up and return DataSet
objConn.Close()
return objDS
End Function
But I'm getting the error at Fill command:
The Microsoft Office Access database engine could not find the object 'MyNamedTable1'. Make sure the object exists and that you spell its name and the path name correctly.
I tried to read the entire sheet in the SELECT, and then to fish out my table through objDS.Tables, but then Tables gets loaded with only one table with everything in it.
Any Recommendations?
You cannot use Microsoft.Jet.OLEDB.4.0 with Excel 12.0 you should use Microsoft.ACE.OLEDB.12.0 instead.
Incidentally, you are filling a DataSet but returning a DataTable you need to change one of those.
Personally I prefer to use a DataTable for this but you may prefer a DataSet. If you want to use a DataTable you can...
Dim objDT As New DataTable
objDT.Load(objCmd.ExecuteReader)

Error when trying to read data from Excel in VB.Net

I've tried many different routes in being able to build a page that allows the user to choose an excel file and then reads data from that file. So far all I've gotten is errors.
My latest error is: "Cannot update. Database or object is read-only."
Here is my code:
Protected Sub Upload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Upload.Click
If (testFile.HasFile) Then
Dim ds As DataSet
Dim strFileType As String = System.IO.Path.GetExtension(testFile.FileName).ToString().ToLower()
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
Dim MyConnection As System.Data.OleDb.OleDbConnection
MyConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & testFile.FileName & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=2")
' Select the data from Sheet1 ([in-house$]) of the workbook.
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
ds = New System.Data.DataSet
MyCommand.Fill(ds) - __This is where the error points.__
grvExcelData.DataSource = ds.Tables(0)
End If
End Sub
Any ideas on why this is being thrown? I'm just trying to output the data to a gridview for now. Later I will need to loop through each cell, but I'm trying one step at a time.
Also, if there's a better way to do this I am completely open to it!
Thanks!
But strFileType is the extension of the file that you wish to open. (I.E. for filename.xls it is just the .xls part)
Probably you want the full file name.
MyConnection = New System.Data.OleDb.OleDbConnection( _
"provider=Microsoft.Jet.OLEDB.4.0; " & _
"data source=" & testFile.FileName & "; " & _
"Extended Properties=Excel 8.0")
Now, for the 'better part':
You don't close the connection, and this should never happen.
A simple Using block will save you
Using MyConnection = New OleDbConnection( _
"provider=Microsoft.Jet.OLEDB.4.0; " & _
"data source=" & strFileType & "; " & _
"Extended Properties=Excel 8.0")
' Select the data from Sheet1 ([in-house$]) of the workbook.
Using MyCommand = New OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
Dim ds = New System.Data.DataSet
MyCommand.Fill(ds)
End Using
End Using
And I suggest to add the Import directive to avoid the lenghty namespace prefix for every single OleDb variable