Results 1 to 11 of 11

Thread: [RESOLVED] DataAdapter thinks everything is NULL

  1. #1

    Thread Starter
    Member _cerberus_'s Avatar
    Join Date
    Jun 2019
    Location
    Minnesota, USA
    Posts
    37

    Resolved [RESOLVED] DataAdapter thinks everything is NULL

    I'm at a complete loss and very confused. I have two different WinForms that perform almost exactly the same - that is to retrieve data from the database and be able to edit & save that data back, or to create new records. On form "A" everything works as expected with no errors. On form "B" it thinks controls are NULL if that column in the database is set to "Not NULL." Form "B" uses almost identical code to form "A" for building everything, as well as editing and saving records. If I change a "problem" column to accept nulls, then the error goes away for that column. This is not an issue on form "A" even though it has a similar database setup as well.

    IF I do a CType(bs_Record.current, datarowview).Item("Room") I get the value expected.
    If I do a dt_Record.Rows.Item(772).item("Room") I get the value expected.

    Here is the error I am getting:
    Name:  Error.png
Views: 745
Size:  14.5 KB


    I am not understanding why the DataAdapter thinks the controls are NULL, even though the BindingSource AND DataTable both have the information in them.


    This is the code to build the DA, DT, and BS:
    Code:
    Using SQLcmd As New SqlCommand With {
    	.Connection = Vars.sqlConn,
    	.CommandText = "SELECT * FROM [BAD].[data_Lab_Asset] ORDER BY [BGL_ID] DESC"}
    	da_Record.SelectCommand = SQLcmd
    	Dim sqlCB As New SqlCommandBuilder(da_Record)
    	AddHandler da_Record.RowUpdated, AddressOf OnRowUpdated
    
    	da_Record.Fill(dt_Record)
    
    	dt_Record.Columns("OP_Status_ID").DefaultValue = 3
    
    	'** ALL Check boxes need a Default Value for the "Add New" to work
    	dt_Record.Columns("Retired").DefaultValue = False
    	dt_Record.Columns("Storage").DefaultValue = False
    	dt_Record.Columns("Transferred").DefaultValue = False
    	dt_Record.Columns("Removed").DefaultValue = False
    	dt_Record.Columns("Calibration_Req").DefaultValue = False
    	dt_Record.Columns("TQC_Req").DefaultValue = False
    	dt_Record.Columns("TQC_Built").DefaultValue = False
    	dt_Record.Columns("TQC_Worklist_ID").DefaultValue = 0
    
    	bs_Record.DataSource = dt_Record
    	bsnav_Record.BindingSource = bs_Record
    End Using
    Here is a snippet of the Binding code:
    Code:
    Private Sub BindControls()
    	Try
    		txtRecID.DataBindings.Add("Text", bs_Record, "ID_Lab_Asset")
    
    		cboxSupportGroup.DataBindings.Add("SelectedValue", bs_Record, "Support_Group_ID")
    		cboxArea.DataBindings.Add("SelectedValue", bs_Record, "Work_Area_ID")
    		txtRoom.DataBindings.Add("Text", bs_Record, "Room")
    
    		cboxClass.DataBindings.Add("SelectedValue", bs_Record, "Class_ID")
    		cboxSubclass.DataBindings.Add("SelectedValue", bs_Record, "Subclass_ID")
    		cboxSubcategory.DataBindings.Add("SelectedValue", bs_Record, "Subcategory_ID")
    
    		chkCalReq.DataBindings.Add("Checked", bs_Record, "Calibration_Req")
    		dtpCalDue.DataBindings.Add("Text", bs_Record, "Calibration_Due", True, DataSourceUpdateMode.OnValidation, " ", "MM/dd/yyyy")
    
    		dtpPurch.DataBindings.Add("Text", bs_Record, "Date_Purchased", True, DataSourceUpdateMode.OnValidation, " ", "MM/dd/yyyy")
    		dtpRecvd.DataBindings.Add("Text", bs_Record, "Date_Received", True, DataSourceUpdateMode.OnValidation, " ", "MM/dd/yyyy")
    		txtRecvdFrom.DataBindings.Add("Text", bs_Record, "Received_From")
    
    		txtComments.DataBindings.Add("Text", bs_Record, "Comments")
    
    	Catch ex As Exception
    		CustExErrorMsg(Name, Reflection.MethodBase.GetCurrentMethod().Name, GetExceptionInfo(ex))
    	End Try
    End Sub
    Code to create new row in BindingSource:
    Code:
    Private Sub btnNew_Click(sender As Object, e As EventArgs) Handles BNavAddNewItem.Click
    	Try
    		bs_Record.AddNew()
    
    		bs_Related.Filter = "BIOMED_Tag = 'XXX'"
    		bs_Validation.Filter = "Lab_Asset_ID = 'XXX'"
    
    		dtpPurch.Value = New Date(Date.Now.Year, Date.Now.Month, Date.Now.Day - 1)
    		dtpRecvd.Value = New Date(Date.Now.Year, Date.Now.Month, Date.Now.Day - 1)
    		dtpInUse.Value = New Date(Date.Now.Year, Date.Now.Month, Date.Now.Day - 1)
    
    		EnableControls()
    
    	Catch ex As Exception
    		CustExErrorMsg(Name, Reflection.MethodBase.GetCurrentMethod().Name, GetExceptionInfo(ex))
    	End Try
    End Sub
    And finally the code to save the record:
    Code:
    Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles BNavSaveItem.Click
    	Try
    		If IsComplete() Then
    			If blnNew Then If IsDuplicate() Then GoTo TheEnd
    
    			Me.Validate()
    			bs_Record.EndEdit()
    			da_Record.Update(dt_Record)
    
    			If blnNew Then bs_Record.Position = bs_Record.Find("ID_Lab_Asset", ID_New)
    
    TheEnd:
    			IsDirty = False
    			blnEdit = False
    			blnNew = False
    			DisableControls()
    		End If
    
    	Catch ex As Exception
    		CustExErrorMsg(Name, Reflection.MethodBase.GetCurrentMethod().Name, GetExceptionInfo(ex))
    	End Try
    End Sub

  2. #2
    Frenzied Member
    Join Date
    Feb 2003
    Posts
    1,807

    Re: DataAdapter thinks everything is NULL

    After glancing at your code, I see it looks pretty clean, however you used a GoTo statement where it looks like an If/EndIf block could be used. I strongly recommend using modern structured programming techniques for control flow unless you absolutely have no alternative. Also ,the error message you posted implies the controls being "null" isn't the issue. It looks like there's a null data being returned by your data adapter. Could you post a working sample for people to test?

  3. #3

    Thread Starter
    Member _cerberus_'s Avatar
    Join Date
    Jun 2019
    Location
    Minnesota, USA
    Posts
    37

    Re: DataAdapter thinks everything is NULL

    Quote Originally Posted by Peter Swinkels View Post
    After glancing at your code, I see it looks pretty clean, however you used a GoTo statement where it looks like an If/EndIf block could be used. I strongly recommend using modern structured programming techniques for control flow unless you absolutely have no alternative. Also ,the error message you posted implies the controls being "null" isn't the issue. It looks like there's a null data being returned by your data adapter. Could you post a working sample for people to test?
    Peter,
    I'm not sure what the "modern structured programming techniques for control flow" would be for VB.net - I'm used to coding in VBA for Excel. I'm open to anything you have to offer as an example for what would be correct.

    Unfortunately, I cannot provide a working sample as it does contain some proprietary information that would be difficult to cut out.

    You are correct that the control being "null" is not the issue. I have "check" code that runs before the save to make sure certain controls have been populated - everything comes out clean. I have no idea why the data adapter would be returning any null values if the control, data table, and binding source all have the correct information. It's almost like all the data is being lost between the BS.EndEdit and the DA.Update - or the DA is just not seeing the DT/BS correctly?

    I'm sure the issue is something simple I'm overlooking... it's always the simplest fix for the most complex problems.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: DataAdapter thinks everything is NULL

    So debug your code. That's why VS has a debugger. Place a breakpoint at the top of the relevant code and then step through it line by line, examining the state at each step to ensure that everything is what you expect it to be. If it's not then you'll be able to work out exactly what and where.
    I have no idea why the data adapter would be returning any null values
    That's a nonsensical statement. The data adapter is not returning any null values. The data adapter is getting null values from the DataTable. The DataTable is where all the data is stored so the DataTable is what you need to be looking at. One option, for debugging at least, is to call GetChanges on the DataTable, which will return a new DataTable containing only the changed rows. That will make it easier to examine just the rows that have changed and are being saved.

  5. #5
    Frenzied Member
    Join Date
    Feb 2003
    Posts
    1,807

    Re: DataAdapter thinks everything is NULL

    @_cerberus_: GoTo was already discouraged when vb6 came out. I learned to avoid it even as far back as Quick Basic. I suggest you browse the keyword listing for vb over at the MSDN, at: https://docs.microsoft.com/en-us/dot...ence/keywords/ - "Continue" for example, is a control flow statement specific to vb.net but probably not useful in your case.

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: DataAdapter thinks everything is NULL

    If you are doing this:
    vb.net Code:
    1. If x Then GoTo Label1
    2.  
    3.     '...
    4.  
    5. Label1:
    then you should be doing this instead:
    vb.net Code:
    1. If Not x Then
    2.     '...
    3. End If
    This garbage:
    vb.net Code:
    1. If blnNew Then If IsDuplicate() Then GoTo TheEnd
    should have been this in the first place:
    vb.net Code:
    1. If blnNew AndAlso IsDuplicate() Then GoTo TheEnd
    so you simply negate that expression and put the code the GoTo would skip into the If block.

  7. #7

    Thread Starter
    Member _cerberus_'s Avatar
    Join Date
    Jun 2019
    Location
    Minnesota, USA
    Posts
    37

    Re: DataAdapter thinks everything is NULL

    Quote Originally Posted by jmcilhinney View Post
    So debug your code. That's why VS has a debugger. Place a breakpoint at the top of the relevant code and then step through it line by line, examining the state at each step to ensure that everything is what you expect it to be. If it's not then you'll be able to work out exactly what and where.
    I did debug my code with breakpoints. In the Immediate window I ran CType(bs_Record.current, datarowview).Item("Room") and dt_Record.Rows.Item(772).item("Room") after the BindingSource.EndEdit and before the DataAdapter.Update - Each of those return the expect non-null values. It's only when the DA.Update happens that values become null. I will take your suggestion and call GetChanges on the DataTable to see what there is.

    That's a nonsensical statement. The data adapter is not returning any null values. The data adapter is getting null values from the DataTable. The DataTable is where all the data is stored so the DataTable is what you need to be looking at. One option, for debugging at least, is to call GetChanges on the DataTable, which will return a new DataTable containing only the changed rows. That will make it easier to examine just the rows that have changed and are being saved.
    I'm not going to argue semantics with you, but when I know the data table had data in it (from debugging before the update) and then the data adapter errors with null values, it is in a way returning null values. Just a difference of terminology I guess.

  8. #8

    Thread Starter
    Member _cerberus_'s Avatar
    Join Date
    Jun 2019
    Location
    Minnesota, USA
    Posts
    37

    Re: DataAdapter thinks everything is NULL

    Quote Originally Posted by jmcilhinney View Post
    If you are doing this:
    vb.net Code:
    1. If x Then GoTo Label1
    2.  
    3.     '...
    4.  
    5. Label1:
    then you should be doing this instead:
    vb.net Code:
    1. If Not x Then
    2.     '...
    3. End If
    This garbage:
    vb.net Code:
    1. If blnNew Then If IsDuplicate() Then GoTo TheEnd
    should have been this in the first place:
    vb.net Code:
    1. If blnNew AndAlso IsDuplicate() Then GoTo TheEnd
    so you simply negate that expression and put the code the GoTo would skip into the If block.
    Thank you for your suggestions. However, I'm not sure if it fully helps what I was trying to achieve, although I'm sure there is a better way then what I did it.
    Only if blnNew=True do I want to run IsDuplicate(), and regardless of whether either of those are True/False, I need to run the code after "TheEnd."
    I thought about putting in a Finally statement, but I don't want to run that if the IsComplete() comes back false.
    I think I might be stuck with using a label?
    vb.net Code:
    1. Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles BNavSaveItem.Click
    2.     Try
    3.         If Not IsComplete() Then Exit Sub
    4.         If blnNew AndAlso IsDuplicate() Then GoTo TheEnd:
    5.  
    6.         lblTSS.Text = "Saving..."
    7.         lblTSS.BackColor = Color.IndianRed
    8.         Application.DoEvents()
    9.  
    10.         Me.Validate()
    11.         bs_Record.EndEdit()
    12.         da_Record.Update(dt_Record)
    13.  
    14.         If blnNew Then bs_Record.Position = bs_Record.Find("ID_Lab_Asset", ID_New)
    15.  
    16. TheEnd:
    17.         IsDirty = False
    18.         blnEdit = False
    19.         blnNew = False
    20.         DisableControls()
    21.  
    22.         lblTSS.Text = "Done"
    23.         lblTSS.BackColor = Color.LightGreen
    24.  
    25.     Catch ex As Exception
    26.         CustExErrorMsg(Name, Reflection.MethodBase.GetCurrentMethod().Name, GetExceptionInfo(ex))
    27.     End Try
    28. End Sub

  9. #9
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: DataAdapter thinks everything is NULL

    Quote Originally Posted by _cerberus_ View Post
    Thank you for your suggestions. However, I'm not sure if it fully helps what I was trying to achieve, although I'm sure there is a better way then what I did it.
    Only if blnNew=True do I want to run IsDuplicate(), and regardless of whether either of those are True/False, I need to run the code after "TheEnd."
    I thought about putting in a Finally statement, but I don't want to run that if the IsComplete() comes back false.
    I think I might be stuck with using a label?
    vb.net Code:
    1. Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles BNavSaveItem.Click
    2.     Try
    3.         If Not IsComplete() Then Exit Sub
    4.         If blnNew AndAlso IsDuplicate() Then GoTo TheEnd:
    5.  
    6.         lblTSS.Text = "Saving..."
    7.         lblTSS.BackColor = Color.IndianRed
    8.         Application.DoEvents()
    9.  
    10.         Me.Validate()
    11.         bs_Record.EndEdit()
    12.         da_Record.Update(dt_Record)
    13.  
    14.         If blnNew Then bs_Record.Position = bs_Record.Find("ID_Lab_Asset", ID_New)
    15.  
    16. TheEnd:
    17.         IsDirty = False
    18.         blnEdit = False
    19.         blnNew = False
    20.         DisableControls()
    21.  
    22.         lblTSS.Text = "Done"
    23.         lblTSS.BackColor = Color.LightGreen
    24.  
    25.     Catch ex As Exception
    26.         CustExErrorMsg(Name, Reflection.MethodBase.GetCurrentMethod().Name, GetExceptionInfo(ex))
    27.     End Try
    28. End Sub
    1) No, it doesn't directly help the issue at hand, but it makes it easier for others to help
    2) That's why jmc suggested AndAlso ... the first part of hte value will be checked .. if it's true - and only if it's true - it will then run isDuplicate ... if blnNew is false, then it's skipped.
    3) IF you want something to always run, then it goes after hte block before it...
    Code:
    If something andAlso somethingElse then
      do this
      do that
    End If
    
    Do something to runs no matter hte results of the above block
    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  10. #10
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: DataAdapter thinks everything is NULL

    Code:
    Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles BNavSaveItem.Click
      if IsComplete() Then
        If Not (blnNew andAlso IsDuplicate()) then
            lblTSS.Text = "Saving..."
            lblTSS.BackColor = Color.IndianRed
            Application.DoEvents()
     
            Me.Validate()
            bs_Record.EndEdit()
    
    
            ' If you want a Try Catch, this would be the place for it... keep them as small as possible.
            da_Record.Update(dt_Record)
    
            If blnNew Then bs_Record.Position = bs_Record.Find("ID_Lab_Asset", ID_New)
    
        end If
    
        IsDirty = False
        blnEdit = False
        blnNew = False
        DisableControls()
    
        lblTSS.Text = "Done"
        lblTSS.BackColor = Color.LightGreen
    
    End Sub

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  11. #11

    Thread Starter
    Member _cerberus_'s Avatar
    Join Date
    Jun 2019
    Location
    Minnesota, USA
    Posts
    37

    Re: DataAdapter thinks everything is NULL

    Quote Originally Posted by jmcilhinney View Post
    One option, for debugging at least, is to call GetChanges on the DataTable, which will return a new DataTable containing only the changed rows. That will make it easier to examine just the rows that have changed and are being saved.
    JM- Thank you for this idea, I was finally able to solve the issue. By using Dim dt_test As DataTable = dt_Record.GetChanges(DataRowState.Added) I was able to determine TWO rows were getting added as new instead of one. The first one was getting added because I had "AddNewItem" on the Binding Navigator set to one of the buttons, but that button I already had set to a click event. This was causing it to double add rows. Once I set "AddNewItem" to "(none)" all the code worked just fine. Wish I would have seen that when I was comparing my two forms side-by-side.
    The statement below is true...
    ...The statement above is false.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width