Saving to a spreadsheet
Hi all
I am writing a simple program that reads the info from a spreadsheet based on the user's selection and places it in a DataGridView. Now that part I have managed without any problems using OLEDBConnection.
What I want to do is to allow the user to change certain fields and then be able to click a button to ammend them to the table. I don't want to add a new row, just update what is already there. I know I ave done this before but cannot remember how and can't find much about it on the net.
Anyone got any coding examples I can follow?
Thanks
# 1 Re: Saving to a spreadsheet
You are using OleDBConnection to connect to the Excel and you must be using OleDbDataAdapter too. This dataadapter has an update method for which you will have to generate an Update Command first. Take a look at the MSDN for the Update Method and how to use it.
PS: Any special reason for creating this new user id?
# 2 Re: Saving to a spreadsheet
LOL
For some reason, I couldn't login with my other one so had to create a new one.
Cheers for that. Will checkout the update method now.
# 3 Re: Saving to a spreadsheet
I now ave the code to perform the update but am not sure how to attach it to a button. The code is:
da.Update(myDataset)
But how can I get the button to perform that? The code I have already is:
Private Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
excelCon2.Open()
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
'Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp = '7rjt'", excelCon2)
Dim ds2 As New DataSet
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
End
End Sub
Thanks for any help
# 4 Re: Saving to a spreadsheet
You need to write this code in the event handler of the click event of the button. like you have written End in cmdExit's click event handler.
Remember the Click event handler should have access to the Dataadapter, the oledb connection, and the dataset. So you need to make them as Class level objects by declaring them outside of the form load event handler.
Also what is the use of using End. It does not help. You shouls have used Me.Close() rather than End.
# 5 Re: Saving to a spreadsheet
Cheers for that. I will get onto it straight away
# 6 Re: Saving to a spreadsheet
Still not got it to work. I have made the changes that you said about Shuja Ali but the spreadsheet is not updating. Here is the code:
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim ds2 As New DataSet
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
LoginForm1.Close()
Me.Close()
End Sub
Private Sub cmdupdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAward.Click
If ds2.HasChanges Then
da2.Update(ds2)
End If
End Sub
End Class
Any more help would be very appreciated!!
# 7 Re: Saving to a spreadsheet
any error on the following statement?
da2.Update(ds2)
as Shuja Ali has already pointed out you should suppy an update command for da2.UpdateCommand property. or might as well, use Command builder.
hope that helps!
# 8 Re: Saving to a spreadsheet
Hi Thread1
There is no error message when I use that bit of code. Could you give me an example of an update command for da2.UpdateCommand property or using the command builder?
Thanks for your help so far ;)
# 9 Re: Saving to a spreadsheet
you'd simply create a command builder passing the data adapter as its parameter...
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim _cb as new oledb.oledbcommandbuilder(da2)
Dim ds2 As New DataSet
.
.
.
# 10 Re: Saving to a spreadsheet
Thread1 thanks for the help so far. I reckon I must be extra thick cus I have altered the code as you said but it still doesn't work. Here is the code:
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim _cb As New OleDb.OleDbCommandBuilder(da2)
Dim ds2 As New DataSet
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
LoginForm1.Close()
Me.Close()
End Sub
Private Sub cmdupdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAward.Click
da2.Update(ds2)
End Sub
End Class
Any ideas why the update doesn't work?
# 11 Re: Saving to a spreadsheet
Please someone help me - I am close to going insane with this problem!
# 12 Re: Saving to a spreadsheet
uhumm.. what is the content of da.UpdateCommand.CommandText? i am just curious regarding the SQL statement (field names, etc) or should you build a primary key or something to be used in update-SQL WHERE clause. :confused:
# 13 Re: Saving to a spreadsheet
Hi Thread1 here is my code:
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim _cb As New OleDb.OleDbCommandBuilder(da2)
Dim ds2 As New DataSet
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
LoginForm1.Close()
Me.Close()
End Sub
Private Sub cmdupdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdupdate.Click
'_cb.GetUpdateCommand("update [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
'da2.UpdateCommand = _cb
da2.Update(ds2, "[" & Points & "]")
End Sub
End Class
I have now added a field to the spreadsheet that has a unique number in it - the studentid. Could this act as a Primar Key?
Thanks again so far
# 14 Re: Saving to a spreadsheet
Forgot to sya that with the above code, I am now getting the following error:
Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information
Please Please someone help me!!!
# 15 Re: Saving to a spreadsheet
uh oh! it seems like you're going to create the update command manually. it will take your time if you have number of columns in excel :D. well.. you can remove the commandbuilder. and by the way, you must set the IMEX to 0 in the connection string.
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=0""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim ds2 As New DataSet
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
' COL1 here must be the column that holds unique identification for rows (primary key)
Dim update As New OleDb.OleDbCommand("UPDATE [Points$] SET COL2 = ?, COL3 = ? WHERE COL1 = ?", excelCon2)
update.Parameters.Add("@COL2", OleDb.OleDbType.VarWChar, 255, "COL2")
update.Parameters.Add("@COL3", OleDb.OleDbType.VarWChar, 255, "COL3")
update.Parameters.Add("@COL1", OleDb.OleDbType.VarWChar, 255, "COL1")
da2.UpdateCommand = update
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
LoginForm1.Close()
Me.Close()
End Sub
Private Sub cmdupdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdupdate.Click
da2.Update(ds2.tables(0))
End Sub
End Class
# 16 Re: Saving to a spreadsheet
Hi Thread1 thanks for your help so far. I have implemented your code as shown below:
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
' COL1 here must be the column that holds unique identification for rows (primary key)
Dim update As New OleDb.OleDbCommand("UPDATE [Points$] SET COL2 = ?, COL3 = ?, SET COL4 = ?, COL5 = ?, SET COL6 = ?, COL7 = ?, SET COL8 = ?, COL9 = ?, SET COL10 = ?, COL11 = ? WHERE StudID = StudID", excelCon2)
update.Parameters.Add("@StudID", OleDb.OleDbType.VarWChar, 255, "StudID")
update.Parameters.Add("@Name", OleDb.OleDbType.VarWChar, 255, "Name")
update.Parameters.Add("@ClsGrp", OleDb.OleDbType.VarWChar, 255, "ClsGrp")
update.Parameters.Add("@AwardedPoints", OleDb.OleDbType.VarWChar, 255, "AwardedPoints")
update.Parameters.Add("@Sanctions", OleDb.OleDbType.VarWChar, 255, "COL5")
update.Parameters.Add("@Pastoral", OleDb.OleDbType.VarWChar, 255, "COL6")
update.Parameters.Add("@Assesment", OleDb.OleDbType.VarWChar, 255, "COL7")
update.Parameters.Add("@House", OleDb.OleDbType.VarWChar, 255, "House")
update.Parameters.Add("@Total", OleDb.OleDbType.VarWChar, 255, "Total")
update.Parameters.Add("@Target", OleDb.OleDbType.VarWChar, 255, "Target")
update.Parameters.Add("@OnTrip?", OleDb.OleDbType.VarWChar, 255, "OnTrip?")
da2.UpdateCommand = update
End Sub
The only thing is, I get the following error when I click on the Update button:
Syntax error in update statement
which points to this line
da2.Update(ds2.tables(0))
Thanks again for your help so far
# 17 Re: Saving to a spreadsheet
you're almost there. anyway, here is a simple code that generates the right column names for the update SQL statement.
Dim update As New OleDb.OleDbCommand
Dim sb As New System.Text.StringBuilder("UPDATE [Sheet1$] SET ", 1024)
' assume StudID as the primary key
For Each c As DataColumn In ds2.Tables(0).Columns
If String.Compare(c.ColumnName, "StudID", True) <> 0 Then
sb.AppendFormat("[{0}] = ?,", c.ColumnName)
update.Parameters.Add(String.Format("@{0}", c.ColumnName), OleDb.OleDbType.VarWChar, 255, String.Format("{0}", c.ColumnName))
End If
Next
If sb.Chars(sb.Length - 1) = ","c Then sb.Remove(sb.Length - 1, 1)
' put the primary key in WHERE clause
sb.Append(" WHERE StudID = ?")
update.Parameters.Add("@StudID", OleDb.OleDbType.VarWChar, 255, "StudID")
update.CommandText = sb.ToString()
update.Connection = excelCon2
da2.UpdateCommand = update
# 18 Re: Saving to a spreadsheet
That's great. Thanks for that. Will try it out later in work and let ya know how I get on!
;)
# 19 Re: Saving to a spreadsheet
This is frustrating now - I am getting the error:
IndexOutOfRangeException was unhandled
Cannot find table o
On the following line:
For Each c As DataColumn In ds2.Tables(0).Columns
Any ideas as to why?
Thanks
# 20 Re: Saving to a spreadsheet
it seems like it is looking for table o while we're using index 0 :D. where did you put the code, it must be after you fill the ds2 ...
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
Dim update As New OleDb.OleDbCommand
Dim sb As New System.Text.StringBuilder("UPDATE [Sheet1$] SET ", 1024)
' assume StudID as the primary key
For Each c As DataColumn In ds2.Tables(0).Columns
If String.Compare(c.ColumnName, "StudID", True) <> 0 Then
sb.AppendFormat("[{0}] = ?,", c.ColumnName)
update.Parameters.Add(String.Format("@{0}", c.ColumnName), OleDb.OleDbType.VarWChar, 255, String.Format("{0}", c.ColumnName))
End If
Next
If sb.Chars(sb.Length - 1) = ","c Then sb.Remove(sb.Length - 1, 1)
' put the primary key in WHERE clause
sb.Append(" WHERE StudID = ?")
update.Parameters.Add("@StudID", OleDb.OleDbType.VarWChar, 255, "StudID")
update.CommandText = sb.ToString()
update.Connection = excelCon2
da2.UpdateCommand = update
End Sub
# 21 Re: Saving to a spreadsheet
Doh - my fault. Pasted the code BEFORE I filled the DS!!
I am now getting the error:
OleDbException was unhandled
Cannot update '(expression)'; field not updateable.
For the line:
da2.Update(ds2.Tables(0))
Is this to do with the primary key? The Column StudID definately doesn't contain any duplicates in it.
Here is the full ocde for the form incase needed:
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=0""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim ds2 As New DataSet
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
Dim update As New OleDb.OleDbCommand
Dim sb As New System.Text.StringBuilder("UPDATE [points$] SET ", 1024)
' assume StudID as the primary key
For Each c As DataColumn In ds2.Tables(0).Columns
If String.Compare(c.ColumnName, "StudID", True) <> 0 Then
sb.AppendFormat("[{0}] = ?,", c.ColumnName)
update.Parameters.Add(String.Format("@{0}", c.ColumnName), OleDb.OleDbType.VarWChar, 255, String.Format("{0}", c.ColumnName))
End If
Next
If sb.Chars(sb.Length - 1) = ","c Then sb.Remove(sb.Length - 1, 1)
' put the primary key in WHERE clause
sb.Append(" WHERE StudID = ?")
update.Parameters.Add("@StudID", OleDb.OleDbType.VarWChar, 255, "StudID")
update.CommandText = sb.ToString()
update.Connection = excelCon2
da2.UpdateCommand = update
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
LoginForm1.Close()
Me.Close()
End Sub
Private Sub cmdupdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdupdate.Click
da2.Update(ds2.Tables(0))
End Sub
End Class
Thanks in advance
# 22 Re: Saving to a spreadsheet
i never encounter such error and i guess it has something to do with the XLS cell protection or something. you may try to include only those fields which you think is updatable in the SQL statement.
P.S. it would help also if you attach your xls file here.
# 23 Re: Saving to a spreadsheet
Hi Thread1, will check the XLS cell protectin thing. Meanwhile, I attach a copy of the spreadsheet. I have deleted the names out of the Name column for confidentiality purposes. I have had to convert it to a TAB delimited file as it wouldn't allow an .xls file to be uploaded!
Thanks so far ;)
# 24 Re: Saving to a spreadsheet
tried to convert and run the file using our code, and you would not believe it, i manage to update the columns without any problem! :p
you can zip and attach the xls file here, just don't truncate the first row (columns) if it is confidential.
# 25 Re: Saving to a spreadsheet
thats wierd! I wonder why it doesn't work here then?
Are you using the same code as I posted in my last post? This one:
Public Class frmViewer
Dim excelCon2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TutGrpPtsManager\points.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=0""")
Dim da2 As New OleDb.OleDbDataAdapter("Select * from [Points$] where ClsGrp Like '" & ClsGrp & "'", excelCon2)
Dim ds2 As New DataSet
Public Sub frmViewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblForm.Text = ClsGrp
Debug.Print(ClsGrp)
excelCon2.Open()
da2.Fill(ds2)
DataGridView1.DataSource = ds2.Tables(0)
Debug.Print(ClsGrp)
Dim update As New OleDb.OleDbCommand
Dim sb As New System.Text.StringBuilder("UPDATE [points$] SET ", 1024)
' assume StudID as the primary key
For Each c As DataColumn In ds2.Tables(0).Columns
If String.Compare(c.ColumnName, "StudID", True) <> 0 Then
sb.AppendFormat("[{0}] = ?,", c.ColumnName)
update.Parameters.Add(String.Format("@{0}", c.ColumnName), OleDb.OleDbType.VarWChar, 255, String.Format("{0}", c.ColumnName))
End If
Next
If sb.Chars(sb.Length - 1) = ","c Then sb.Remove(sb.Length - 1, 1)
' put the primary key in WHERE clause
sb.Append(" WHERE StudID = ?")
update.Parameters.Add("@StudID", OleDb.OleDbType.VarWChar, 255, "StudID")
update.CommandText = sb.ToString()
update.Connection = excelCon2
da2.UpdateCommand = update
End Sub
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
LoginForm1.Close()
Me.Close()
End Sub
Private Sub cmdupdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdupdate.Click
da2.Update(ds2.Tables(0))
End Sub
I will try to convert the file I sent you and then use that one.
# 26 Re: Saving to a spreadsheet
here's the XLS file :D
# 27 Re: Saving to a spreadsheet
I think I know what it was - 2 coloumns in my spreadsheet - the Target and Total columns use formulas.
They are only basic ones e.g. the Total formula is =SUM(D2+F2+G2+H2-E2) and the Target one is =SUM(100-I2)
Is there anyway to get it to save with the formulas in place e.g if they data in columns Total and Target haven't changed, then don't update those columns?
# 28 Re: Saving to a spreadsheet
the easiest way is to exclude them from the list of fields in the select command/sql..
Dim da2 As New OleDb.OleDbDataAdapter("Select StudID, Name, ClsGrp, AwardedPoints, Sanctions, Pastoral, Assessment, House, [OnTrip?] FROM [points$]", excelCon2)
# 29 Re: Saving to a spreadsheet
I thought of that but the thing is, I need them to be able to see those 2 columns as they contain important totals. There must be a way of just updating the columns that have changed.
# 30 Re: Saving to a spreadsheet
okay, exclude them in the update command.
# 31 Re: Saving to a spreadsheet
Hi again Thread1
Could you please give me an example of how to do this? I really need to get this finished now. I feel I am on the verge of finishing. This is the last question I promise!
Thanks a lot :)
# 32 Re: Saving to a spreadsheet
it must be easy, you need to change only this (bold texts) part of our code.
.
.
.
For Each c As DataColumn In ds2.Tables(0).Columns
If Array.IndexOf(New String() {"StudID", "Target", "Total"}, c.ColumnName) = -1 Then
'If String.Compare(c.ColumnName, "StudID", True) <> 0 Then
sb.AppendFormat("[{0}] = ?,", c.ColumnName)
update.Parameters.Add(String.Format("@{0}", c.ColumnName), OleDb.OleDbType.VarWChar, 255, String.Format("{0}", c.ColumnName))
End If
Next
.
.
.
# 33 Re: Saving to a spreadsheet
I have tried what you suggested above but it still displays the Cannot update '(expression)'; field not updateable error
# 34 Re: Saving to a spreadsheet
Anyone??
# 35 Re: Saving to a spreadsheet
I have sorted it out - all I had to do was make the columns readonly!
e.g.:
DataGridView1.Columns("Pastoral").ReadOnly = True
DataGridView1.Columns("Assessment").ReadOnly = True
DataGridView1.Columns("House").ReadOnly = True
DataGridView1.Columns("Total").ReadOnly = True
DataGridView1.Columns("Target").ReadOnly = True
DataGridView1.Columns("OnTrip?").ReadOnly = True
DOH I am sooooooo thick sometimes ;)
Thanks for all your help everyone