Winforms DataTable Convert to Excel - winforms

In asp.net, it is quite easy to convert a datatable to an excel file. How do I do the same for datatables in winforms?
For Example: in my asp.net code, here is my function to convert the datatable to excel:
Public Shared Sub DataTableToExcel(ByVal dt As DataTable, ByVal FileName As String
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.Write(Environment.NewLine)
For Each row As DataRow In dt.Rows
For i As Integer = 0 To dt.Columns.Count - 1
HttpContext.Current.Response.Write(row(i).ToString().Replace(";", String.Empty) + ";")
Next
HttpContext.Current.Response.Write(Environment.NewLine)
Next
HttpContext.Current.Response.ContentType = "application/ms-excel"
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + FileName + ".xls")
HttpContext.Current.Response.[End]()
End Sub
But in winforms, you cannot use the same as it is. You need to read out the datatable and create/open the excel workbook.
I wish there is a way to directly convert datatable used in winforms to excel fast.
Thanks.

All this code is really doing is creating a CSV file (with semicolons instead of commas) and telling Excel to open it. You could do something similar in C# with the following code. Note that 'FileName' must include an extension that Excel is associated with.
Public Shared Sub DataTableToExcel(ByVal dt As DataTable, ByVal FileName As String)
StreamWriter writer = new StreamWriter(FileName)
For Each row As DataRow In dt.Rows
For i As Integer = 0 To dt.Columns.Count - 1
writer.Write(row(i).ToString().Replace(";", String.Empty) + ";")
Next
writer.WriteLine()
Next
writer.Close()
System.Diagnostics.Process.Start(FileName)
End Sub

Related

Comma-separated string to data table error: input array is longer

I am trying to put data received from an API call that is comma-delimited into a datatable.
The data comes in something like this:
Name,ID,Date,Supervisior CRLF
Joe,123,1/1/2020,George CRLF
Mike,456,2/1/2020,George CRLF
Dan,789,4/1/2021,George
If there is only one row of data then my code works the data displays on screen just fine.
If there is more than one row I get an error "Input array is longer than the number of columns in this table."
I tried doing a split on comma and environment new line (also vbCRLF); none of those resolved the issue.
Any ideas on how I can resolve this?
Here is my code:
Dim vartable As DataTable = New DataTable()
vartable.Columns.Add("Name", GetType(String))
vartable.Columns.Add("ID", GetType(String))
vartable.Columns.Add("Date", GetType(String))
vartable.Columns.Add("Supervisior", GetType(String))
Dim inputstring As String
inputstring = (apiresponse) 'redacted API code as it works fine If I just display 'raw data to text field
Dim rowData As String() = inputstring.Split(New Char() {",",Environment.NewLine})
vartable.Rows.Add(rowData) 'this is where I get the input array error if 'more than one row of 'data
GridView1.DataSource = vartable
GridView1.DataBind()
It looks like you're expecting the Split() function to act on each of the delimiters separately, so you get an array of arrays, with each element in the outer array holding one line/row. This is not how it works.
You need to separate the lines first, and then in a loop for each line separate the contents by comma. The test way to do this is NOT by calling Split(). Instead, you can use a StringReader (which is different from StreamReader):
Using rdr As New StringReader(apiresponse)
Dim line As String = rdr.ReadLine()
While line IsNot Nothing
Dim rowData As String() = line.Split(","c)
vartable.Rows.Add(rowData)
line = rdr.ReadLine()
End While
End Using
But I would be surprised to learn the code to access the API doesn't also need to deal with streams at some point, even if you don't see it directly, meaning there exists a possible version of this that is even more efficient from using StreamReader connected to the api response directly.
For fun, since it's been a while since I've had to do this in VB, I made this extension module:
Public Module TextExt
<Extension()>
Public Iterator Function AsLines(data As TextReader) As IEnumerable(Of String)
Dim line As String = data.ReadLine()
While line IsNot Nothing
Yield line
line = data.ReadLine()
End While
End Function
<Extension()>
Public Iterator Function AsLines(data As String) As IEnumerable(Of String)
Using rdr As New StringReader(data)
For Each line As String In AsLines(rdr)
Yield line
Next
End Using
End Function
End Module
Which would let me write it like this:
For Each row As String() In apiresponse.AsLines().Select(Function(ln) ln.Split(","c))
vartable.Rows.Add(row)
Next
Finally, I need to add my customary warning about how it's a really bad idea to use .Split() as a CSV parser.

Exception with sqlite database "no such table"

First of all I´m developing a database with autosuggest box. I´ve created a database with DB Browser and imported data. I was reading documentation in C# how connect database and retrieve data. The issue is show up an exception error:
enter image description here
I´ve connected the database in properties with content option. I paste the code:
Public NotInheritable Class METARTAF
Inherits Page
Dim dbpath As String = Path.Combine(ApplicationData.Current.LocalFolder.Path, "airportsdb.sqlite3")
Dim conn As SQLite.Net.SQLiteConnection = New SQLite.Net.SQLiteConnection(New WinRT.SQLitePlatformWinRT(), dbpath)
Dim airportinfo As List(Of String) = Nothing
Public Sub New()
' This call is required by the designer.
InitializeComponent()
End Sub
Private Sub AutoSuggestBox_TextChanged(sender As AutoSuggestBox, args As AutoSuggestBoxTextChangedEventArgs)
Dim datairport As New List(Of String)
Dim retrieve = conn.Table(Of flugzeuginfo)().ToList
If args.Reason = AutoSuggestionBoxTextChangeReason.UserInput Then
If sender.Text.Length > 1 Then
For Each item In retrieve
datairport.Add(item.IATA)
datairport.Add(item.ICAO)
datairport.Add(item.Location)
datairport.Add(item.Airport)
datairport.Add(item.Country)
Next
airportinfo = datairport.Where(Function(x) x.StartsWith(sender.Text)).ToList()
sender.ItemsSource = airportinfo
End If
Else
sender.ItemsSource = "No results..."
End If
End Sub
Private Sub AutoSuggestBox_SuggestionChosen(sender As AutoSuggestBox, args As AutoSuggestBoxSuggestionChosenEventArgs)
Dim selectedItem = args.SelectedItem.ToString()
sender.Text = selectedItem
End Sub
Private Sub AutoSuggestBox_QuerySubmitted(sender As AutoSuggestBox, args As AutoSuggestBoxQuerySubmittedEventArgs)
If args.ChosenSuggestion Is Nothing Then
stationidtxt.Text = args.ChosenSuggestion.ToString
End If
End Sub
Anyone could help about this?
Before you query or insert into a table, you should CREATE it. This tells SQLite what columns you have and suggests datatypes (on other rdbms's you get actual data type enforcement but SQLite does not do that). If this is your problem, you will want to spend some time with the SQLite documentation on data types and the ability to hook them into your application.
On the other hand, as you seem to be trying to retrieve data, this suggess one of two things is wrong. Either you care connecting to the wrong db (in which case SQLite will usually helpfully create an empty db for you!) or else you are specifying the wrong table.

Data transfer using vb.net

I am new to vb.net and very confused at this point. I have experience with vba within excel and have taken a basic vb class at my university but I am clue less when it comes to this.
I have multi projects I would like to try, but I am stuck on how to transfer data, text string from one program to the other using a vb.net app!
I believe the process I am looking for is data binding? is that correct?
The 3 processes I am trying to accomplish.
Excel to Excel text or cell transfer/ copy and paste.
I have file A which is an excel file with rows and columns of data in cells. Then I have file B which is a template with graphs and some other formulas. I am trying to use a vb.net app to open file A copy all the data and paste into a sheet in file B. I have figured out how to open the files but as for the data transfer method I have not found anything.
Private Sub btn_Do_Click(sender As Object, e As EventArgs) Handles btn_Do.Click
Dim txtpath As String
Dim csvpath As String = "C:\Temp"
Dim FileTXT As String
Dim folderpath As String
Dim FinalFile As String
folderpath = "C:\Users\aholiday\Desktop\Data Dump"
FileTXT = cbo_FileList.Text
csvpath = "C:\Temp\" & FileTXT & ".csv"
txtpath = folderpath & "\" & FileTXT & ".txt"
FinalFile = "C:\Users\aholiday\Desktop\Book1"
File.Copy(txtpath, csvpath)
Process.Start("EXCEL.EXE", csvpath)
Process.Start("EXCEL.EXE", FinalFile)
File.Delete(csvpath)
End Sub
Access database to a chart in vb.net app.
Next I have an vb.net app that has a chart in it. How would I get data from an excel file into it. I have no code for this because I am not sure what the method I need is. I need this to be "live" meaning if someone changes something in the excel file it will update on the chart in the app. But the the first step is getting the data out of excel and into the chart. This is the only example I could find and its for Microsoft access as the data source. It didn't work.
Imports System.Data.OleDb
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs)Handles Button1.Click
Chart1.Series.Add("Numbers")
Dim Conn As OleDbConnection = New OleDbConnection
Dim Provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
Dim dataFile = "C:\Users\aholiday\Desktop\Database11.accdb"
Conn.ConnectionString = Provider & dataFile
Conn.Open()
'Adds data to chart
Dim cmd As OleDbCommand = New OleDbCommand("Select [Month],[Number] FROM [Table1]", Conn)
Dim dr As OleDbDataReader = cmd.ExecuteReader
While dr.Read
Chart1.Series("Table1").Points.AddXY(dr("Month").ToString, dr("Number").ToString)
End While
dr.Close()
cmd.Dispose()
End Sub
End Class
Excel to vb.net pictures and text string transfer.
And last. I have an vb.net app that have textbox and picture boxes in the design layout. I have an excel file with strings of text and pictures within cells. I would like code to copy the text and pictures and place them in the textbox and Picturebox.
I would like to learn how one would accomplish any of those.Please post any helpful content from sources. Any suggestions and especially examples would be awesome. Please nothing from Microsoft unless it crystal clear. I have spent about a day researching and googled everything I could think of and have found very little. None that work when I try to use it.
Thank you

VB.NET - .accdb database not saving changes

I can't figure out why my code won't save to my .accdb database.
I am fetching data from a .accdb database file and displaying it in a DataGridView, and then allowing changes to be made to it there. (This is a stock control system.) After making changes, the user is meant to be able to send the data back so it is saved in the .accdb file.
I have looked online everywhere and tried multiple different ways of doing this. This is the way I am currently using to solve the problem, but when running the code it does not save to the .accdb file. (However, it throws up no errors.)
Public Class Database
Dim datatable As DataTable
Dim adapter As OleDb.OleDbDataAdapter
Dim dbCon As New OleDb.OleDbConnection
Dim dbProvider As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;"
Dim dbRsrc As String = "Data Source =" & System.IO.Directory.GetCurrentDirectory & "/Resources/List.accdb"
Dim binding As BindingSource
Dim cmdBuilder As OleDb.OleDbCommandBuilder
Private Sub Database_Load(sender As Object, e As EventArgs) Handles MyBase.Load
dbCon.ConnectionString = dbProvider & dbRsrc
dbCon.Open()
adapter = New OleDb.OleDbDataAdapter("Select * FROM List", dbCon)
datatable = New DataTable
adapter.FillSchema(datatable, SchemaType.Source)
adapter.Fill(datatable)
binding = New BindingSource
binding.DataSource = datatable
dbCon.Close()
StockTable.DataSource = binding
End Sub
Private Sub SaveBtn_Click(sender As Object, e As EventArgs) Handles SaveBtn.Click
'insert validation here
Try
dbCon.ConnectionString = dbProvider & dbRsrc
dbCon.Open()
cmdBuilder = New OleDb.OleDbCommandBuilder(adapter)
adapter.AcceptChangesDuringUpdate = True
adapter.Update(datatable)
dbCon.Close()
Catch ex As Exception
MsgBox(ex.Message.ToString() & " Save Unsuccessful.")
End Try
End Sub
End Class
Not sure where I'm going wrong - when I hit the 'save' button, it should connect to the database, build a SQL query to update it and then update my datatable + .accdb database, right?
To test it, I've tried editing multiple columns and saving it, but when opening the file it still says the same values as it had before.
Any suggestions/pointers? I'm pretty newbie to VB.NET, learnt it about 3 months ago and only just starting to get fully into it.
Many thanks to the user "jmcilhinney" who helped me to reach this answer. I feel highly stupid at not realising that my code was working.
I used
Debug.WriteLine("Update value: " & adapter.Update(datatable))
Debug.WriteLine("Connection str: " & dbProvider & dbRsrc)
to find that my update command worked, and that in fact the output of my database file was in the /bin/ folder. I didn't realise that it used the /bin/ folder, and was looking in the root folder with the .VB files, etc.

Using CSV .txt files with arrays in VB.NET to edit data?

I'm a beginner trying to learn VB.NET and I'm not quite sure how I'll explain this, but I'll give it a shot. Basically, I've written a txt file with about 10 lines of data in CSV form.
For example:
John, 10, 14
Michael, 14, 27
Billy, 13, 45
etc, etc....
I just want to be able to read and edit particular lines - not necessarily add new lines.
Just wondering if someone could just outline how I'd go about this - not asking anyone to write the program for me. I just don't know what to do and I couldn't understand other answers I've found on SO that attempted to solve the same problem. I don't know if I'm just a bit dense or something so it'd be great if someone could perhaps give a simple, 'dumbed-down' outline of what I need to do.
Thank you.
as stated in the comments you usually read all the file into memory, manipulate it and write it all back.
dotnet has a method that puts a file content in an array (line by line)
if you need to access individual cells in the CSV you probably want to run the split method on each line and join to merge them back together.
the split/join methods are either an method of the string/array object or its in the Strings namespace
a method for writing the file back is also in the System.IO Namespace
You don't asking to write the code for you, I can understand you but I think there is no way to show how can you do that. I used split/join methods as #weberik mentioned. It is a simple console application:
Public Class Sample
Public Shared Sub Main()
CreateExampleFileIfNotExists()
'lines variable is an "Array"
Dim lines() As String = IO.File.ReadAllLines("Example.txt")
'write items to the console
ShowItems(lines, "Values before edit:")
'edit the items
EditItems(lines)
'write edited items to the console
ShowItems(lines, "Values after edit:")
'save changes?
Save(lines)
'finish
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
Public Shared Sub ShowItems(lines() As String, header As String)
Console.WriteLine(header)
Dim headers() As String = {"Name:", "Value1:", "Value2:"}
WriteItems(headers)
For Each line In lines
WriteItems(line.Split(","))
Next
End Sub
Public Shared Sub EditItems(lines() As String)
For i As Integer = 0 To lines.Length - 1
Dim line As String = lines(i)
Dim values() As String = line.Split(",")
'edit the item
values(0) = "Edited " & values(0)
values(1) += i
values(2) *= i
lines(i) = String.Join(",", values)
Next
Console.WriteLine() 'empty line
End Sub
Public Shared Sub WriteItems(itemValues() As String)
Dim line As String = ""
For Each item In itemValues
line &= item & vbTab & vbTab
Next
Console.WriteLine(line)
End Sub
Public Shared Sub CreateExampleFileIfNotExists()
If Not IO.File.Exists("Example.txt") Then
IO.File.WriteAllLines("Example.txt", {"John,10,14", "Michael,14,27", "Billy,13,45"})
End If
End Sub
Public Shared Sub Save(lines() As String)
Console.WriteLine(vbCrLf & "Do you want to save the changes? Y/N")
Dim result = Console.ReadKey()
Console.WriteLine()
Select Case result.Key
Case ConsoleKey.Y
IO.File.WriteAllLines("Example.txt", lines)
Console.WriteLine("The changes has been saved.")
End Select
End Sub
End Class

Resources