VB.Net Working with and Manipulating an Excel Spreadsheet - excel

I want to iterate through a row in my dataset. If the first cell of the row is of the pattern 1234-Name, then I want to strip the number (1234) from that and save it as a variable. Basically, the first cell is the employee and their number, like 1234-Bob McDonald. If it isn't of that form then I want to ignore it and move to the next row.
Then I want to go cell by cell in the same row, and whatever is in the cell, save it to a different variable (column 2 is location, column 3 is number of hours worked, etc.)
Here is the code I have so far:
Public Function ReadXLFile(ByVal FileName As String) As DataSet
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim Ds As System.Data.DataSet
Dim MyAdapter As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & "Extended Properties=Excel 16.0;")
MyAdapter = New System.Data.OleDb.OleDbDataAdapter("Select * from [Sheet1$]", MyConnection)
Ds = New System.Data.DataSet
MyAdapter.Fill(Ds)
Return Ds
End Function

How about this?
Public Sub GetData(ByVal FileName As String)
Dim strEmployeeNumber As String
Dim strEmployeeName As String
Dim strLocation As String
Dim intHours As Integer
Dim myDataSet As DataSet = ReadXLFile(FileName)
Dim myFirstCell As String
Dim mMatch As Match
Dim r As Regex = New Regex("^[0-9]+-[A-Za-z]+")
Dim arrFirstCell() As String
For Each myDr As DataRow In myDataSet.Tables(0).Rows
myFirstCell = myDr.Item(myDataSet.Tables(0).Columns(0))
mMatch = r.Match(myFirstCell)
If mMatch.Success Then
arrFirstCell = Split(mMatch.Value, "-")
strEmployeeNumber = arrFirstCell(0)
strEmployeeName = arrFirstCell(1)
strLocation = myDr.Item(myDataSet.Tables(0).Columns(1))
intHours = CInt(myDr.Item(myDataSet.Tables(0).Columns(2)))
Console.WriteLine("Number: {0} Name: {1} Location: {2} Hours: {3}", strEmployeeNumber, strEmployeeName, strLocation, intHours)
End If
Next
End Sub

Related

Read Multiple Excel Sheets in a Listview

I am trying to read an excel file that has multiple sheets 1,2,3,4,5,6,7,8,9,10
I need to read several columns of what is in those sheets for example from the range a1: a20 and c1: c20
The result is listing it in a listview, I am trying with several suggestions that appear in the forum, but it only allows me to read one sheet and I need to read several at the same time. Anyway I put the code that I am using.
Thanks in advance
Public Class Frm_ImportarLibro
Public Function Obtenerdatos(ByVal ruta As String, ByVal hoja As String, ByVal rango As String) As DataTable
Dim cadenaConexion As String = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=NO';" &
"Data Source=" & ruta
Using cnn As New OleDbConnection(cadenaConexion)
Dim cmd As OleDbCommand = cnn.CreateCommand()
cmd.CommandText = String.Format("SELECT * FROM [{0}${1}]", hoja, rango)
Dim da As New OleDbDataAdapter(cmd)
Dim dtTemp As New DataTable("Prueba")
da.Fill(dtTemp)
Dim dt As DataTable = dtTemp.Clone()
Dim rows As DataRow() = dtTemp.Select()
For index As Integer = 0 To rows.Count - 1
Dim row As DataRow = rows(index)
If (row.Item(0) Is DBNull.Value) Then
Exit For
End If
dt.ImportRow(row)
Next
Return dt
End Using
End Function
I believe this would be a matter of looping through the sheets and loading a DataTable for each sheet which is then added to a DataSet. My code assumes that the same range is used for each sheet. I made the range contiguous because it would require a separate command for each non-contiguous range. I believe it would be easier to ignore the extraneous data in the resulting DataTable.
Private cadenaConexion As String = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=NO';Data Source="
Private rango As String = "A1:C20"
Private Function GetXLSheetNames(path As String) As List(Of String)
Dim SheetNames As New List(Of String)
Dim dt As DataTable
Using cn As New OleDbConnection(cadenaConexion & path)
cn.Open()
dt = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
End Using
For Each row As DataRow In dt.Rows
Dim s = row("Table_Name").ToString
SheetNames.Add(s)
Next
Return SheetNames
End Function
Public Function Obtenerdatos(ByVal ruta As String, ByVal hoja As String, ByVal rango As String) As DataSet
Dim ds As New DataSet
Dim lst = GetXLSheetNames(ruta)
Using cnn As New OleDbConnection(cadenaConexion & ruta),
cmd As New OleDbCommand()
cmd.Connection = cnn
cnn.Open()
For Each s In lst
Dim dt As New DataTable(s)
cmd.CommandText = $"SELECT * FROM [{s}{rango}]"
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
ds.Tables.Add(dt)
Next
End Using
Return ds
End Function

Reading from Excel getting prompts instead of string on occasion

The issue i am having right now is that the first row of the data i get from the excel documents sometimes come back as prompts instead of their proper data types(only some of the cells). i have tried remaking the spreadsheets and redoing all the formatting on the excel side so i'm left to assume its something to do with the oledb class? Any information or a push in the right direction would be greatly appreciated.
Imports Microsoft.Office.Interop
Public Class Form1
Dim ExTable1 As New DataTable
Dim ExTable2 As New DataTable
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.ShowDialog()
ExTable1 = ConnectToFile(OpenFileDialog1.FileName)
Table1.DataSource = ExTable1
End Sub
Function ConnectToFile(path)
Dim dt As DataTable = New DataTable
Dim selStr As String = "SELECT * FROM [{0}]"
Dim dtSchema
Dim drSchema
Dim con As OleDb.OleDbConnection = New OleDb.OleDbConnection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & path & ";Extended Properties=Excel 12.0 Xml;"
con.Open()
dtSchema = con.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
drSchema = dtSchema.Rows(0)
Dim Sheet1 = drSchema("TABLE_NAME")
Dim cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand(String.Format(selStr, Sheet1))
cmd.Connection = con
Dim da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter
da.SelectCommand = cmd
da.Fill(dt)
Table1.DataSource = dt
con.Close()
con.Dispose()
Return dt
End Function
End Class

Why is my code is getting second row as header instead of first row

My code is getting second row records treating them as header while i want it to get first row records as hearder (code is skiping first row)
Note: am looping through columns
I have written my code to loop through an excel sheet to get headers of the sheet.It works fine but instead of getting the first row records,it skips and get the second row records
Note: am looping through columns
Dim path As String = txtPath.Text
Dim excel_connection As OleDbConnection
Dim dt As DataTable
Dim cmd As OleDbDataAdapter
'Dim sql As String
'Dim result As Boolean
Dim emp_type_id As String = ""
Dim branch_id As String = ""
Dim bank_id As String = ""
excel_connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0 Xml;")
cmd = New OleDbDataAdapter("SELECT * FROM [sheet$]", excel_connection)
dt = New DataTable
cmd.Fill(dt)
For Each column As DataColumn In dt.Columns
Dim columnName As String = dt.Rows(0)(column.ColumnName).ToString()
If columnName = "" Then
Else
MsgBox(columnName)
End If
Next
I want it to loop through the first row
Note: am looping through columns
Try adding HDR=No into OleDbConnection Extended Properties. Like below:
excel_connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 12.0 Xml;HDR=No;IMEX=1;';")

How to export comma delimited data to excel sheet, but each row is a new excel sheet

i have a comma delimited text file as follows
RLGAcct#,PAYMENT_AMOUNT,TRANSACTION_DATE,CONSUMER_NAME,CONSUMER_ADD_STREET,CONSUMER_ADD_CSZ,CONSUMER_PHONE,CONSUMER_EMAIL,LAST_FOUR
ZTEST01,50.00,11/15/2018,ROBERT R SMITH,12345 SOME STREET,60046,,adam#adamparks.com,2224
ZTEST02,100.00,11/15/2018,ROBERT JONES,5215 OLD ORCHARD RD,60077,,adam#adamparks.com,2223
ZTEST03,75.00,11/15/2018,JAMES B MCDONALD,4522 N CENTRAL PARK AVE APT 2,60625,,adam#adamparks.com,2222
ZTEST04,80.00,11/15/2018,JOHN Q DOE,919 W 33RD PL 2ND FL,60608,,adam#adamparks.com,2221
ZTEST05,60.00,11/15/2018,SAMANTHAN STEVENSON,123 MAIN ST,60610,,adam#adamparks.com,2220
I need to export this to excel so that each value between a comma is inserted into a column in excel
So
ZTEST01 is in A1,
50.00 is in B1
11/15/2018 in C1 ...
The thing is i need each row to be inserted into a newly created excel worksheet.
The code i have is as follows:
Dim xlApp As New Excel.Application
Dim xlWorkbook As Excel.Workbook
Dim xlWorksheet As Excel.Worksheet
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
'xlWorkbook = xlApp.workboos.Add() using this later once i have the parsing figured out
Dim columns As New List(Of String)
Dim ccPayment = "C:\Users\XBorja.RESURGENCE\Downloads\Payments_Credit.txt"
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(ccPayment)
MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
MyReader.Delimiters = New String() {","}
Dim currentRow As String()
'Loop through all of the fields in the file.
'If any lines are corrupt, report an error and continue parsing.
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
' Include code here to handle the row.
For Each r In currentRow
columns.Add(r)
C
Next r
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & " is invalid. Skipping")
End Try
End While
'Dim index0 = columns(0)
'Dim index1 = columns(1)
'Dim index2 = columns(3)
'Dim index3 = columns(3)
'Dim index4 = columns(4)
'Dim index5 = columns(5)
'Dim index6 = columns(6)
'Dim index7 = columns(7)
'Dim index8 = columns(8)
'Console.WriteLine(index0 & index1 & index2 & index3 & index4 & index5 & index6 & index7 & index8)
End Using
For Each r In columns
Console.WriteLine(r)
Next
end sub
As you can see I was trying to see if i could index these so that i could possibly equate each one to a cell in excel.
The other problem is that this text file changes daily. The columns are always set (9 columns) but the rows change dynamically daily based on how many transactions we get.
I would recommend using the EPPlus package which is available via NuGet. It removes the COM challenges of working with Excel and works by reading and writing the XLSX spreadsheet files.
The following sample does what you where asking:
Private Sub btnStackOverflowQuestion_Click(sender As Object, e As EventArgs) Handles btnStackOverflowQuestion.Click
Dim ccPayment As String = "C:\temp\so.csv"
Using pkg As New ExcelPackage()
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(ccPayment)
MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
MyReader.Delimiters = New String() {","}
Dim sheetCount As Integer
While Not MyReader.EndOfData
sheetCount += 1
Dim newSheet As ExcelWorksheet = pkg.Workbook.Worksheets.Add($"Sheet{sheetCount}")
Try
Dim currentRow As String() = MyReader.ReadFields()
Dim columnCount As Integer = 0
For Each r In currentRow
columnCount += 1
newSheet.Cells(1, columnCount).Value = r
Next r
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & " is invalid. Skipping")
End Try
End While
End Using
Dim fi As New FileInfo("C:\temp\so.xlsx")
pkg.SaveAs(fi)
End Using
End Sub

Excel Imports way more rows than expected

with my code below I'm importing an excel file that contains 5 worksheets, but I'm only wanting data from 3 of them. I'm getting about 7 times as many rows as expected. How do I ensure I only get populated rows from each sheet? no dupes.
Dim strConnection As String = ConfigurationManager.ConnectionStrings("conn").ToString
Dim excelConnString As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Server.MapPath(excelFile) & "; Extended Properties=""Excel 12.0 Xml; HDR=Yes""")
Dim conn As OleDbConnection = New OleDbConnection(excelConnString)
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.Connection = conn
Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim dt As DataTable = New DataTable()
conn.Open()
Dim dtSheet As DataTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
For Each sheet As System.Data.DataRow In dtSheet.Rows
Dim sheetName As String = sheet("table_name").ToString()
If sheetName = "UT$" Or sheetName = "XRAY$" Or sheetName = "FLANGE$" Then
cmd.CommandText = "select * from [" & sheetName & "] WHERE [Drawing] Is Not NULL"
da.SelectCommand = cmd
da.Fill(dt)
Dim myImportFinding As New ImportFinding
For i As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(i)("Platform") Is Nothing OrElse IsDBNull(dt.Rows(i)("Platform")) Then
myImportFinding.PLATFORM = ""
Else
myImportFinding.PLATFORM = dt.Rows(i)("Platform")
End If
Yes, there was a whole lot of code missing, but the important parts are there. I decided to refactor and have it working now. Each time I looped through it inserted all the rows from the three worksheets. I decided to move the actual import out into a new method and started off with a fresh data table, command and data adapter for each workbook. Seems to work fine now.

Resources