?
Solved

Object reference not set to an instance of an object.

Posted on 2006-05-15
32
Medium Priority
?
1,222 Views
Last Modified: 2016-08-29
Getting this error in my project.  https://filedb.experts-exchange.com/incoming/ee-stuff/90-ch3.zip

An unhandled exception of type 'System.NullReferenceException' occurred in WindowsApplication2.exe

Additional information: Object reference not set to an instance of an object.
0
Comment
Question by:sirbounty
  • 17
  • 9
  • 2
  • +2
32 Comments
 
LVL 5

Expert Comment

by:razorback041
ID: 16685148
debug it, and paste the code that it fails on...some additional code(before and after) would be helpful...maybe the whole function
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16685160
Form code....

    Private Sub frmList_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Fill the dataset for the list box
        daLastName.Fill(DsLastName1)
        'Set the combo box for no current selection
        cboLastName.SelectedIndex = -1
    End Sub

    Private Sub cboLastName_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboLastName.SelectedIndexChanged
        'Get the record to match the selection
        If cboLastName.SelectedIndex <> -1 Then
            DsEmployee1.Clear()
            daEmployee.SelectCommand.Parameters("@lname").Value = cboLastName.Text  <----Fails here with the error mentioned above
            daEmployee.Fill(DsEmployee1)
        End If
    End Sub
End Class
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16686454
When a combobox is bound to a datasource its .SelectedIndexChanged event appears to fire either when the binding is declared, if the datasource is already filled with data, or when the datasource is filled with data, if the binding is done first.  And, when that happens, it seems that the .SelectedIndex property for which it fires will not always be -1.

So my guess on this one is that your code is firing during you form load as part of that process and that, when it does fire, the cboLastName.Text is a null value.  Try declaring

   Dim Loading As Boolean = True

at the start of your form, putting

   If Loading Then Exit Sub

as the first line of your cboLastName_SelectedIndexChanged sub, and only putting

   Loading = False

at some point in your code when all the binding and dataloading that afects the combobox has been done.

Roger

 
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 67

Author Comment

by:sirbounty
ID: 16686752
The form loads fine - no errors.
It's only when I select a Last Name from the combo that it generates this error.

I did try that anyway and still get the same error.

0
 
LVL 5

Expert Comment

by:razorback041
ID: 16686940
try changing cboLastName.Text to cboLastNames.selectedvalue
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16686951
same error
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16687251
1) If you select 'daEmployee', you will notice that the SelectCommand property is nothing, so you can't execute this line:

daEmployee.SelectCommand.Parameters("@lname").Value = cboLastName.Text

2) Is this a lesson out of a book?

3) Why use ODBC?  Why not OleDb?

Bob

0
 
LVL 67

Author Comment

by:sirbounty
ID: 16687272
Yes, it's a practice lesson (Lord knows I could use all I can get in that area).
The book actually points to using an sql adapter.  I've had some difficulty working that angle.  I'm sure it's a pilot error, so I went (aimlessly) where I could.

I'll check that out - thanx Bob! :^)
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16687298
I get that stupid "No mapping exists" error...(http://www.experts-exchange.com/Q_21843485.html).  
I have to fiddle with it to get it working...
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16687305
Still does the same thing Bob (and I 'thought' that my sql was in there before).
I did generate a new ds as well (overwriting original).
<sigh>
0
 
LVL 39

Expert Comment

by:appari
ID: 16687941
i think you are getting the error in this line
DsEmployee1.Clear()

try changing it to, i think initially DsEmployee1 is not filled.

            If Not IsNothing(DsEmployee1) Then
                DsEmployee1.Clear()
            End If
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16688661
On the project as you originally posted it, these are the totality of references to da.Employee

*********

In the Windows Generated Region

  in Declarations

    Friend WithEvents daEmployee As System.Data.Odbc.OdbcDataAdapter

  in InitializeComponent sub

        Me.daEmployee = New System.Data.Odbc.OdbcDataAdapter

        '[...]

        'daEmployee
        '
        Me.daEmployee.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "employee", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("lname", "lname")})})

And in the cboLastName_SelectedIndexChanged sub

            daEmployee.SelectCommand.Parameters("@lname").Value = cboLastName.Text
            daEmployee.Fill(DsEmployee1)

********

So, as Bob says, when it reached the lines in the cboLastName_SelectedIndexChanged sub, there wasn't a SelectCommand for the daEmployee and, as there was no such command, there couldn't be any parameters for it either.

It looks, from your later postings, as though you've tried to correct that - "I 'thought' that my sql was in there before" - but how did you do that?  What code did you use, and where did you put it?  It looks as though the original code was generated by dragging data components onto the form.  If that is so, the easiest approach might be to delete the existing daEmployee, drag a new one on to the form and re-configure it.  That should not only make sure that the select command and parameters are there but also that the table mappings are re-done.

Roger

PS  I doubt that there would be a problem with DsEmployee1.Clear().  DsEmployee1 seems to have been properly declared.  As (I agree) it would not have been filled, the .Clear() would not actually do anything, but I don't think it would throw an error.
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16689626
Correct - the Clear() does not generate the error.
This is a textboox hands-on that initially began with a simple drop down of the last names.  At that time, my select statement was simply 'select lname from employee'.
The other problem I have is - when I 'do' drag the table (from server explorer), it always generates an error, so I end up adding the components manually.
I've started from scratch twice on this thing and run into the same issues each time.  
How did I correct it?  I right clicked on daEmployee, and modified the sql from the 'wizard' there.  Even now looking at it, it is set to "select .... from ... where lname='@lname'"

So, this time I went to the odbccommand1, renamed it to cmdEmployee, added the active con (conPubs) and then modified the commandtext to the same select statement.

This time, when I run it - I get this error:

An unhandled exception of type 'System.IndexOutOfRangeException' occurred in system.data.dll

Additional information: An OdbcParameter with ParameterName '@lname' is not contained by this OdbcParameterCollection.
0
 
LVL 39

Expert Comment

by:appari
ID: 16689668

>>"select .... from ... where lname='@lname'"
 try removing the single quotes around @lname
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16689706
invalid property value
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16689788
>>
this time I went to the odbccommand1, renamed it to cmdEmployee, added the active con (conPubs) and then modified the commandtext to the same select statement
<<

>>
Additional information: An OdbcParameter with ParameterName '@lname' is not contained by this OdbcParameterCollection.
<<

And did you also modify the list of parameters for odbccommand1 so that they became parameters for cmdEmployee?

How about doing what I did a few posts up and going through the code extracting all the references to the relevant dataadapter and posting that?

Roger
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16689821
>>did you also modify the list of parameters for odbccommand1 so that they became parameters for cmdEmployee<<

I actually renamed odbccommand1 to cmdEmployee.
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16689869
   Friend WithEvents daLastName As System.Data.Odbc.OdbcDataAdapter
    Friend WithEvents DsLastName1 As WindowsApplication2.dsLastName
    Friend WithEvents dvLastName As System.Data.DataView
   
    Friend WithEvents daEmployee As System.Data.Odbc.OdbcDataAdapter
    Friend WithEvents DsEmployee1 As WindowsApplication2.dsEmployee
   
    Friend WithEvents cmdEmployee As System.Data.Odbc.OdbcCommand

   
    Me.cmdSQLLName = New System.Data.Odbc.OdbcCommand
    Me.daLastName = New System.Data.Odbc.OdbcDataAdapter
    Me.DsLastName1 = New WindowsApplication2.dsLastName
    Me.dvLastName = New System.Data.DataView
    Me.daEmployee = New System.Data.Odbc.OdbcDataAdapter
    Me.DsEmployee1 = New WindowsApplication2.dsEmployee
    Me.cmdEmployee = New System.Data.Odbc.OdbcCommand
    CType(Me.DsLastName1, System.ComponentModel.ISupportInitialize).BeginInit()
    CType(Me.dvLastName, System.ComponentModel.ISupportInitialize).BeginInit()
    CType(Me.DsEmployee1, System.ComponentModel.ISupportInitialize).BeginInit()
   
    Me.cmdSQLLName.CommandText = "SELECT lname FROM employee"
    Me.cmdSQLLName.Connection = Me.conPubs
   
    Me.daLastName.SelectCommand = Me.cmdSQLLName
    Me.daLastName.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "employee", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("lname", "lname")})})
   
    Me.DsLastName1.DataSetName = "dsLastName"
    Me.DsLastName1.Locale = New System.Globalization.CultureInfo("en-US")
   
    Me.dvLastName.Sort = "lname"
    Me.dvLastName.Table = Me.DsLastName1.employee
 
    Me.daEmployee.SelectCommand = Me.cmdEmployee
    Me.daEmployee.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "employee", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("lname", "lname")})})
   
    Me.DsEmployee1.DataSetName = "dsEmployee"
    Me.DsEmployee1.Locale = New System.Globalization.CultureInfo("en-US")
   
    Me.cmdEmployee.CommandText = "SELECT emp_id, fname, lname, hire_date FROM employee WHERE (lname = @lname)"
    Me.cmdEmployee.Connection = Me.conPubs
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16689950
Originally the code would have loooked something like

   Me.odbccommand1.CommandText = <Whatever>
   Me.odbccommand1.Connection = <whatever>
   Me.odbccommand1.Parameters.Add(<whatever>)

What was asking was whether, when you did the renaming, you renamed ALL parts including

   Me.odbccommand1.Parameters.Add(<whatever>)

The code you've now posted shows that you didn't.  Or, if you did, it's gone missing somewhere.

Roger
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16690770
I've got

 Me.cmdEmployee.CommandText = "SELECT emp_id, fname, lname, hire_date FROM employee WHERE (lname=@lname)"
        Me.cmdEmployee.Connection = Me.conPubs

But, I don't add the parameters until the selectedindexchange of the combo box...
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16691570
No, you don't add the parameter then.  What you add in "the selectedindexchange of the combo box" is the VALUE that you want the named parameter to have.  The Parameter, on the one hand, and the Parameter's Value, on the other hand, are different.  Until a parameter has been added to the Parameters Collection of cmdEmployee there is no parameter for a parameter's value to be given to.

In your command text

 Me.cmdEmployee.CommandText = "SELECT emp_id, fname, lname, hire_date FROM employee WHERE (lname=@lname)"

you are indicating, with the bit that says "(lname=@lname)", that when the select command is run it should look for the value to which lname should be equal in a parameter called @lname.  But that is not enough to create that parameter.  That has to be done with something like

  Me.cmdEmployee.Parameters.Add("@lname", OdbcType.VarChar)

The first argument is the parameter's name, the second is its datatype.  I say "something like ..." as I'm not used to working with ODBC.  Try putting that immediately after

       Me.cmdEmployee.Connection = Me.conPubs

and see if it works.  If it doesn't, then have a look in the help files for OdbcParameter Constructor and try other versions.  What I was hoping was that the wizard would originally have created the parameter with code equivalent to the above, but perhaps - because of the difficulties you say you've had with the wizard - it didn't.

Keep at it.  You're nearly there ;-)

Roger
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16692951
Thanx for the encouragement.  I'm a long way from my ultimate goal though (understanding all this!).

I found this site: http://www.codeproject.com/cs/database/odbcnet_syb_stp.asp which, I think, shows how to use the Parameters, but I'm not sure how OdbcType should be declared?
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16693393
How about using the code in this link as your pattern?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdataodbcodbcdataadapterclassselectcommandtopic.asp

The first few lines are doing something very similar to what you want to do: that is, have a select statement with a where clause in it.  And its in VB.NET, which the code in the link you posted isn't - though it's easily translatable.  The major difference is that the example uses two parameters, rather than one.  But it illustrates the approach and would need very little modification.

As I said, I'm not used to working with ODBC, but it looks like this

    Me.cmdEmployee.CommandText = "SELECT emp_id, fname, lname, hire_date FROM employee WHERE (lname = ?)"
    Me.cmdEmployee.Connection = Me.conPubs
    Me.cmdEmployee.Parameters.Add("@lname", OdbcType.VarChar, 50)

should do it for you.  I've guessed at the size of the lname field.  If it's different from 50, you can substitute some other number.  You will notice that I've changed the (lname = @lname) to (lname = ?).  That's because that's how the example does it.  So it looks like ODBC is like OleDb (and different from SQL) and marks its parameters with "?" rather than a name beginning with "@".

Roger
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16695528
Man, ya gotta love Roger (aka THE ADO.NET guy)!!!

I was sitting at work reading these comments without the ability to respond.   Luckily, somebody else could pick up the ball.

Bob
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16696231
Yay!  I got a bit further...

Now it errors/halts at the "End If" with the following:

An unhandled exception of type 'System.InvalidCastException' occurred in system.data.dll
Additional information: Object must implement IConvertible.

Of the cbo, my Index=7, text is "", and Value (which is what it's set to use) returns:
{System.Data.DataRowView}
    [System.Data.DataRowView]: {System.Data.DataRowView}

<sigh>
Should I give up and move on to the next section?  I think I know how it's "supposed" to work...very frustrating when the 'book' doesn't show the correct way to accomplish these tasks...I copied it almost precisely... : (
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16696240
Would it be relatively easy to switch gears to oledb?
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16697682
>>
I copied it almost precisely
<<

I don't know whether the 'book' is wrong or it's that word 'almost' ;-)

The problem now seems to be that the last names data is not getting to the combobox.  The combobox is bound to a dataview

        Me.cboLastName.DataSource = Me.dvLastName

That dataview's table is declared by this line

        Me.dvLastName.Table = Me.DsLastName1.employee

But when the data for last name is brought over from the database it is done with this line

        daLastName.Fill(DsLastName1)

That means that it is just dumped in a datatable in the dataset having the default name of "Table", rather than being put in a datatable named "employee" which is what the dataview is relying on.

My guess is that there was (there certainly should have been) in the original code a line giving a table mapping to the daLastName dataadapter.  But I gather from a comment above (although the other thread to which it refers has now been deleted) that you've had problems with table mappings.  So rather than reinstating (or re-coding that) you should be able to overcome the problem by changing this line

        daLastName.Fill(DsLastName1)

to this

        daLastName.Fill(DsLastName1, "employee")

That will make sure that the data goes in a datatable with the name that the dataview expects.  Another alternative would be to change this line

        Me.cboLastName.DataSource = Me.dvLastName

to

        Me.cboLastName.DataSource = Me.DsLastName1.Tables(0)

which would bind the combobox direct to the (first and only) table in DsLastName1 and get the last name data already sorted (rather than relying on the dataview to do the sorting) by changing the SelectCommand CommandText from

       "SELECT lname FROM employee"

to

       "SELECT lname FROM employee ORDER BY lname"

Re a switch to oledb.  Provided you have a database - usually .mdb - to work with with oledb, yes, a switch would be easy.  In principle, I'm not sure that it would make it any easier to learn.  The basics are very similar, it's just some of the detailed syntax that differs, and oledb has its own quirks.  But you might find that the wizards work better with it.

Roger
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16698279
I sincerely appreciate the effort and time you've put forth explaining all this to me.

By 'almost', I meant only that the book example was with using an sql da.  I was unable to do this (for reasons I'll exclude here, but probably are worth the effort of another question, since this seems to be the books standard adapter).

So, I couldn't be certain that everything would be the same.  I suppose I grabbed the odbc, not really thinking about it, and had typically used ole myself (oops).


>>The problem now seems to be that the last names data is not getting to the combobox.<<

But, it is there...  When I run the program, the combo is populated.  The errors start occuring when I actually choose a Last name from the cbo.
The purpose of this exercise was supposed to show how you're better off binding to a dataview, cause you (supposedly) can't sort it otherwise (?).

The text reads:  When you want to display the data in alphabetical order...you can usually set Sorted to True.  Unfortunately, this does not work when bound to a data source.

But it would also make sense to simply order it via the sql statement.

>> But I gather from a comment above ... that you've had problems with table mappings.<<
Yes, and if you have any suggestions on 'that' problem, I'd be more than glad to reopen it!

So, I tried it again with the change you suggested above (adding "employee" as the table name).  It's still halting at the same spot, but I just identified the 'spot' as the line above the End If (the End If gets highlighted in green, thus my confusion).  So, it's actually this line causing the problem :

daEmployee.Fill(DsEmployee1)

Thanx again for your patience and time! I really appreciate it.
0
 
LVL 34

Accepted Solution

by:
Sancler earned 2000 total points
ID: 16698430
Ignore all that.  I was thinking about this and realised that, if my diagnosis was correct, there wouldn't have been any data in the combobox so there couldn't - as you reported - be an Index of 7.  So I went back to the original code and the necessary Table Mapping is there.  I was looking at the wrong dataadapter ;-(.

The change you need to make instead is in this line

            daEmployee.SelectCommand.Parameters("@lname").Value = cboLastName.Text

instead of cboLastName.Text, I suggest you use cboLastName.SelectedItem, but you will then have to extract from it - as it is a datarowview - the precise value that you want.  This should do it.

            daEmployee.SelectCommand.Parameters("@lname").Value = CType(cboLastName.SelectedItem,DataRowView).Item("lname")

Sorry about that.

Roger

PS  I was typing this when the notification of your last post arrived.  But I left it as it was.

0
 
LVL 67

Author Comment

by:sirbounty
ID: 16698729
No apology necessary.
Whoo hoo...it's finally working! :)
Thank you, thank you, thank you!

Now, on to the next project...I hope you'll be around for a while...haha. :^)
0
 
LVL 34

Expert Comment

by:Sancler
ID: 16698931
Glad it's sorted.  And - despite the serial frustrations of it not working - I think you'll find that it did throw up a few useful learning points.  And that, after all, is what the exercise was really about.

Thanks for the points.

Roger
0
 
LVL 67

Author Comment

by:sirbounty
ID: 16724750
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses
Course of the Month16 days, 18 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question