can't add row

D

dennist

I thought I had this mastered, but apparently I don't.
Here's the problem. On one tab of a form I have a listbox
of Authors. In the previous tab a topic is created,
usually an article. On the next tab the user can assign
the author(s) who wrote the article to the
TopicAuthorAssignments table. On the authors tab page I
created a connection - cnTAA, dataadapter, daTAA, and
dataset dsTAA.

I try to do the update in a class called clsDataChor,
public function NewTopicAuthorAssignment. Something goes
wrong. I set up the call to this function in the code
below:

Private Sub btnSaveTabAuthors_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
btnSaveTabAuthors.Click

Dim clsDChor As New clsDataChor
If lstAuthors.SelectedIndex = -1 Then
MsgBox("No Author selected.")
cboTopicIssuers.Focus()
Exit Sub
End If

Dim i, idx, iValue, iValue1 As Integer
giCount = lstAuthors.SelectedIndices.Count - 1
giValue = CInt(txtID.Text)
clsDChor.NewTopicAuthorAssignment(Me)
For i = 0 To lstAuthors.SelectedIndices.Count - 1
idx = lstAuthors.SelectedIndices(i)
Dim drv As DataRowView
drv = lstAuthors.Items(idx)
'MessageBox.Show(drv.Row("ID")).ToString
() '["selectedvalue"]
'MessageBox.Show(drv.Row
[listBox1.ValueMember].ToString())
iValue = CInt(txtID.Text)
iValue1 = drv.Row("ID")
'MsgBox(iValue.ToString & " " &
iValue1.ToString)
Next

End Sub

giCount and giValue are public 'global' variables,
later used in the function.

Now the code of the function, with some comments on what
happens when I try alternatives, follows:

Public Function NewTopicAuthorAssignment(ByVal frm As
frmTopicFromStart) As Boolean

NewTopicAuthorAssignment = False
Try
frm.cnTAA.Open()
Catch er As Exception
MessageBox.Show("Type = " &
er.GetType.ToString & vbCr & "Message = " & er.Message)
End Try

'frm.daTAA.Fill(dsTAA, "TopicAuthorAssignments")
' dstaa is a type and cannot be used as an
expression
frm.daTAA.Fill
(frm.DsTAA1, "TopicAuthorAssignments")

'Dim tblTAA As
frm..TopicAuthorAssignmentsDataTable
'if frm, nothing appears after .
'if frmtopicfromstart, 4 items appear after . but
none relevant to datasets or datatables
'if dstaa1, nothing appears after dot
'if I start typing d, dstaa appears
Dim tblTAA As
dsTAA.TopicAuthorAssignmentsDataTable
Dim rowTAA As dsTAA.TopicAuthorAssignmentsRow


Dim i, idx As Integer
For i = 0 To giCount
MsgBox(giCount.ToString)
rowTAA = tblTAA.NewTopicAuthorAssignmentsRow
'object reference not set to an instance of
an object.
rowTAA.TopicID = giValue
idx = frm.lstAuthors.SelectedIndices(i)
Dim drv As DataRowView
drv = frm.lstAuthors.Items(idx)
rowTAA.AuthorID = drv.Row("ID")
tblTAA.AddTopicAuthorAssignmentsRow
(rowTAA) '. as tfsnet2.dstaa.topicauthorassignmentsrow)

Next

If frm.DsTAA1.HasChanges Then
Try
Dim intTAAModified As Integer
intTAAModified = frm.daTAA.Update
(frm.DsTAA1.TopicAuthorAssignments)
Dim strOutput As String
strOutput = "Modified " & intTAAModified
& " TopicAuthorAssignment(s)"
MessageBox.Show(strOutput, "Update
succeeded!", MessageBoxButtons.OK,
MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message, "Update
failed!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Else
MessageBox.Show("No changes to
submit!", "SubmitChanges", MessageBoxButtons.OK,
MessageBoxIcon.Information)
End If

End Function



The error I get is as follows

rowTAA = tblTAA.NewTopicAuthorAssignmentsRow
'object reference not set to an instance of
an object.

in more detail,
An unhandled exception of
type 'System.NullReferenceException' occurred in
TFSNet2.exe

Additional information: Object reference not set to an
instance of an object

dennist
 
K

Kathleen Dollard

Dennist,

This is too much code to expect people here to wade through (aim for 20 or
less lines of code). I did this morning, but might not another day. Compiler
errors just need the code surrounding the line indicated, and the
declarations of the appropriate variables.

You're error is null reference, you're problem line is
rowTAA = tblTAA.NewTopicAuthorAssignmentsRow

With a null referenece exception it is almost certain that the variable
tblTAA is not being instantiated properly. It is declared as
Dim tblTAA As
dsTAA.TopicAuthorAssignmentsDataTable

Which does not instantiate it.You probably just need to add New to this
line.

The logic of your code is quite convoluted, and the loop in the first
routine you posted accomplishes nothing as far as I can tell. Code to update
your database should not be this complex. I suggest that you take a look at
simplifying it, including passing parameters instead of using global
variables. Global variables to communicate between methods is a technique of
last resort. You will get burned by it, and it should not be needed for this
kind of code.

I think with a second look at this code you can simplify it, and if you have
any trouble with that, or in how to avoid global variables for inter-method
communications, folks here will be glad to help.

--
Kathleen Dollard
Microsoft MVP
Author "Code Generation in Microsoft .NET"


dennist said:
I thought I had this mastered, but apparently I don't.
Here's the problem. On one tab of a form I have a listbox
of Authors. In the previous tab a topic is created,
usually an article. On the next tab the user can assign
the author(s) who wrote the article to the
TopicAuthorAssignments table. On the authors tab page I
created a connection - cnTAA, dataadapter, daTAA, and
dataset dsTAA.

I try to do the update in a class called clsDataChor,
public function NewTopicAuthorAssignment. Something goes
wrong. I set up the call to this function in the code
below:

Private Sub btnSaveTabAuthors_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
btnSaveTabAuthors.Click

Dim clsDChor As New clsDataChor
If lstAuthors.SelectedIndex = -1 Then
MsgBox("No Author selected.")
cboTopicIssuers.Focus()
Exit Sub
End If

Dim i, idx, iValue, iValue1 As Integer
giCount = lstAuthors.SelectedIndices.Count - 1
giValue = CInt(txtID.Text)
clsDChor.NewTopicAuthorAssignment(Me)
For i = 0 To lstAuthors.SelectedIndices.Count - 1
idx = lstAuthors.SelectedIndices(i)
Dim drv As DataRowView
drv = lstAuthors.Items(idx)
'MessageBox.Show(drv.Row("ID")).ToString
() '["selectedvalue"]
'MessageBox.Show(drv.Row
[listBox1.ValueMember].ToString())
iValue = CInt(txtID.Text)
iValue1 = drv.Row("ID")
'MsgBox(iValue.ToString & " " &
iValue1.ToString)
Next

End Sub

giCount and giValue are public 'global' variables,
later used in the function.

Now the code of the function, with some comments on what
happens when I try alternatives, follows:

Public Function NewTopicAuthorAssignment(ByVal frm As
frmTopicFromStart) As Boolean

NewTopicAuthorAssignment = False
Try
frm.cnTAA.Open()
Catch er As Exception
MessageBox.Show("Type = " &
er.GetType.ToString & vbCr & "Message = " & er.Message)
End Try

'frm.daTAA.Fill(dsTAA, "TopicAuthorAssignments")
' dstaa is a type and cannot be used as an
expression
frm.daTAA.Fill
(frm.DsTAA1, "TopicAuthorAssignments")

'Dim tblTAA As
frm..TopicAuthorAssignmentsDataTable
'if frm, nothing appears after .
'if frmtopicfromstart, 4 items appear after . but
none relevant to datasets or datatables
'if dstaa1, nothing appears after dot
'if I start typing d, dstaa appears
Dim tblTAA As
dsTAA.TopicAuthorAssignmentsDataTable
Dim rowTAA As dsTAA.TopicAuthorAssignmentsRow


Dim i, idx As Integer
For i = 0 To giCount
MsgBox(giCount.ToString)
rowTAA = tblTAA.NewTopicAuthorAssignmentsRow
'object reference not set to an instance of
an object.
rowTAA.TopicID = giValue
idx = frm.lstAuthors.SelectedIndices(i)
Dim drv As DataRowView
drv = frm.lstAuthors.Items(idx)
rowTAA.AuthorID = drv.Row("ID")
tblTAA.AddTopicAuthorAssignmentsRow
(rowTAA) '. as tfsnet2.dstaa.topicauthorassignmentsrow)

Next

If frm.DsTAA1.HasChanges Then
Try
Dim intTAAModified As Integer
intTAAModified = frm.daTAA.Update
(frm.DsTAA1.TopicAuthorAssignments)
Dim strOutput As String
strOutput = "Modified " & intTAAModified
& " TopicAuthorAssignment(s)"
MessageBox.Show(strOutput, "Update
succeeded!", MessageBoxButtons.OK,
MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message, "Update
failed!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Else
MessageBox.Show("No changes to
submit!", "SubmitChanges", MessageBoxButtons.OK,
MessageBoxIcon.Information)
End If

End Function



The error I get is as follows

rowTAA = tblTAA.NewTopicAuthorAssignmentsRow
'object reference not set to an instance of
an object.

in more detail,
An unhandled exception of
type 'System.NullReferenceException' occurred in
TFSNet2.exe

Additional information: Object reference not set to an
instance of an object

dennist
 
K

Kevin Yu [MSFT]

Thanks for Kathlenn's response.

Hi Dennis,

The exception means that tblTAA is a null reference here, because it hasn't
been instantiated. So when you are going to dereference it, the exception
is thrown. Please try to change the following line

Dim tblTAA As dsTAA.TopicAuthorAssignmentsDataTable()

to

Dim tblTAA As New dsTAA.TopicAuthorAssignmentsDataTable()

to recover.

If anything is unclear, please feel free to reply to the post. Happy New
Year!

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
G

Guest

Thank both of you for spending your new year's weekend in
part helping me.

Kevin knows, but Kathleen most likely doesn't know, about
my condition. In case she doubts it, she can check with
Gil Berkovich of MSDN in Ireland, or Karen(don't know her
last name) at Microsoft technical support in Haifa.

If I seem less sharp than I should be it's because I am.
I suffer from a spinal injury from a terrorist attack.
Spinal pain is called world class pain, for a reason.
Often I have to take a narcotic against it. Every night
I have to take a strong sleeping medicine, and I take an
enormous amount of anti-spastic medicine, which also
doesn't sharpen the mind. To top it off, I have to take
a muscle relaxant, called Clonix in Israel, a cousin of
valium.

I changed the dim tblTAA statement to new. That helped.
My code for that function is now:

Public Function NewTopicAuthorAssignment(ByVal frm As
frmTopicFromStart) As Boolean

NewTopicAuthorAssignment = False
Try
frm.cnTAA.Open()
Catch er As Exception
MessageBox.Show("Type = " &
er.GetType.ToString & vbCr & "Message = " & er.Message)
End Try

'frm.daTAA.Fill(dsTAA, "TopicAuthorAssignments")
' dstaa is a type and cannot be used as an
expression
frm.daTAA.Fill
(frm.DsTAA1, "TopicAuthorAssignments")

'Dim tblTAA As
frm..TopicAuthorAssignmentsDataTable
'if frm, nothing appears after .
'if frmtopicfromstart, 4 items appear after . but
none relevant to datasets or datatables
'if dstaa1, nothing appears after dot
'if I start typing d, dstaa appears
Dim tblTAA As New
dsTAA.TopicAuthorAssignmentsDataTable
Dim rowTAA As dsTAA.TopicAuthorAssignmentsRow


Dim i, idx As Integer
For i = 0 To giCount
'MsgBox(giCount.ToString)
rowTAA = tblTAA.NewTopicAuthorAssignmentsRow
'object reference not set to an instance of
an object.
rowTAA.TopicID = giValue
idx = frm.lstAuthors.SelectedIndices(i)
Dim drv As DataRowView
drv = frm.lstAuthors.Items(idx)
rowTAA.AuthorID = drv.Row("ID")
tblTAA.AddTopicAuthorAssignmentsRow
(rowTAA) '. as tfsnet2.dstaa.topicauthorassignmentsrow)
frm.daTAA.InsertCommand = New
OleDb.OleDbCommand("INSERT INTO TopicAuthorAssignments
(TopicID, AuthorID) VALUES( ?, ?)", cn)
frm.daTAA.InsertCommand.Parameters.Add
("@TopicID", OleDb.OleDbType.Integer, 4, "TopicID")
frm.daTAA.InsertCommand.Parameters.Add
("@AuthorID", OleDb.OleDbType.Integer, 4, "AuthorID")
frm.daTAA.Update
(frm.DsTAA1.TopicAuthorAssignments)

Next

'If frm.DsTAA1.HasChanges Then
' Try
' Dim intTAAModified As Integer
' intTAAModified = frm.daTAA.Update
(frm.DsTAA1.TopicAuthorAssignments)
' Dim strOutput As String
' strOutput = "Modified " & intTAAModified
& " TopicAuthorAssignment(s)"
' MessageBox.Show(strOutput, "Update
succeeded!", MessageBoxButtons.OK,
MessageBoxIcon.Information)
' Catch ex As Exception
' MessageBox.Show(ex.Message, "Update
failed!", MessageBoxButtons.OK, MessageBoxIcon.Error)
' End Try
'Else
' MessageBox.Show("No changes to
submit!", "SubmitChanges", MessageBoxButtons.OK,
MessageBoxIcon.Information)
'End If
frm.cnTAA.Close()


End Function

It operates without error, but it doesn't update my
database with a new row in the TopicAuthorAssignments
table. I've tried any number of variations, without
success. This last variation is inefficient, calling the
update method one author at a time.

Obviously I'd like a method that updated the database
after the dataset added all the new rows.

Although the method appears convoluted, I took it pretty
much from Chapter 13 of ADO.NET, Core Reference, from
Microsoft Press.

I would actually like to create the adapter and dataset
in code, but I got nowhere with it, even though almost
identical code worked elsewhere in clsDataChor.

If someone can help further, I'd be much obliged.

dennist
 
K

Kathleen Dollard

Dennist,

First, this isn't as inefficient at runtime as you think becuase the current
version of SQL Server/.NET updates rows across the wire one record at a time
anyway.

Second, To get this working in fewer lines of code, becuase that's more
efficient for the programmer, I'd suggest you create a DataAdapter through
the wizard and then go steal the code from the DataAdapter to put it
whereever you want to put it. Just to save typing, I use that approach when
I'm not using stored procedures.
 
D

dennist

Thanks for the answer.

I'm afraid I didn't make myself clear. It isn't
working. No errors are generated, but the database isn't
updated. There are no rows in the TopicAuthorAssignments
table.

Oh, and it's an Access database, not an sql server
database.

dennist
 
C

Cor

Hi Dennist,

I agree with Kathleen that your code is very good obfuscasted.
(Unreadable for others)

My advice for you is a little bit else than Katleen, write your program
first without using all those classes.
(You can do that always later)

Your error but that will probably just be the first and there will follow.

Dim rowTAA As dsTAA.TopicAuthorAssignmentsRow
Dim i, idx As Integer
For i = 0 To giCount
MsgBox(giCount.ToString)
rowTAA = tblTAA.NewTopicAuthorAssignmentsRow

You have never set a reference.
That can be something as

dim rowTaa as new datarow

But I cannot see it.

An other advice put in the top of your program Option Strict on

And when you then get errors, do not think you resolve that with Option
strict Off

Just some thoughts,

Cor
 
K

Kevin Yu [MSFT]

Hi Dennis,

From the code, we can see that "Dim tblTAA As New
dsTAA.TopicAuthorAssignmentsDataTable" creates a new DataTable from the
table. However, the table tblTAA hasn't been added to the DataSet table
collection. So when you update the database with
"frm.daTAA.Update(frm.DsTAA1.TopicAuthorAssignments)", no action is taken,
because frm.DsTAA1.TopicAuthorAssignments was not changed at all. Please
try to use the following instead.

frm.daTAA.Update(tblTAA)

If anything is unclear, please feel free to reply to the post.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
D

dennist

Kevin, works fine. Thank you.

But it seems to me that I've done it in a roundabout
way. Since that topicauthorassignments table is already
in dstaa, why can't I appeal to a new datarow from that
table directly? I just tried several approaches but vb
rejected them. Is there a way I can use the dataset
directly?

Also, what confuses me no end. Which is the dataset.
dsTAA, or dsTAA1?

dennist
 
K

Kevin Yu [MSFT]

Hi Dennis,

Since the daTAA is filling the form.DsTAA1, I think we should use the
DsTAA1 instead of dsTAA. You can try the following code to get the instance
of the DataTable which contains data.

Dim tblTAA As DsTAA1.TopicAuthorAssignmentsDataTable =
DsTAA1.TopicAuthorAssignments

If anything is unclear, please feel free to reply to the post.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
D

dennist

Thanks Kevin,

However when I put in the statement

Dim tblTAA As DsTAA1.TopicAuthorAssignmentsDataTable =
DsTAA1.TopicAuthorAssignments()

I get the error dstaa1.topicauthorassignmentsdatatable is
not defined.

I've take care to comment out conflicting statements.

dennist
-----Original Message-----
Hi Dennis,

Since the daTAA is filling the form.DsTAA1, I think we should use the
DsTAA1 instead of dsTAA. You can try the following code to get the instance
of the DataTable which contains data.

Dim tblTAA As
DsTAA1.TopicAuthorAssignmentsDataTable =
 
K

Kevin Yu [MSFT]

Hi Dennis,

I can't tell why this happens because I haven't seen the context of the
code. You can try to check the definition of DsTAA1. Is it the same type as
dsTAA?

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
D

dennist

Kevin, thank you for keeping watch. I'm very ill right
now so can't post my problem. Hopefully tomorrow, if not
Friday.

Dennist
 
K

Kevin Yu [MSFT]

Hi Dennis,

Welcome back any time. I'm always ready to help.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
Top