CSV to XLSX VB.NET - excel

enter image description hereenter image description hereI am just learning VB.NET and unfortunately I have been tasked with something I do not have a clue how to do.
I need to create a quick windows based application to export csv files into an XLSX file.
Yes, I know that other posts may have a similar topic however this one I believe is unique.
The CSV file will have 5 headers, `Line, Component, Picked, Placed and Missed. We have part numbers in column 2 that would be placed under Component. I am understanding from the powers that be, this file sums the total part numbers i.e. 0-5490045 and the line JUKI 3 and totals Picked, Placed and Missed parts. I have provided a sample rows below. First row is the csv formatted, the second is the output. I am not sure which loop would be best a FOR loop, WHILE loop etc. I am assuming I will need a loop of some sort to get through all the data in the csv file.
The only code I have opens the dialog box and allows for file selection and attempts to read into a datatable. I am attempting to get this working and then restructure some code.
Imports Spire.Xls
Imports System.Windows.Forms
Imports System.Data
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dialog As OpenFileDialog = New OpenFileDialog
dialog.Filter="CSV document(*.csv)|*.csv"
Dim result As DialogResult = dialog.ShowDialog
If(result=DialogResult.OK) Then
Dim csvFile As String = dialog.FileName
Dim workbook As Workbook = New Workbook
workbook.LoadFromFile(csvFile,",")
Dim worksheet As Worksheet = workbook.Worksheets(0)
Dim dt As DataTable=worksheet.ExportDataTable
Me.dataGridView1.DataSource=dt
End If
End Sub
End Class
JUKI 3 0-5490045 96 96 3
Line Component Picked Placed Missed
JUKI 3 0-5490045 99 96 3

I hate to make a suggestion and not show how it would work. Below is an example using a custom object called Machine to hold the data. This class is a bare minimum for an object and is only used as an example to get you started. It has some fields that will come in handy when looping thru the list to do your computations. It is also here you could add some custom functions/subs to help in some task that involves “Machine” objects. Also here you could add some compare functions which will enable you to sort among other things. After you put all this together you should end up with a list of valid Machine objects.
It is this list you could use to help you move on to the computing/removing duplicates part of your task. In the process of computing the data you could create a final list of Machine objects that you could use to export to excel with headers or display it to a DataGridView. Hope this helps.
Machine Class
Public Class Machine
Private name As String
Private partNumber As String
Private inventoryIn As Integer
Private inventoryOut As Integer
Private inventoryMissing As Integer
Public Sub New(inName As String, inPartNum As String, inInvIn As Integer, inInvOut As Integer, InInvMis As Integer)
name = inName
partNumber = inPartNum
inventoryIn = inInvIn
inventoryOut = inInvOut
inventoryMissing = InInvMis
End Sub
Property GetName As String
Get
Return name
End Get
Set(value As String)
name = value
End Set
End Property
Public Overrides Function ToString() As String
Return "Name: " + name + " #: " + partNumber + vbTab + " In:" + inventoryIn.ToString() + " Out:" + inventoryOut.ToString() + " Miss:" + inventoryMissing.ToString()
End Function
End Class
Now to your issue of reading the file
I did not use anything involving excel. Since you have a simple csv file we will use it. Also we will use the Machine class above. Using your open file dialog we get the name of the file to read. A variable partsList is created to hold the Machine objects created when reading the file. Then a for each loop goes through the list and displays the results in a text box on the form.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dialog As OpenFileDialog = New OpenFileDialog
dialog.Filter = "CSV document(*.csv)|*.csv"
Dim result As DialogResult = dialog.ShowDialog
If (result = DialogResult.OK) Then
Dim csvFile As String = dialog.FileName
Dim partsList As List(Of Machine) = ReadText(csvFile)
For Each curMac As Machine In partsList
TextBox1.AppendText(curMac.ToString() + Environment.NewLine)
Next
End If
End Sub
Function to read the csv file
Private Function ReadText(filePath As String) As List(Of Machine)
Dim fileReader As System.IO.StreamReader
Dim data As List(Of Machine) = New List(Of Machine)
fileReader = My.Computer.FileSystem.OpenTextFileReader(filePath)
Dim curline As String = ""
While (Not curline Is Nothing)
curline = fileReader.ReadLine()
'' need to check for valid data
'' if anything is invalid simply ignore it... i.e. your bad rows
'' keep in mind this will also ignore good rows that have a single piece of data bad
If (StringOK(curline)) Then
Dim newMac = GetMac(curline)
data.Add(newMac)
End If
End While
Return data
End Function
A couple of helper functions to validate the data
Private Function StringOK(inString As String) As Boolean
If (String.IsNullOrEmpty(inString)) Then
Return False
End If
Dim splitArray() As String = inString.Split(",")
Try
If ((String.IsNullOrEmpty(splitArray(0))) Or (String.IsNullOrEmpty(splitArray(1)))) Then
Return False
End If
Dim value As Integer
If ((Not Integer.TryParse(splitArray(2), value)) Or
(Not Integer.TryParse(splitArray(3), value)) Or
(Not Integer.TryParse(splitArray(4), value))) Then
Return False
End If
Return True
Catch ex As Exception
Return False
End Try
End Function
Function GetMac(inString As String) As Machine
Dim splitArray() As String = inString.Split(",")
Dim value As Integer
Dim name As String = splitArray(0)
Dim number As String = splitArray(1)
Integer.TryParse(splitArray(2), value)
Dim invIn As Integer = value
Integer.TryParse(splitArray(3), value)
Dim invOut As Integer = value
Integer.TryParse(splitArray(4), value)
Dim invMis As Integer = value
Return New Machine(name, number, invIn, invOut, invMis)
End Function

If you are trying to accomplish how to import the data into a datatable below is a fast way of handling that. This will bring your whole csv into a datatable which you could then do logic on and create your xlsx file.
Friend Shared Function GetExcelFile(ByVal strFileName As String, ByVal strPath As String) As DataTable
Try
Dim dt As New DataTable
Dim ConStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strPath & ";Extended Properties=""Text;HDR=Yes;FMT=Delimited\"""
Dim conn As New OleDb.OleDbConnection(ConStr)
Dim da As New OleDb.OleDbDataAdapter("Select * from " & strFileName, conn)
da.Fill(dt)
Return dt
Catch ex As Exception
Return Nothing
End Try
End Function

Related

Read from Excel - write to CSV in different column order

I need to understand if there is a possibility, within VB.NET, to be able to read the columns of an Excel file and write them out to a CSV file in a different order.
In practice, the Excel file we are sent has 6 columns: "amount", "branch", stock "," proposal "," quantity "," type ". The company management system accepts the text file with the columns in a different order: "branch", "stock", "amount", "quantity", "type", "proposal". This creates a problem for me because when I go to convert it my ERP fails to recognize that the column is in a different position.
I arrive at the concrete question, I would like to have the possibility to read the columns and make it possible through a script to be able to position them according to the position I decide.
I tried this code for import and convert to txt, but I need another script:
Imports System.IO
Imports ExcelDataReader
Imports System.Text
Public Class Form1
Dim tables As DataTableCollection
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "(*.xls)|*.xls|(*.xls)|*.xlsx"}
If ofd.ShowDialog() = DialogResult.OK Then
txtFileName.Text = ofd.FileName
Using Stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read)
Using reader As IExcelDataReader = ExcelReaderFactory.CreateReader(Stream)
Dim result As DataSet = reader.AsDataSet(New ExcelDataSetConfiguration() With {
.ConfigureDataTable = Function(__) New ExcelDataTableConfiguration() With {
.UseHeaderRow = True}})
tables = result.Tables
cboSheet.Items.Clear()
For Each table As DataTable In tables
cboSheet.Items.Add(table.TableName)
Next
End Using
End Using
End If
End Using
End Sub
Private Sub cboSheet_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSheet.SelectedIndexChanged
Dim dt As DataTable = tables(cboSheet.SelectedItem.ToString())
dgProposte.DataSource = dt
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim writer As TextWriter = New StreamWriter("C:\Users\antonio\Desktop\Prova.txt")
For i As Integer = 0 To dgProposte.Rows.Count - 2 Step +1
For j As Integer = 0 To dgProposte.Columns.Count - 1 Step +1
writer.Write(vbTab & dgProposte.Rows(i).Cells(j).Value.ToString() & vbTab & "")
Next
writer.WriteLine("")
Next
writer.Close()
MessageBox.Show("Dati Esportati")
End Sub
The tables that you get from importing the Excel sheet(s) have their column names set, and you can index the column by its name.
So, and with a little adjustment to factor out some methods:
Imports System.IO
Imports ExcelDataReader
Public Class Form1
Dim tables As DataTableCollection
Private Sub WriteToCsv(tableName As String, filename As String)
Dim columnWriteOrder = {"branch", "stock", "amount", "quantity", "type", "proposal"}
Using writer As TextWriter = New StreamWriter(filename)
Dim tbl = tables(tableName)
For i As Integer = 0 To dgProposte.Rows.Count - 2
Dim vals As New List(Of String)
For j As Integer = 0 To columnWriteOrder.Length - 1
Dim val = tbl.Rows(i).Item(columnWriteOrder(j)).ToString()
vals.Add(val)
Next
writer.WriteLine(String.Join(vbTab, vals))
Next
End Using
End Sub
Private Sub PopulateSheetNames()
cboSheet.Items.Clear()
For Each table As DataTable In tables
cboSheet.Items.Add(table.TableName)
Next
End Sub
Private Sub cboSheet_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSheet.SelectedIndexChanged
If cboSheet.SelectedIndex >= 0 Then
Dim tableName = cboSheet.SelectedItem.ToString()
Dim dt As DataTable = tables(tableName)
dgProposte.DataSource = dt
End If
End Sub
Private Sub bnLoad_Click(sender As Object, e As EventArgs) Handles bnLoad.Click
Using ofd As OpenFileDialog = New OpenFileDialog() With {.Filter = "(*.xlsx)|*.xlsx|(*.xls)|*.xls", .InitialDirectory = "C:\temp"}
If ofd.ShowDialog() <> DialogResult.OK Then
Exit Sub
End If
txtFileName.Text = ofd.FileName
Using Stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read)
Using reader As IExcelDataReader = ExcelReaderFactory.CreateReader(Stream)
Dim edsc = New ExcelDataSetConfiguration() With {
.ConfigureDataTable = Function(__) New ExcelDataTableConfiguration() With {
.UseHeaderRow = True}}
Dim result As DataSet = reader.AsDataSet(edsc)
tables = result.Tables
End Using
End Using
PopulateSheetNames()
End Using
End Sub
Private Sub bnSaveAsCsv_Click(sender As Object, e As EventArgs) Handles bnSaveAsCsv.Click
If cboSheet.SelectedIndex < 0 Then
MessageBox.Show("Please select a sheet name.", "No sheet name selected", MessageBoxButtons.OK, MessageBoxIcon.Information)
Exit Sub
End If
Dim sheetName = cboSheet.SelectedItem.ToString()
If Not String.IsNullOrEmpty(sheetName) Then
WriteToCsv(sheetName, "C:\temp\Prova.csv")
MessageBox.Show("Dati Esportati.", "Dati Esportati", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
End Class
I changed the names of the buttons because "Button1" and "Button2" are not descriptive.
(I set the .InitialDirectory of the OpenFileDialog because it was convenient for me.)
Why you don't map a DTO of your data table?
Public Class MioDto
Property campoUno As String
Property campoDue As String
'...ecc
End Class
and then you can fill a dto in a cicle or so...
Dim a As New MioDto() With {.campoUno="...", campoDue="..."}
or if you want you can use
https://github.com/AutoMapper/AutoMapper
When you have a Dto class filled you can use it for generate your txt with youor preferred order.

How to generate a reduced Excel when filtering by id in vb.net

In vb.net I have lists that contains variables of an Excel file.
Example:
Lists first Excel:
ID
WEIGHT
NAME
CAU65469
1234
jkaufman
DEX74893
1234
jdee
Second one:
ID
COLOR
VOLUME
CAU65469
YELLOW
900
DEX743413
BLUE
1500
I want to generate a third file that looks like this:
ID
WEIGHT
NAME
COLOR
VOLUME
CAU65469
1234
jkaufman
YELLOW
900
My solution is to shorten the second Excel by filtering by id
so it would only show me the data if the ID is found in both files and then comparing by coordinates.
On vb.net, how can I save the position of an Excel (index) by an ID in order to shorten the Excel?
My code in vb.net, I have the values in lists like this:
Public ID As New List(Of String)
Public ID2 As New List(Of String)
Public COLOR As New List(Of String)
Public NAME As New List(Of String)
Public WEIGHT New List(Of String)
Public VOLUME As New List(Of String)
To just fill information in a new Excel I use this code.
I use a function like this to extract the information from the Excel files.
Function extraer_valores_planilla(ByRef ruta As String) As Boolean
ExcelPackage.LicenseContext = LicenseContext.NonCommercial
Try
Dim stream = System.IO.File.OpenRead(ruta)
Dim package = New OfficeOpenXml.ExcelPackage(stream)
'// Libro
Dim Workbook = package.Workbook
'// Hojas
Dim hojas = Workbook.Worksheets
' While (Workbook.Worksheets.Count >= aux)
Dim hojaUsuarios = Workbook.Worksheets(Workbook.Worksheets.Item(0).ToString)
Dim indice As Integer = 2
While (indice < 5000)
If (IsNothing(hojaUsuarios.Cells("A" & indice).Value) = False) Then
ID.Add(hojaUsuarios.Cells("A" & indice).Value)
End If
indice += 1
End While
indice += 1
Catch EX As Exception
MsgBox(EX.ToString)
Return False
End Try
Return True
and then I fill the third Excel like this:
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
ExcelPackage.LicenseContext = LicenseContext.NonCommercial
Dim path As String = seleccionardirectorio("Excel|.xlsx")
If (String.IsNullOrWhiteSpace(path) = False) Then
Dim excel = New ExcelPackage(New FileInfo(path))
excel.Workbook.Worksheets.Add("Hoja1")
Dim aux As Integer = 1
Dim Workbook = excel.Workbook
Dim hojas = Workbook.Worksheets
Dim dict As New Dictionary(Of String, String)
Dim hoja1 = Workbook.Worksheets("Hoja1")
'DAMOS NOMBRE A LAS COLUMNAS
INICIALIZAR_PLANILLA(hoja1)
While (aux <= ID.Count)
hoja1.Cells("C" & aux + 1).Value = COLOR.Item(aux - 1)
aux += 1
End While
One of the things we (should) do when we write programs in an object oriented language, is try and move away from thinking like "I have to store 5 bits of info about an object - id, color, name, weight, volume. I'll make 5 arrays, one for each thing, and relate them all positionally so the "ID1 BLUE JOHN 50KG 200m3" data is at array index 9 in each of the five arrays"
Instead we should be thinking "I'll make a class with 5 properties, and I'll create instances of it and fill them" - this way the items of data don't remain related purely because they "just happen to all be at position 9 in some arrays" but instead are all together and representing an object. Nearly line of code you write in VB uses something that obeys this notion - you should too
Public Class Whatever
Public Property ID As String
Public Property Color As String
Public Property Name As String
Public Property Weight As String
Public Property Volume As String
End Class
Next we use some collection that supports looking things up, like a Dictionary:
Function extraer_valores_planilla(ByRef ruta As String, isFirstExcel as Moolean) As Boolean
... 'put code that opens file here - i removed for clarity
Dim das New Dictionary(Of String, Whatever)
Dim indice As Integer = 2
While (indice < 5000)
If (IsNothing(hojaUsuarios.Cells("A" & indice).Value)) Then
indice += 1
Continue While
End If
Dim id = hojaUsuarios.Cells("A" & indice).Value
If Not d.ContainsKey(id) Then d(id) = New Whatever
d(id).ID = id
If isFirstExcel Then
d(id).Weight = hojaUsuarios.Cells("B" & indice).Value
d(id).Name = hojaUsuarios.Cells("C" & indice).Value
Else
d(id).Color = hojaUsuarios.Cells("B" & indice).Value
d(id).Volume = hojaUsuarios.Cells("C" & indice).Value
indice += 1
End While
The posted code does not show how ID2 Color, Volume, Weight, Name lists come to be populated with anything. I've assumed that WEIGHT/COLOR is in column B, and NAME/VOLUME is in column C
At the end of this operation you have a dictionary that has ID strings mapping to Whatever objects... And those objects Will have two or four properties filled in depending on if their ID was present in one file or the other

validate strings in an excel in vb.net

I have a question, in vb.net, how can i validate that 2 values are the same in an excel in vb.net
for example i have defined 3 list
Public NSPS As New List(Of String)
Public CONTAINER As New List(Of String)
Public CONTAINER2 As New List(Of String)
I have 2 excel files where CONTAINER and CONTAINER2 are id's
So i need to create a third excel file that filters only the id's that repeat themselves in the 2 excel
meaning if i have an id: CARU9891569 in the 2 files, only then it transfers to the generated excel
and the 2 excel's have some extra information, for example: excel 1 has the variables: DELIVERY, CONTAINER, VOLUME.
the second excel has the variables: NSPS, NPOS, PACKAGES, CONTAINER2
SO the generated excel needs to have all of the variables: DELIVERY, CONTAINER, VOLUME, NSPS, NPOS, PACKAGES. using CONTAINER as the filter
to just fill information in a new excel i use this code
i use a function like this to extract the information from the excel files
Function extraer_valores_planilla(ByRef ruta As String) As Boolean
ExcelPackage.LicenseContext = LicenseContext.NonCommercial
Try
Dim stream = System.IO.File.OpenRead(ruta)
Dim package = New OfficeOpenXml.ExcelPackage(stream)
'// Libro
Dim Workbook = package.Workbook
'// Hojas
Dim hojas = Workbook.Worksheets
' While (Workbook.Worksheets.Count >= aux)
Dim hojaUsuarios = Workbook.Worksheets(Workbook.Worksheets.Item(0).ToString)
Dim indice As Integer = 2
While (indice < 5000)
'Numero entrega'
If (IsNothing(hojaUsuarios.Cells("A" & indice).Value) = False) Then
NSPS.Add(hojaUsuarios.Cells("A" & indice).Value)
End If
indice += 1
End While
indice += 1
Catch EX As Exception
MsgBox(EX.ToString)
Return False
End Try
Return True
and then i fill the third excel like this
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
ExcelPackage.LicenseContext = LicenseContext.NonCommercial
Dim path As String = seleccionardirectorio("Excel|.xlsx")
If (String.IsNullOrWhiteSpace(path) = False) Then
Dim excel = New ExcelPackage(New FileInfo(path))
excel.Workbook.Worksheets.Add("Hoja1")
Dim aux As Integer = 1
Dim Workbook = excel.Workbook
Dim hojas = Workbook.Worksheets
Dim dict As New Dictionary(Of String, String)
Dim hoja1 = Workbook.Worksheets("Hoja1")
'DAMOS NOMBRE A LAS COLUMNAS
INICIALIZAR_PLANILLA(hoja1)
While (aux <= CONTAINER.Count)
hoja1.Cells("C" & aux + 1).Value = ENTREGA.Item(aux - 1)
aux += 1
End While
this is the same for all variables i just resume for you guys and this works just fine.
should i use 2 cicles to filter the excel, maybe a for each, sorry i am new to programing and i am stuck in this part
any ideas would be helpfull
Thanks in advance!
yes, use 2 for each loops.
for each item in list
for each otheritem in list2
if item = otheritem then
' These items match
end if
next
next
Replace the dummy variables with yours

Read values from graph on website using excel macro

I have a problem for which I can not find the solution on my own. I tried to read out the values from the following website: https://datawrapper.dwcdn.net/6E03v/580/. I think I have managed to find the corresponding part in the code of the website which is
THIS ONE. As per my understanding the values can be found with tag "span" or class "fg", but none of them seems to work. This is the code I am using for it in the version I use tag "span":
Dim WertFG As Selenium.WebElement
Dim WerteFG As Selenium.WebElements
Dim strTargetTab As String
Dim lgNaechsteFreieZeileZwiSpTblFaelleNachAlter As Long
Dim lgSpalte As Long
Dim lgNaechsteFreieZeileReiterNTVCoronadaten As Long
'Wertzuweisung Variablen
Set ChromeBrowser = New Selenium.ChromeDriver
'Chrome starten und auf die relevante Seite für die gesuchte TabelleCoronaVirusPandemieParameter gehen
ChromeBrowser.Start baseUrl:="https://datawrapper.dwcdn.net/"
ChromeBrowser.Get "/6E03v/577/"
'Werte auslesen
strTargetTab = ThisWorkbook.Worksheets("ZwiSp Tbl Fälle nach Alter").Name
ThisWorkbook.Worksheets(strTargetTab).Activate
ThisWorkbook.Worksheets(strTargetTab).Range("A1:A50").ClearContents
Application.Wait (Now + TimeValue("00:00:03"))
'Tabellenwerte auslesen
Set WerteFG = ChromeBrowser.FindElementsByTag("span")
lgNaechsteFreieZeileZwiSpTblFaelleNachAlter = ThisWorkbook.Worksheets(strTargetTab).Cells(Rows.Count, 1).End(xlUp).Row + 1
lgSpalte = 1
For Each WertFG In WerteFG
ThisWorkbook.Worksheets(strTargetTab).Cells(lgNaechsteFreieZeileZwiSpTblFaelleNachAlter, lgSpalte).Value = WertFG.Text
lgNaechsteFreieZeileZwiSpTblFaelleNachAlter = lgNaechsteFreieZeileZwiSpTblFaelleNachAlter + 1
Next WertFG
ChromeBrowser.Close
Does someone have an idea, why this does not work? Has it something to do with the fact, that the values on the graph are only shown when you hover above the corresponding part of the graph?
Thanks for your help!
Oliver
Addition:
What I want to do:
Read out all the values for tag “span” to a worksheet in excel. Each value should be written in consecutive cell in the worksheet, i.e. A2, A3, ….
What the macro does:
Reads out the values for tag “span” for the first 4 rows then delivers 11 rows with no values and then again shows the remaining values of the website for the element “span”. I assume that in the 11 empty rows the numbers to the graph (this is what I need) would be shown, if the macro would work correctly. I have also attached a screenshot of the read out results to this post:
Read Out Results Excel Worksheet
There is a wait needed before download is pulling from that page.
Also, it would be better to target specific spans e.g.
Dim values As webelements, labels As webelements, r As Long
Set values = chromebrowser.FindElementsByCss(".dontshow span")
Set labels = chromebrowser.FindElementsByCss(".series span")
r = 0
For i = 1 To labels.Count Step 2
Debug.Print labels.Item(i).Text
Debug.Print values(i).Text
Debug.Print values(i + 1).Text
r = r + 1
Next
However, data comes from a csv that you can download. The csv has a timestamp parameter which may help with caching. I doubt server does much with it. #TimWilliams wrote a very nice little function to generate unix timestamps which you can use to construct the csv download url.
So, if there is other stuff you want on that page you can just chromebrowser.get to the constructed url and it will download:
Public Sub GetCovidNumbers()
Dim downloadUrl As String
downloadUrl = "https://static.dwcdn.net/data/6E03v.csv?v=" & CStr(toUnix(Now))
Debug.Print downloadUrl
'd.get downloadUrl
End Sub
Public Function toUnix(dt) As Long
'https://stackoverflow.com/a/12326121 #TimWilliams
toUnix = DateDiff("s", "1/1/1970", dt)
End Function
Or, if you only need that, you can set a download path and use urlmon to download from constructed url e.g.
Public Const folderName As String = "C:\Users\<user>\Desktop\covid.csv" '<=Change as required
Public Sub downloadCSV()
Dim ret As Long
ret = URLDownloadToFile(0, "https://static.dwcdn.net/data/6E03v.csv?v=" & CStr(toUnix(Now)), folderName, BINDF_GETNEWESTVERSION, 0)
End Sub
In all cases, you need to tidy up the headers in output and the age category 5-9. I would simply ignore those as they are constants so you can have them stored elsewhere.

Retrive the rows/data from datagridview after the application has been closed

I have a dialog form here where a user can upload a file from Excel and import and display to the datagrid view. However, my problem is when the user closes the application or form, the datagridview was empty and reset.
My question is how can I retrieve its data and display it, every time the user will open the form. Is it possible if the data was not saved in the database and will only based on the uploaded or imported Excel file? And if the user has uploaded a new Excel, I want to replace the existing rows or data in the datagridview.
I really hope you would help.
Below you can find my code:
Imports System.Data
Public Class frmSupplier
Private Sub btn_upload_supplier_Click(sender As Object, e As EventArgs) Handles btn_upload_supplier.Click
Try
If btn_upload_supplier.Text = "New" Then
Dim Openfile As New OpenFileDialog
Openfile.ShowDialog()
txtpath_supplier.Text = Openfile.FileName
Label1.Text = txtpath_supplier.Text
If txtpath_supplier.Text = Nothing Then
Else
btn_upload_supplier.Text = "Upload"
End If
ElseIf btn_upload_supplier.Text = "Upload" Then
Dim dtItemlist As New DataTable
Dim obj As New Basegeneral
Try
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + txtpath_supplier.Text.ToString() + "; Extended Properties=Excel 8.0;")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
MyCommand.TableMappings.Add("Table", "TestTable")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
dg_details.DataSource = DtSet.Tables(0)
MyConnection.Close()
Catch ex As Exception
MessageBox.Show(Me, ex.ToString, "Error:")
End Try
End If
Catch ex As Exception
MessageBox.Show(Me, ex.ToString, "Error:")
End Try
End Sub
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
Try
Dim row As System.Data.DataRow = GridView1.GetDataRow(GridView1.FocusedRowHandle)
If row.Item(0).ToString = "" Then
MessageBox.Show("Please select supplier to remove", "KCC Retail System")
Return
End If
If DevExpress.XtraEditors.XtraMessageBox.Show("Are you sure you want to remove supplier '" & row.Item(0) & "'?", "WARNING", MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
MessageBox.Show("Supplier " & row.Item(0) & " has been removed!", "KCC Retail System")
GridView1.DeleteRow(GridView1.FocusedRowHandle)
Else
Return
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error :")
End Try
End Sub
Private Sub btn_clear_Click(sender As Object, e As EventArgs) Handles btn_clear.Click
btn_upload_supplier.Text = "New"
txtpath_supplier.Text = ""
End Sub
The form will be open when the user click the button and it will display as a dialog (ShowDialog).
To save and then re-hydrate the contents of a DataGridView you can use a binary formatter.
Imports System.IO
Import System.Runtime.Serialization.Formatters.Binary
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim FileName As String = "MyData.dat" 'Will save in bin directory
Dim dt As DataTable = CType(DataGridView1.DataSource, DataTable)
' 1. Create an instance of a Binary Formatter
Dim bf As New BinaryFormatter
' 2. Create a file stream passing in (the name of the file to create, mode: Create, access: Write, share: none)
Using fs As Stream = New FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None)
' 3. use the Serialize method of the Binary Formatter passing in the file stream(file name, create, write, no share) And the object
bf.Serialize(fs, dt)
End Using
End Sub
Private Sub btnFillFromFill_Click(sender As Object, e As EventArgs) Handles btnFillFromFill.Click
Dim FileName As String = "MyData.dat"
Dim dt As DataTable
' 1. Create an instance of Binary Formatter
Dim bf As New BinaryFormatter()
' 2. Get an instance of a FileStream for the OpenRead method of File passing in (the fileName)
Using fs As Stream = File.OpenRead(FileName)
' 3. cast back to original object, the Deserialize method of the Binary Formatter passing in the File Stream
dt = CType(bf.Deserialize(fs), DataTable)
End Using
DataGridView1.DataSource = dt
End Sub

Resources