First I'm going to try to explain my problem.

I have two tables in a SQLEXPRESS database, a company table (opdg) and a contacts table (opdg_cp) which is holding the contacts for a company by company Id (opdg_Id). BTW Id in the company table is the primary key and is Identity, increment 1.

To keep it simple:

Company DataBase

Id Name

1 HillWood

2 Fergusson

3 van Dyke


Contacts Database

Id Lastname opdg_Id

1 Dewalt 1

2 Johnson 1

3 Henderson 3

4 Anderson 2

5 Eastwood 2

So 2 contacts belong to Fergusson, 2 to Hillwood and 1 to van Dyke

I created two datagridviews on one form. On holding the Companies and on holding the contacts. Both datagridviews are able to update, add, and insert records. What I'm trying to do is:

If I walk through the company database in the first datagridview, the second datagridview should show me the contacts for that company because of the opdg_Id cell in the contacts table. Well, I did that, it works well. I will include all code below.

But, I get a problem when I'm scrolling down in the company datagridview and I hit the CurrentRow.IsNewRow event to add a new record. Because at that point there is just at that particular moment no known value in the Id cell of the company table, it's still NULL. At that point I'm using the



datagridview_CurrentCellChanged event to search for matching contacts by C_Id, but the Id cell is NULL so I get an error.

Below the Code. BTW for opening, closing the database I use a separate Class, which I also include below.

This is the Class I'm using:

Imports System.Data.SqlClient

Public Class SQLControl
Dim HostIP = My.Settings.HostIP
Dim DataBase = My.Settings.Database
Dim User = My.Settings.User
Dim Password = My.Settings.Password

' CONNECTION
Public SQLCon As New SqlConnection With {.ConnectionString = "server=" & HostIP & ";User=" & User & ";Pwd=" & Password & ";Database=" & DataBase}
Public SQLCmd As New SqlCommand

Public Function HasConnection() As Boolean
Try
SQLCon.Open()

SQLCon.Close()
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
End Try

End Function

' SQL DATA
Public SQLDA As SqlDataAdapter
Public SQLDS As DataSet

' QUERY PARAMETERS
Public Params As New List(Of SqlParameter)

' QUERY STATISTICS
Public RecordCount As Integer
Public Exception As String


Public Sub ExecQuery(Query As String)
Try
SQLCon.Open()

' CREATE SQL COMMAND
SQLCmd = New SqlCommand(Query, SQLCon)

' LOAD PARAMETERS INTO SQL COMMAND
Params.ForEach(Sub(x) SQLCmd.Parameters.Add(x))

' CLEAR PARAMETER LIST
Params.Clear()

' CREATE NEW DATASET AND DATAADAPTER
SQLDS = New DataSet
SQLDA = New SqlDataAdapter(SQLCmd)
RecordCount = SQLDA.Fill(SQLDS)

SQLCon.Close()

Catch ex As Exception
Exception = ex.Message
End Try

If SQLCon.State = ConnectionState.Open Then SQLCon.Close()
End Sub

End Class

Below the code for the Windows form, I deleted as much as code to keep it clear, and the BOLD part is my problem. BTW I'm from Holland, so I'm trying to explain my problem in English as good as I can.


Imports System.Data.Sql
Imports System.Data.SqlClient

Public Class Opdrachtgevers
' TWO NEW INSTANCES FROM SQLCONTROL CLASS
Private SQL As New SQLControl
Private SQL1 As New SQLControl
Public search As String
' WHEN FORM IS LOADED
Private Sub Opdrachtgevers_Load(sender As Object, e As EventArgs) Handles MyBase.Load

' EXECUTE QUERY AND POPULATE GRID, (FIRST DATAGRIDVIEW, COMPANY)
SQL.ExecQuery("select * from opdg")

' CALL LOADGRID_OPDG SUBROUTINE (First DataGridView, COMPANY)
LoadGrid_opdg()

' DISABLE SAVE BUTTON
btn_Opslaan_Opdg.Enabled = False

End Sub

' LOADGRID_OPDG SUBROUTINE
Private Sub LoadGrid_opdg()

' IF DATA IS RETURNED, POPULATE GRID & BUILD UPDATE COMMAND
If SQL.RecordCount > 0 Then
Opdg_Grid_View.DataSource = SQL.SQLDS.Tables(0)
Opdg_Grid_View.Rows(0).Selected = True
Opdg_Grid_View.Columns("id").Visible = False
SQL.SQLDA.UpdateCommand = New SqlCommandBuilder(SQL.SQLDA).GetUpdateCommand
End If
End Sub

Private Sub opdg_grid_view_CurrentCellChanged(sender As Object, e As EventArgs) Handles Opdg_Grid_View.CurrentCellChanged

If Opdg_Grid_View.CurrentCellAddress.X < 0 Or Opdg_Grid_View.CurrentCellAddress.Y < 0 Then Exit Sub
If Opdg_Grid_View.CurrentRow.IsNewRow Then

' THIS IS WHERE I HAVE A PROBLEM. IF A NEW ROW IS DETECTED AND THERE

' IS A NULL VALUE IN THE ID CELL, I CAN'T SEARCH THE CONTACTS TABLE,

' BECAUSE, THIS IS A NEW COMPANY RECORD, AND NOT SAVED

' BUT INSTEAD OF THAT, AFTER FILLING IN THE COMPANY'S RECORD,

' IT SHOULD BE POSSIBLE TO GO TO THE SECOND DATAGRIDVIEW TO FILL

' IN THE FIRST NEW CONTACT FOR THAT COMPANY.
Else
' GET THE COMPANY'S ID
search = Opdg_Grid_View.CurrentRow.Cells("id").Value

'SEARCH FOR THE COMPANY'S CONTACT
SQL1.ExecQuery("select * from opdg_cp where opdg_id =" & search)

' LOAD THE CONTACTS DATAGRIDVIEW
LoadGrid_opdg_cp()
End If
Exit Sub
End Sub
Private Sub LoadGrid_opdg_cp()


' IF DATA IS RETURNED, POPULATE GRID & BUILD UPDATE COMMAND
If SQL1.RecordCount > 0 Then

Opdg_Cp_Grid_View.DataSource = SQL1.SQLDS.Tables(0)
Opdg_Cp_Grid_View.Rows(0).Selected = True
Opdg_Cp_Grid_View.Columns("id").Visible = False
Opdg_Cp_Grid_View.Columns("opdg_id").Visible = False

SQL1.SQLDA.UpdateCommand = New SqlCommandBuilder(SQL1.SQLDA).GetUpdateCommand
Else
Call CType(Opdg_Cp_Grid_View.DataSource, DataTable).Rows.Clear()
End If
End Sub

Private Sub opdg_cp_grid_view_CurrentCellChanged(sender As Object, e As EventArgs) Handles Opdg_Cp_Grid_View.CurrentCellChanged

If Opdg_Cp_Grid_View.CurrentCellAddress.X < 0 Or Opdg_Grid_View.CurrentCellAddress.Y < 0 Then Exit Sub
If Opdg_Cp_Grid_View.CurrentRow.IsNewRow Then

Else
Dim search = Opdg_Cp_Grid_View.CurrentRow.Cells("id").Value
SQL1.ExecQuery("select * from opdg_cp where opdg_id =" & search)
LoadGrid_opdg_cp()
End If
Exit Sub
End Sub


Private Sub btn_Opslaan_Opdg_Click(sender As Object, e As EventArgs) Handles btn_Opslaan_Opdg.Click
' SAVE UPDATES TO THE DATABASE
SQL.SQLDA.Update(SQL.SQLDS) ' TO DO : ERROR CHECKING, DATA VALIDATION

' REFRESH GRID DATA
LoadGrid_opdg()

' DISABLE SAVE BUTTON
btn_Opslaan_Opdg.Enabled = False
MsgBox("Gegevens zijn opgeslagen")

End Sub

Private Sub Opdg_Grid_View1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles Opdg_Grid_View.CellValueChanged
btn_Opslaan_Opdg.Enabled = True
End Sub

Private Sub Opdg_Grid_View1_RowsRemoved(sender As Object, e As DataGridViewRowsRemovedEventArgs) Handles Opdg_Grid_View.RowsRemoved
btn_Opslaan_Opdg.Enabled = True
End Sub

Private Sub Opdrachtgevers_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
If Me.WindowState = FormWindowState.Normal Then
My.Settings.Opdg_Location = Me.Location
My.Settings.Opdg_Size = Me.Size
End If
My.Settings.Opdg_Ws = Me.WindowState
My.Settings.Save()
End Sub

Private Sub btn_Zoek_Opdg_Click(sender As Object, e As EventArgs) Handles btn_Zoek_Opdg.Click
SQL.ExecQuery("select * from opdg where Bedrijfsnaam like '" & txt_Zoek_Opdg.Text & "%'")

LoadGrid_opdg()

End Sub

Private Sub Btn_Opslaan_Opdg_Cp_Click(sender As Object, e As EventArgs) Handles Btn_Opslaan_Opdg_Cp.Click


Opdg_Cp_Grid_View.CurrentRow.Cells(0).Value = search


SQL1.SQLDA.Update(SQL1.SQLDS)
MsgBox("Gegevens zijn opgeslagen")
End Sub
End Class



So, this is it. In short:

If a new company is added, don't search for the contact, but it should be able to add that contact directly after the company's record is filled in in the first datagridview.

Many thanks for everybody who takes some time to look at this problem.

regards,

Mark Hofland