The SelectCommand property has not been initialized before calling 'Fill - vb.net

Im trying to upload some records from an excel file and got that error when uploaded the source to the server.
`sqlQuery = "Select * from [Sheet1$]"
oleConn = New OleDb.OleDbConnection
oleConn.ConnectionString = conString
If oleConn.State = ConnectionState.Closed Then oleConn.Open()
oleCmd = New OleDb.OleDbCommand(sqlQuery, oleConn)
oleCmd.Connection = oleConn
oleCmd.CommandText = "Select * from [Sheet1$]"'--tried to add this but gettin the same error
oleCmd.CommandType = CommandType.Text'--and this
oleDa = New OleDb.OleDbDataAdapter(oleCmd)
oleDa.SelectCommand = oleCmd
oleDa.Fill(oleDs)
oleCmd.Dispose()
If oleConn.State = ConnectionState.Open Then oleConn.Close()
Return oleDs`

Try,
For opening connection
If oleConn.State <> ConnectionState.Open Then
oleConn.Open()
End if
For closing
If oleConn.State <> ConnectionState.Closed Then
oleConn.State.Close()
End if

still same. is that probability crash on VS. before i install SDK for VS is run good. but after fail install SDK become like that.

Try This code
Private Sub buttonExecute_Click(sender As Object, e As EventArgs) Handles buttonExecute.Click
Try
' Fill the DataGridView and connection string TextBox
Dim FilePath As String = "C:\ExcelFile.xls" 'This is where file is located
Dim FileType As String = "*.xlsx" 'This what extinction that file have
Using connection As New OleDbConnection(GetConnectionString(FilePath, FileType))
connection.Open()
textBoxConnectionString.Text = GetConnectionString(FilePath, FileType)
Using adapter As New OleDbDataAdapter("Select * from [Sheet1$]", connection)
adapter.Fill(data)
End Using
End Using
Catch ex As Exception
' Display any errors
MessageBox.Show("[" & ex.[GetType]().Name & "] " & ex.Message & ex.StackTrace)
End Try
End Sub
Here method to getconiction string:
Function Excel_GetConnectionString(FilePath As String, FileType As String) As String
' Name of the Excel worksheet to open
Dim filename As String = FilePath
' Note: the Types array exactly matches the entries in openFileDialog1.Filter
' For Excel 2007 XML (*.xlsx)
' For Excel 2007 Binary (*.xlsb)
' For Excel 2007 Macro-enabled (*.xlsm)
' For Excel 97/2000/2003 (*.xls)
Dim Types As String() = {"Excel 12.0 Xml", "Excel 12.0", "Excel 12.0 Macro", "Excel 8.0", "Excel 5.0"}
' For Excel 5.0/95 (*.xls)
' Note: openFileDialog1.FilterIndex was saved into textBoxFilename.Tag
Dim Type As String = Types(CInt(FileType) - 1)
' True if the first row in the Excel data is a header (used for column names, not data)
Dim Header As Boolean = True
' True if columns containing different data types are treated as text
' (note that columns containing only integer types are still treated as integer, etc)
Dim TreatIntermixedAsText As Boolean = True
' Build the actual connection string
Dim builder As New OleDb.OleDbConnectionStringBuilder()
builder.DataSource = filename
If Type = "Excel 5.0" OrElse Type = "Excel 8.0" Then
builder.Provider = "Microsoft.Jet.OLEDB.4.0"
Else
builder.Provider = "Microsoft.ACE.OLEDB.12.0"
End If
builder("Extended Properties") = Type & ";HDR=" & (If(Header, "Yes", "No")) & ";IMEX=" & (If(TreatIntermixedAsText, "1", "0"))
' The "ACE" provider requires either Office 2007 or the following redistributable:
' Office 2007 Data Connectivity Components:
' http://www.microsoft.com/downloads/details.aspx?familyid=7554F536-8C28-4598-9B72-EF94E038C891&displaylang=en
' The "ACE" provider can be used for older types (e.g., Excel 8.0) as well.
' The connection strings used for Excel files are not clearly documented; see the following links for more information:
' Excel 2007 on ConnectionStrings.com:
' http://www.connectionstrings.com/excel-2007
' Excel on ConnectionStrings.com:
' http://www.connectionstrings.com/excel
' Microsoft OLE DB Provider for Microsoft Jet on MSDN:
' http://msdn.microsoft.com/en-us/library/ms810660.aspx
' KB247412 Methods for transferring data to Excel from Visual Basic:
' http://support.microsoft.com/kb/247412
' KB278973 ExcelADO demonstrates how to use ADO to read and write data in Excel workbooks:
' http://support.microsoft.com/kb/278973
' KB306023 How to transfer data to an Excel workbook by using Visual C# 2005 or Visual C# .NET:
' http://support.microsoft.com/kb/306023
' KB306572 How to query and display excel data by using ASP.NET, ADO.NET, and Visual C# .NET:
' http://support.microsoft.com/kb/306572
' KB316934 How to use ADO.NET to retrieve and modify records in an Excel workbook with Visual Basic .NET:
' http://support.microsoft.com/kb/316934
Return builder.ConnectionString
End Function

Related

VB.NET reading xlsx file gives not a valid path

I can't seem to read a .xlsx file using the following connection string:
Webconfig
<add name="Excel07ConString" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1}'"/>
Code File
conStr = ConfigurationManager.ConnectionStrings("Excel07ConString").ConnectionString
Dim connExcel As New OleDbConnection(conStr)
connExcel.Open()
I have been getting this error:
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)". OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "'F:\Ishan\Projects\ImportExcel2DB\ImportExcel2DB\Files\Whole Extract.xlsx' is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on which the file resides.".
and yes there is file at this specific location. Any help would be appreciated!
The HDR needs to be either Yes or No. See my project below
Imports System.IO
Imports System.Data
Imports System.Data.OleDb
Module Module1
Sub Main()
Dim reader As New CSVReader()
Dim ds As DataSet = reader.ReadCSVFile("filename", True)
End Sub
End Module
Public Class CSVReader
Public Function ReadCSVFile(ByVal fullPath As String, ByVal headerRow As Boolean) As DataSet
Dim path As String = fullPath.Substring(0, fullPath.LastIndexOf("\") + 1)
Dim filename As String = fullPath.Substring(fullPath.LastIndexOf("\") + 1)
Dim ds As DataSet = New DataSet()
Dim header As String
If headerRow Then
header = "Yes"
Else
header = "No"
End If
Try
If File.Exists(fullPath) Then
Dim ConStr As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}" + ";Extended Properties=""Text;HDR={1};FMT=Delimited\""", path, header)
Dim SQL As String = String.Format("SELECT * FROM {0}", filename)
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter(SQL, ConStr)
adapter.Fill(ds, "TextFile")
ds.Tables(0).TableName = "Table1"
End If
For Each col As DataColumn In ds.Tables("Table1").Columns
col.ColumnName = col.ColumnName.Replace(" ", "_")
Next
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Return ds
End Function
End Class

Retrieve data from excel file to make charts using the visual basic

I'm fairly new to Visual Basic. I'm using the Visual Studio 2013 and MS Excel 2010. I would like to program a code with VB that can retrieve information from the Excel .xlsx file and using that information to make charts.
Here's the edited version:
Imports System.Reflection
Imports Excel = Microsoft.Office.Interop.Excel
'Add reference Assemblies, Framework, System.Windows.Forms.DataVisualization
'Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim excelApp As Excel.Application
Dim excelWB As Excel.Workbook
Dim excelWS As Excel.Worksheet
Dim FNameRng As Excel.Range
Dim AveRng As Excel.Range
Dim AveCLRng As Excel.Range
Dim AveUCLRng As Excel.Range
Dim FNameArry As New ArrayList()
Dim AveArry As New ArrayList()
Dim AveCLArry As New ArrayList()
Dim AveUCLArry As New ArrayList()
excelApp = CreateObject("Excel.Application")
excelApp.Visible = False
'Open the Workbook
excelWB = excelApp.Workbooks.Open("C:\Users\Joesph\Documents\Charts\Control Limit\18x17 - 10 mil stop.xlsx")
excelWS = excelApp.Sheets("18x17 - 10 mil stop")
'Set the Range for File Name
FNameRng = excelWS.Range("A2", excelWS.Range("A2").End(Excel.XlDirection.xlDown))
'Set the Range for Average Data
AveRng = excelWS.Range("B2", excelWS.Range("B2").End(Excel.XlDirection.xlDown))
AveCLRng = excelWS.Range("H2", excelWS.Range("H2").End(Excel.XlDirection.xlDown))
AveUCLRng = excelWS.Range("I2", excelWS.Range("I2").End(Excel.XlDirection.xlDown))
'Store Range as Array
FNameArry.Add(FNameRng.Value)
AveArry.Add(AveRng.Value)
AveCLArry.Add(AveCLRng.Value)
AveUCLArry.Add(AveUCLRng.Value)
Me.CenterToScreen()
Me.WindowState = FormWindowState.Maximized
Chart1.Titles.Add("Title1")
Chart1.Titles(0).Text = "Average"
Chart1.Titles(0).Font = New Font("Garamond", 24, FontStyle.Bold)
Chart1.Series("Series1").XValueMember = "FNameArry"
Chart1.Series("Series1").YValueMembers = "AveArry"
Chart1.Series("Series1").YValueMembers = "AveCLArry"
Chart1.Series("Series1").YValueMembers = "AveUCLArry"
End Sub
End Class
So, I store the Excel range into an arraylist. I used the array as the Chart points. The program now can run without any error, but it display nothing other than the chart title. What did I do wrong here? Do I have to loop the array for the chart to display the X and Y axis? Any help would be appreciated. Thank you!
Here it is. I am using the OLE db driver to get data out of xlsx instead of Interop. I am also using 3 series instead of a single one with multiple Y values.
Imports System.Windows.Forms.DataVisualization.Charting
Imports System.Data
Imports System.Data.OleDb
'The Excel file name
Dim fileName As String = "YourExcelData.xlsx"
'connection string for Xlsx files - Microsoft ACE OLEDB 12.0
'Connect to Excel 2007 (and later) files with the Xlsx file extension.
'That is the Office Open XML format with macros disabled.
' "HDR=Yes;" indicates that the first row contains columnnames, not data.
'"HDR=No;" indicates the opposite.
'"+fileNameString+" remove String from it as defind above
Dim sConn As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+fileNameString+";Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
Dim myConnection As New OleDbConnection(sConn)
myConnection.Open()
' The code to follow uses a SQL SELECT command to display the data from the worksheet.
' Create new OleDbCommand to return data from worksheet.
' change range
Dim myCommand As New OleDbCommand("Select * From [data1$A2:I2500]", myConnection)
' create a database reader
Dim myReader As OleDbDataReader = myCommand.ExecuteReader (CommandBehavior.CloseConnection)
' Populate the chart with data in the file
' can also use Chart.DataBindTable
Chart1.Series(0).Points.DataBindXY(myReader, "FNameArry", myReader, "AveArry")
Chart1.Series(1).Points.DataBindXY(myReader, "FNameArry", myReader, "AveCLArry")
Chart1.Series(2).Points.DataBindXY(myReader, "FNameArry", myReader, "AveUCLArry")
' close the reader and the connection
myReader.Close()
myConnection.Close()

Fast Export of Large Datatable to Excel Spreadsheet in VB.Net

I have an interesting conundrum here, how do I quickly (under 1 minute) export a large datatable (filled from SQL, 35,000 rows) into an Excel spreadsheet for users. I have code in place that can handle the export, and while nothing is "wrong" with the code per se, it is infuriatingly slow taking 4 minutes to export the entire file (sometimes longer if a user has less RAM or is running more on their system). Sadly, this is an improvement over the 10+ minutes it used to take using our old method. Simply put, can this be made any faster, without using 3rd party components? If so, how? My code is as follows, the slow down occurs between messageboxes 6 and 7 where each row is written. Thank you all for taking the time to take a look at this:
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnJeffTest.Click
Test(MySPtoExport)
End Sub
Private Sub Test(ByVal SQL As String)
'Declare variables used to execute the VUE Export stored procedure
MsgBox("start stop watch")
Dim ConnectionString As New SqlConnection(CType(ConfigurationManager.AppSettings("ConnString"), String))
Dim cmdSP As New SqlClient.SqlCommand
Dim MyParam As New SqlClient.SqlParameter
Dim MyDataAdapter As New SqlClient.SqlDataAdapter
Dim ExportDataSet As New DataTable
Dim FilePath As String
MsgBox("stop 1 - end of declare")
Try
' open the connection
ConnectionString.Open()
' Use the connection for this sql command
cmdSP.Connection = ConnectionString
'set this command as a stored procedure command
cmdSP.CommandType = CommandType.StoredProcedure
'get the stored procedure name and plug it in
cmdSP.CommandText = SQL
'Add the Start Date parameter if required
Select Case StDt
Case Nothing
' there's no parameter to add
Case Is = 0
' there's no parameter to add
Case Else
'add the parameter name, it's direction and its value
MyParam = cmdSP.Parameters.Add("#StartDate", SqlDbType.VarChar)
MyParam.Direction = ParameterDirection.Input
MyParam.Value = Me.txtStartDate.Text
End Select
MsgBox("stop 2 - sql ready")
'Add the End Date parameter if required
Select Case EdDt
Case Nothing
' there's no parameter to add
Case Is = 0
' there's no parameter to add
Case Else
'add the parameter name, it's direction and its value
MyParam = cmdSP.Parameters.Add("#EndDate", SqlDbType.VarChar)
MyParam.Direction = ParameterDirection.Input
MyParam.Value = Me.txtEndDate.Text
End Select
'Add the single parameter 1 parameter if required
Select Case SPar1
Case Is = Nothing
' there's no parameter to add
Case Is = ""
' there's no parameter to add
Case Else
'add the parameter name, it's direction and its value
MyParam = cmdSP.Parameters.Add(SPar1, SqlDbType.VarChar)
MyParam.Direction = ParameterDirection.Input
MyParam.Value = Me.txtSingleReportCrt1.Text
End Select
'Add the single parameter 2 parameter if required
Select Case Spar2
Case Is = Nothing
' there's no parameter to add
Case Is = ""
' there's no parameter to add
Case Else
'add the parameter name, it's direction and its value
MyParam = cmdSP.Parameters.Add(Spar2, SqlDbType.VarChar)
MyParam.Direction = ParameterDirection.Input
MyParam.Value = Me.txtSingleReportCrt2.Text
End Select
MsgBox("stop 3 - params ready")
'Prepare the data adapter with the selected command
MyDataAdapter.SelectCommand = cmdSP
' Set the accept changes during fill to false for the NYPDA export
MyDataAdapter.AcceptChangesDuringFill = False
'Fill the Dataset tables (Table 0 = Exam Eligibilities, Table 1 = Candidates Demographics)
MyDataAdapter.Fill(ExportDataSet)
'Close the connection
ConnectionString.Close()
'refresh the destination path in case they changed it
SPDestination = txtPDFDestination.Text
MsgBox("stop 4 - procedure ran, datatable filled")
Select Case ExcelFile
Case True
FilePath = SPDestination & lblReportName.Text & ".xls"
Dim _excel As New Microsoft.Office.Interop.Excel.Application
Dim wBook As Microsoft.Office.Interop.Excel.Workbook
Dim wSheet As Microsoft.Office.Interop.Excel.Worksheet
wBook = _excel.Workbooks.Add()
wSheet = wBook.ActiveSheet()
Dim dt As System.Data.DataTable = ExportDataSet
Dim dc As System.Data.DataColumn
Dim dr As System.Data.DataRow
Dim colIndex As Integer = 0
Dim rowIndex As Integer = 0
MsgBox("stop 5 - excel stuff declared")
For Each dc In dt.Columns
colIndex = colIndex + 1
_excel.Cells(1, colIndex) = dc.ColumnName
Next
MsgBox("stop 6 - Header written")
For Each dr In dt.Rows
rowIndex = rowIndex + 1
colIndex = 0
For Each dc In dt.Columns
colIndex = colIndex + 1
_excel.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
Next
Next
MsgBox("stop 7 - rows written")
wSheet.Columns.AutoFit()
MsgBox("stop 8 - autofit complete")
Dim strFileName = SPDestination & lblReportName.Text & ".xls"
If System.IO.File.Exists(strFileName) Then
System.IO.File.Delete(strFileName)
End If
MsgBox("stop 9 - file checked")
wBook.SaveAs(strFileName)
wBook.Close()
_excel.Quit()
End Select
MsgBox("File " & lblReportName.Text & " Exported Successfully!")
'Dispose of unneeded objects
MyDataAdapter.Dispose()
ExportDataSet.Dispose()
StDt = Nothing
EdDt = Nothing
SPar1 = Nothing
Spar2 = Nothing
MyParam = Nothing
cmdSP.Dispose()
cmdSP = Nothing
MyDataAdapter = Nothing
ExportDataSet = Nothing
Catch ex As Exception
' Something went terribly wrong. Warn user.
MessageBox.Show("Error: " & ex.Message, "Stored Procedure Running Process ", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
'close the connection in case is still open
If Not ConnectionString.State = ConnectionState.Closed Then
ConnectionString.Close()
ConnectionString = Nothing
End If
' reset the fields
ResetFields()
End Try
End Sub
Even though the question was asked several years ago, I thought I would add my solution since the question was posed in VB and the "best answer" is in C#. This solution writes 22,000+ rows (1.9MB) in 4 seconds on an i7 System w/ 16GB RAM.
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Main
Private Sub btnExportToExcel(sender As Object, e As EventArgs) Handles btnExpToExcel.Click
'Needed for the Excel Workbook/WorkSheet(s)
Dim app As New Excel.Application
Dim wb As Excel.Workbook = app.Workbooks.Add()
Dim ws As Excel.Worksheet
Dim strFN as String = "MyFileName.xlsx" 'must have ".xlsx" extension
'Standard code for filling a DataTable from SQL Server
Dim strSQL As String = "My SQL Statement for the DataTable"
Dim conn As New SqlConnection With {.ConnectionString = "My Connection"}
Dim MyTable As New DataTable
Dim cmd As New SqlCommand(strSQL, conn)
Dim da As New SqlDataAdapter(cmd)
da.Fill(MyTable)
'Add a sheet to the workbook and fill it with data from MyTable
'You could create multiple tables and add additional sheets in a loop
ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
DataTableToExcel(MyTable, ws, strSym)
wb.SaveAs(strFN) 'save and close the WorkBook
wb.Close()
MsgBox("Export complete.")
End Sub
Private Sub DataTableToExcel(dt As DataTable, ws As Excel.Worksheet, TabName As String)
Dim arr(dt.Rows.Count, dt.Columns.Count) As Object
Dim r As Int32, c As Int32
'copy the datatable to an array
For r = 0 To dt.Rows.Count - 1
For c = 0 To dt.Columns.Count - 1
arr(r, c) = dt.Rows(r).Item(c)
Next
Next
ws.Name = TabName 'name the worksheet
'add the column headers starting in A1
c = 0
For Each column As DataColumn In dt.Columns
ws.Cells(1, c + 1) = column.ColumnName
c += 1
Next
'add the data starting in cell A2
ws.Range(ws.Cells(2, 1), ws.Cells(dt.Rows.Count, dt.Columns.Count)).Value = arr
End Sub
End Class
Hope it helps.
As when using VBA to automate Excel, you can assign an array directly to the value of a Range object: this is done as a single operation, so you remove the overhead associated with making multiple calls across the process boundaries between your .Net code and the Excel instance.
Eg, see the accepted answer here: Write Array to Excel Range
The answer from CPRouse worked for me except that it left off the last row of data. In the Private Sub DataTableToExcel function, I added 1 to the rows.count on this line and it wrote all the records. ws.Range(ws.Cells(2, 1), ws.Cells(dt.Rows.Count + 1, dt.Columns.Count)).Value = arr
Here is a piece of my own code that performs a very fast export of data from a DataTable to an Excel sheet (use the "Stopwatch" object to compare the speed and let me a comment):
Dim _excel As New Excel.Application
Dim wBook As Excel.Workbook
Dim wSheet As Excel.Worksheet
wBook = _excel.Workbooks.Add()
wSheet = wBook.ActiveSheet()
Dim dc As System.Data.DataColumn
Dim colIndex As Integer = 0
Dim rowIndex As Integer = 0
'Nombre de mesures
Dim Nbligne As Integer = DtMesures.Rows.Count
'Ecriture des entêtes de colonne et des mesures
'(Write column headers and data)
For Each dc In DtMesures.Columns
colIndex = colIndex + 1
'Entête de colonnes (column headers)
wSheet.Cells(1, colIndex) = dc.ColumnName
'Données(data)
'You can use CDbl instead of Cobj If your data is of type Double
wSheet.Cells(2, colIndex).Resize(Nbligne, ).Value = _excel.Application.transpose(DtMesures.Rows.OfType(Of DataRow)().[Select](Function(k) CObj(k(dc.ColumnName))).ToArray())
Next
We had a VB.NET app that did exactly this, and took even longer for our users who were on slow PC's... sometimes 15 minutes.
The app is now an ASP/VB.NET app which simply builds an HTML table and outputs the result as an .xls extension... excel is able to read the HTML table and parse it into a grid format. You can still pass in XML for formatting and options, horizontal pane locking, etc.
If you don't have the option of using ASP.NET... try looking into a way to build an HTML table string and have excel parse & populate for you... much faster! I'm sure excel can parse other types as well.... XML, Arrays, HTML, etc... all would be quicker than manually building each row through VB.NET objects.

Microsoft Excel Data Connections - Alter Connection String through VBA

I have a fairly straightforward question. I am trying to find a way to alter and change a connection string for an existing data connection in an excel workbook through VBA (macro code). The main reason I am trying to do this is to find a way to prompt the user that opens up the workbook to enter their credentials (Username/Password) or have a checkbox for Trusted Connection that would be used in the Connection String of those existing data connections.
Right now the Data connections are running off a sample user that I created and that needs to go away in the production version of the workbook. Hope that makes sense?
Is this possible? If yes, could you please give me a sample/example code block? I would really appreciate any suggestions at this point.
I also had this exact same requirement and although the duplicate question Excel macro to change external data query connections - e.g. point from one database to another was useful, I still had to modify it to meet the exact requirements above. I was working with a specific connection, while that answer targeted multiple connections. So, I've included my workings here. Thank you #Rory for his code.
Also thanks to Luke Maxwell for his function to search a string for matching keywords.
Assign this sub to a button or call it when the spreadsheet is opened.
Sub GetConnectionUserPassword()
Dim Username As String, Password As String
Dim ConnectionString As String
Dim MsgTitle As String
MsgTitle = "My Credentials"
If vbOK = MsgBox("You will be asked for your username and password.", vbOKCancel, MsgTitle) Then
Username = InputBox("Username", MsgTitle)
If Username = "" Then GoTo Cancelled
Password = InputBox("Password", MsgTitle)
If Password = "" Then GoTo Cancelled
Else
GoTo Cancelled
End If
ConnectionString = GetConnectionString(Username, Password)
' MsgBox ConnectionString, vbOKOnly
UpdateQueryConnectionString ConnectionString
MsgBox "Credentials Updated", vbOKOnly, MsgTitle
Exit Sub
Cancelled:
MsgBox "Credentials have not been changed.", vbOKOnly, MsgTitle
End Sub
The GetConnectionString function stores the connection string that you insert your username and password into. This one is for an OLEDB connection and is obviously different depending on the requirements of the Provider.
Function GetConnectionString(Username As String, Password As String)
Dim result As Variant
result = "OLEDB;Provider=Your Provider;Data Source=SERVER;Initial Catalog=DATABASE" _
& ";User ID=" & Username & ";Password=" & Password & _
";Persist Security Info=True;Extended Properties=" _
& Chr(34) & "PORT=1706;LOG=ON;CASEINSENSITIVEFIND=ON;INCLUDECALCFIELDS=ON;" & Chr(34)
' MsgBox result, vbOKOnly
GetConnectionString = result
End Function
This code does the job of actually updating a named connection with your new connection string (for an OLEDB connection).
Sub UpdateQueryConnectionString(ConnectionString As String)
Dim cn As WorkbookConnection
Dim oledbCn As OLEDBConnection
Set cn = ThisWorkbook.Connections("Your Connection Name")
Set oledbCn = cn.OLEDBConnection
oledbCn.Connection = ConnectionString
End Sub
Conversely, you can use this function to get whatever the current connection string is.
Function ConnectionString()
Dim Temp As String
Dim cn As WorkbookConnection
Dim oledbCn As OLEDBConnection
Set cn = ThisWorkbook.Connections("Your Connection Name")
Set oledbCn = cn.OLEDBConnection
Temp = oledbCn.Connection
ConnectionString = Temp
End Function
I use this sub to refresh the data when the workbook is opened but it checks that there is a username and password in the connection string before doing the refresh. I just call this sub from the Private Sub Workbook_Open().
Sub RefreshData()
Dim CurrentCredentials As String
Sheets("Sheetname").Unprotect Password:="mypassword"
CurrentCredentials = ConnectionString()
If ListSearch(CurrentCredentials, "None", "") > 0 Then
GetConnectionUserPassword
End If
Application.ScreenUpdating = False
ActiveWorkbook.Connections("My Connection Name").Refresh
Sheets("Sheetname").Protect _
Password:="mypassword", _
UserInterfaceOnly:=True, _
AllowFiltering:=True, _
AllowSorting:=True, _
AllowUsingPivotTables:=True
End Sub
Here is the ListSearch function from Luke. It returns the number of matches it has found.
Function ListSearch(text As String, wordlist As String, seperator As String, Optional caseSensitive As Boolean = False)
Dim intMatches As Integer
Dim res As Variant
Dim arrWords() As String
intMatches = 0
arrWords = Split(wordlist, seperator)
On Error Resume Next
Err.Clear
For Each word In arrWords
If caseSensitive = False Then
res = InStr(LCase(text), LCase(word))
Else
res = InStr(text, word)
End If
If res > 0 Then
intMatches = intMatches + 1
End If
Next word
ListSearch = intMatches
End Function
Finally, if you want to be able to remove the credentials, just assign this sub to a button.
Sub RemoveCredentials()
Dim ConnectionString As String
ConnectionString = GetConnectionString("None", "None")
UpdateQueryConnectionString ConnectionString
MsgBox "Credentials have been removed.", vbOKOnly, "Your Credentials"
End Sub
Hope this helps another person like me that was looking to solve this problem quickly.

Problems reading an Excel file in VB.net

I have been trying to upload and read an Excel file (.xls, or .xlsx)
I am upploading sucessfully using this code:
Protected Sub btnUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUpload.Click
Dim filepath As String = ""
If FileUpload1.HasFile Then
Try
Dim filename As String = FileUpload1.PostedFile.FileName
Dim extension = (filename.Substring(filename.LastIndexOf("."), (filename.Length() - filename.LastIndexOf("."))))
If extension = ".xlsx" Or extension = ".xls" Then
filepath = "\" & Common.toUnix(Now) & "_" & filename
FileUpload1.SaveAs(Server.MapPath("~/") & filepath)
' ==== NOW READ THE FILE
Else
StatusLabel.InnerText = "Only Excel file types are accepted (.xls/.xlsx)<br> File Uploaded had extension: " & extension
End If
Catch ex As Exception
StatusLabel.InnerText = "Upload status: The file could not be uploaded. The following error occured: " + ex.ToString()
End Try
End If
End Sub
It uploads OK, but when trying to read the file I get this error:
System.Data.OleDb.OleDbException (0x80004005): The Microsoft Jet database engine cannot open the file ''. It is already opened exclusively by another user, or you need permission to view its data.
I am using code to read similar to this:
vb.net traversing an xls / xlsx file?
Therefore the connection is as follows:
Dim connString As String = "Provider=Microsoft.Jet.OLEDB.4.0" & _
";Data Source=" & ExcelFile & _
";Extended Properties=Excel 8.0;"
Dim conn As OleDbConnection = Nothing
Dim dt As System.Data.DataTable = Nothing
Dim excelDataSet As New DataSet()
Try
conn = New OleDbConnection(connString)
conn.Open() '<<< ERROR IS RAISED ON THIS LINE
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
If dt Is Nothing Then
Return Nothing
End If
Dim excelSheets(dt.Rows.Count) As String
Dim i As Integer = 0
For Each row As DataRow In dt.Rows
excelSheets(i) = row("payments").ToString
System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)
If i = SheetNumber Then
Exit For
End If
Next
..................
I'm uploading to a shared server so don't have control as to permissions as such, but I do have read/write permissions and uploading Images works OK, but it's reading this file that I can't get to work.
NOTE
This error occurs with .xls files, when using .xlsx I get this error:
System.Data.OleDb.OleDbException (0x80004005): Cannot update. Database or object is read-only. at System.Data.OleDb.OleDbConnectionInternal
This error occurs on this line:
For Each row As DataRow In dt.Rows
So it appears it is uplpoading and opening the file OK, but not reading the rows....
I am not sure why that's happening either!
Any help would be much appreciated!
ACE is brutal, have troubles with it all the time and it cannot exist on a System in both 32 and 64 bit version at the same time. As a result I just dont use it at all.
To read an Excel XLSX file I use "EPPlus" which has proven to be very easy to deal with and extreamly efficient.
It ONLY works with XLSX (not XLS)
Example... (simple just pulls out first sheet as a datatable)
Public Function XlsxToDataTable(byteStream As IO.MemoryStream) As DataTable
Using pac As New OfficeOpenXml.ExcelPackage(byteStream)
Dim wb As OfficeOpenXml.ExcelWorkbook = pac.Workbook
Dim ws As OfficeOpenXml.ExcelWorksheet = wb.Worksheets(1) '1 based
Dim out As New DataTable
For iC As Integer = 1 To ws.Dimension.End.Column
out.Columns.Add(ws.Cells(1, iC).Value.ToString)
Next
For iR As Integer = 2 To ws.Dimension.End.Row
Dim nr As DataRow = out.NewRow
For iC As Integer = 1 To ws.Dimension.End.Column
nr(iC - 1) = ws.Cells(iR, iC).Value
Next
out.Rows.Add(nr)
Next
Return out
End Using
End Function