windows forms startup issue

ud2008

Well-known member
Joined
Jul 5, 2010
Messages
148
Programming Experience
Beginner
Hi there,

I'm having an issue with the startup of my build app with vb2010.

Let me explain what the situation is at the moment.

I have a form and a splashscreen. I use the application events (startup event) to check if there is a network connection, if so the splashscreen will run and it will check if the database is available, if this is the case, it will copy the online database to the local ms access database.
If the startup check of the network is false, it the user gets a message that there isn't any network available and the program will try to run normal, then when the user clicks the ok button of that message, it will check if the local database has any records. If so the splashscreen will run and the program starts normal (without copy the database, because there isn't any network available).

The issue that I am having is, that when there isn't a network connection and the local database is empty, (I do get the message that the local database is empty), but the program still runs, while it should exit.

Here is the code of the application event:
VB.NET:
Protected Overrides Function OnInitialize(commandLineArgs As System.Collections.ObjectModel.ReadOnlyCollection(Of String)) As Boolean
            Me.MinimumSplashScreenDisplayTime = 5000
            Return MyBase.OnInitialize(commandLineArgs)
        End Function

        Private Sub MyApplication_Startup(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Dim topmessage As New TopMostMessage
            Dim result As DialogResult
            Dim sql As String
            Dim ds As New DataSet
            Dim oledbAdapter As OleDbDataAdapter
            Dim connetionString As String
            Dim connection As OleDbConnection
            If My.Computer.Network.IsAvailable Then
                Dim splash As SplashScreen1 = CType(My.Application.SplashScreen, SplashScreen1)
            Else
                result = topmessage.Show("There is no internet connection available!" & vbNewLine & _
                                        "Songlist Editor 2 will try to run normal!", _
                                        "Songlist Editor 2", MessageBoxButtons.OK, MessageBoxIcon.Warning)
                If result = DialogResult.OK Then
                    connetionString = "Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess
                    sql = "SELECT * FROM songs"
                    connection = New OleDbConnection(connetionString)
                    Try
                        connection.Open()
                        oledbAdapter = New OleDbDataAdapter(sql, connection)
                        oledbAdapter.Fill(ds, "songs")
                        oledbAdapter.Dispose()
                        connection.Close()
                        If ds.Tables(0).Rows.Count > 0 Then
                            'Do nothing
                        Else
                            result = topmessage.Show("Host is not available!" & vbNewLine & _
                                            "Songlist Editor 2 cannot use the local database and will exit!" & vbNewLine & _
                                            "Make sure you have an active internet connection and try again later", _
                                            "Songlist Editor", MessageBoxButtons.OK, MessageBoxIcon.Warning)
                            If result = DialogResult.OK Then
                                e.Cancel = False
                            End If
                        End If
                    Catch ex As Exception
                        MsgBox("Can not open connection ! ")
                    End Try
                End If
            End If
        End Sub

And the splashscreen:
VB.NET:
Sub New()
        InitializeComponent()
    End Sub

    Public Overrides Sub ProcessCommand(ByVal cmd As System.Enum, ByVal arg As Object)
        MyBase.ProcessCommand(cmd, arg)
    End Sub

    Public Enum SplashScreenCommand
        SomeCommandId
    End Enum

Private Sub SplashScreen1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If DataBase.DBConnectionStatus = True Then
            'copy database from online to local
            'dbc.CopyDatabase()
            Dim dt As New DataSet()
            Try
                'Get Data into DataTable from MySQL Server database    
                Using cnn As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw)
                    Dim cmdSelect As MySqlCommand = New MySqlCommand("Select * From songs")
                    cmdSelect.Connection = cnn
                    Dim ad As New MySqlDataAdapter(cmdSelect)
                    ad.AcceptChangesDuringFill = False
                    ad.Fill(dt)
                End Using
                Try

                    DeleteRecords()
                    Try
                        'Insert Data from DataTable into Access database  
                        Using cnn As New OleDbConnection("Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess)
                            Dim cmdSelect As OleDbCommand = New OleDbCommand("Select * From songs")
                            cmdSelect.Connection = cnn
                            Dim ad As New OleDbDataAdapter(cmdSelect)
                            Dim cmdBuilder As New OleDbCommandBuilder(ad)
                            Dim cmd As OleDbCommand = cmdBuilder.GetInsertCommand()
                            cmd.Connection = cnn
                            For Each row As DataRow In dt.Tables(0).Rows
                                ad.InsertCommand = cmd
                            Next
                            ad.Update(dt)
                        End Using
                    Catch ex3 As Exception
                        MessageBox.Show(ex3.Message)
                    End Try
                Catch ex2 As Exception
                    MessageBox.Show(ex2.Message)
                End Try
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        Else
            Application.Exit()
        End If
        version.Text = System.String.Format(version.Text, My.Application.Info.Version.Major, My.Application.Info.Version.Minor, My.Application.Info.Version.Build, My.Application.Info.Version.Revision)
    End Sub

    Public Sub DeleteRecords()
        MScmd.Connection = MScon
        MScmd.CommandType = CommandType.Text
        MScmd.CommandText = "DELETE FROM songs"
        Using MScon
            MScon.Open()
            MScmd.ExecuteNonQuery()
        End Using
    End Sub

The "DBConnectionStatus" is a function in a class:
VB.NET:
Public Shared Function DBConnectionStatus() As Boolean
        Try
            Using sqlConn As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw)
                sqlConn.Open()
                Return (sqlConn.State = ConnectionState.Open)
            End Using
        Catch e1 As MySqlException
            Return False
        Catch e2 As Exception
            Return False
        End Try
    End Function

I hope someone can help me with this.

If I need to clarify something, please let me know.

Thanks in advanced.
 
I do have a question (which is related to the main question).

With the splashscreen.onload I copy a online database to the local database. At this point I copy only one table, but what if I want to copy 3 tables in total, do I need to multiply the try catch part 3 times, or is there another way to do this?

Thanks.
 
I do have a question (which is related to the main question).

With the splashscreen.onload I copy a online database to the local database. At this point I copy only one table, but what if I want to copy 3 tables in total, do I need to multiply the try catch part 3 times, or is there another way to do this?

Thanks.

It depends on the circumstances. If you want to treat the whole lot as a single block and treat an exception thrown in any part of it the same way then you'd just use a single exception handler while if you want to treat each section separately then you would use separate exception handlers. The question you should ask yourself is pretty simple: if all three tables fail to be copied, how many error messages do you want to see? If it's one then you obviously want one exception handler. If it's three then you obviously want separate exception handlers. It also depends on what exception(s) you're catching. Maybe you want an exception handler around the whole lot to catch a connection error but you want an exception handler around each part to catch an exception specific to that part. It really depends on how YOU want YOUR APP to behave, so that's what YOU need to think about.
 
I have the following code:
VB.NET:
If DataBase.DBConnectionStatus = True Then
            'copy database from online to local
            'dbc.CopyDatabase()
            Dim dt As New DataSet()
            Dim dt2 As New DataSet()
            Dim dt3 As New DataSet()
            Dim dt4 As New DataSet()
            Try
                'Get Data into Songs DataTable from MySQL Server database    
                Using cnn As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw)
                    Dim cmdSelect As MySqlCommand = New MySqlCommand("Select * From songs")
                    cmdSelect.Connection = cnn
                    cnn.Open()
                    Dim ad As New MySqlDataAdapter(cmdSelect)
                    ad.AcceptChangesDuringFill = False
                    ad.Fill(dt)
                End Using
                'Get Data into Email DataTable from MySQL Server database
                Using cnn As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw)
                    Dim cmdSelect2 As MySqlCommand = New MySqlCommand("Select * From email")
                    cmdSelect2.Connection = cnn
                    cnn.Open()
                    Dim ad2 As New MySqlDataAdapter(cmdSelect2)
                    ad2.AcceptChangesDuringFill = False
                    ad2.Fill(dt2)
                End Using
                'Get Data into Audio DataTable from MySQL Server database
                Using cnn As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw)
                    Dim cmdSelect3 As MySqlCommand = New MySqlCommand("Select * From Audio")
                    cmdSelect3.Connection = cnn
                    cnn.Open()
                    Dim ad3 As New MySqlDataAdapter(cmdSelect3)
                    ad3.AcceptChangesDuringFill = False
                    ad3.Fill(dt3)
                End Using
                'Get Data into Scores DataTable from MySQL Server database
                Using cnn As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw)
                    Dim cmdSelect4 As MySqlCommand = New MySqlCommand("Select * From scores")
                    cmdSelect4.Connection = cnn
                    cnn.Open()
                    Dim ad4 As New MySqlDataAdapter(cmdSelect4)
                    ad4.AcceptChangesDuringFill = False
                    ad4.Fill(dt4)
                End Using
                Try

                    DeleteRecords()
                    DeleteRecords2()
                    DeleteRecords3()
                    DeleteRecords4()
                    Try
                        'Insert Data from Songs DataTable into Access database  
                        Using con As New OleDbConnection("Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess)
                            Dim cmdSelect As OleDbCommand = New OleDbCommand("Select * From songs")
                            cmdSelect.Connection = con
                            con.Open()
                            Dim ad As New OleDbDataAdapter(cmdSelect)
                            Dim cmdBuilder As New OleDbCommandBuilder(ad)
                            Dim cmd As OleDbCommand = cmdBuilder.GetInsertCommand()
                            cmd.Connection = con
                            For Each row As DataRow In dt.Tables(0).Rows
                                ad.InsertCommand = cmd
                            Next
                            ad.Update(dt)
                        End Using
                        'Insert Data from Email DataTable into Access database  
                        Using con As New OleDbConnection("Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess)
                            Dim cmdSelect2 As OleDbCommand = New OleDbCommand("Select * From email")
                            cmdSelect2.Connection = con
                            con.Open()
                            Dim ad2 As New OleDbDataAdapter(cmdSelect2)
                            Dim cmdBuilder2 As New OleDbCommandBuilder(ad2)
                            Dim cmd2 As OleDbCommand = cmdBuilder2.GetInsertCommand()
                            cmd2.Connection = con
                            For Each row As DataRow In dt2.Tables(0).Rows
                                ad2.InsertCommand = cmd2
                            Next
                            ad2.Update(dt2)
                        End Using
                        'Insert Data from Audio DataTable into Access database  
                        Using con As New OleDbConnection("Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess)
                            Dim cmdSelect3 As OleDbCommand = New OleDbCommand("Select * From Audio")
                            cmdSelect3.Connection = con
                            con.Open()
                            Dim ad3 As New OleDbDataAdapter(cmdSelect3)
                            Dim cmdBuilder3 As New OleDbCommandBuilder(ad3)
                            Dim cmd3 As OleDbCommand = cmdBuilder3.GetInsertCommand()
                            cmd3.Connection = con
                            For Each row As DataRow In dt3.Tables(0).Rows
                                ad3.InsertCommand = cmd3
                            Next
                            ad3.Update(dt3)
                        End Using
                        'Insert Data from Audio DataTable into Access database  
                        Using con As New OleDbConnection("Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess)
                            Dim cmdSelect4 As OleDbCommand = New OleDbCommand("Select * From scores")
                            cmdSelect4.Connection = con
                            con.Open()
                            Dim ad4 As New OleDbDataAdapter(cmdSelect4)
                            Dim cmdBuilder4 As New OleDbCommandBuilder(ad4)
                            Dim cmd4 As OleDbCommand = cmdBuilder4.GetInsertCommand()
                            cmd4.Connection = con
                            For Each row As DataRow In dt4.Tables(0).Rows
                                ad4.InsertCommand = cmd4
                            Next
                            ad4.Update(dt4)
                        End Using
                    Catch ex3 As Exception
                        MessageBox.Show(ex3.Message)
                        Application.Exit()
                    End Try
                Catch ex2 As Exception
                    MessageBox.Show(ex2.Message)
                    Application.Exit()
                End Try
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                Application.Exit()
            End Try
        Else
            Application.Exit()
        End If

But I get this error:

The ConnectionString property has not been initialized

I've googled and it seems to have to do with the open connection, but I can't nail it.

Any idea?
 
You obviously haven't initialised a connection string somewhere, but that code is so much more complex than it needs to be, there's not much point trying to solve that issue until you've cleaned it up. Let's start at the top.

1. Why do you have four DataSets? The whole point of a DataSet is that it can contain multiple DataTables, just like a database can contain multiple tables. You should be either creating four discrete DataTables or else creating just one DataSet. The fact that you are using 'dt' for the variables rather than 'ds' indicates that you are thinking of them as DataTables rather than DataSets anyway.

2. Create one and only one connection for each database.

3. There's no need to create a command, set its Connection and then create a data adapter all separately. You can simply create the data adapter in one line by passing it the SQL query and the connection.

4. When saving the data, you don't need to get the command(s) from the command builder explicitly. You simply create the command builder and call Update on the data adapter. No looping through the DataTable.

Fix those issues to clean up your code and then, if there's still an error, it will be significantly easier to find.
 
Thanks for the comment, I've rewritten the code, but nothing is copied.

Can you take a look at the code and let me know if something seems wrong, because I don't get any error message.
VB.NET:
Private Sub SplashScreen1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If DataBase.DBConnectionStatus = True Then
            'copy database from online to local
            'dbc.CopyDatabase()
            Dim myconnetionString As String
            Dim myconnection As MySqlConnection
            Dim mycommand As MySqlCommand
            Dim myadapter As New MySqlDataAdapter
            Dim msconnetionString As String
            Dim msconnection As OleDbConnection
            Dim mscmdbuild As OleDbCommandBuilder
            Dim msadapter As New OleDbDataAdapter
            Dim ds As New DataSet
            Dim msds As New DataSet
            Dim firstSql As String
            Dim secondSql As String
            Dim thirdSql As String
            Dim fourthSql As String
            msconnetionString = "Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess
            myconnetionString = "Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw
            firstSql = "Select * From songs"
            secondSql = "Select * From email"
            thirdSql = "Select * From Audio"
            fourthSql = "Select * From scores"
            msconnection = New OleDbConnection(msconnetionString)
            myconnection = New MySqlConnection(myconnetionString)
            Try
                myconnection.Open()
                mycommand = New MySqlCommand(firstSql, myconnection)
                myadapter.SelectCommand = mycommand
                myadapter.Fill(ds, "songs")

                myadapter.SelectCommand.CommandText = secondSql
                myadapter.Fill(ds, "email")

                myadapter.SelectCommand.CommandText = thirdSql
                myadapter.Fill(ds, "Audio")

                myadapter.SelectCommand.CommandText = fourthSql
                myadapter.Fill(ds, "scores")

                myadapter.Dispose()
                mycommand.Dispose()
                myconnection.Close()

                ds.Tables(0).TableName = "songs"
                ds.Tables(1).TableName = "email"
                ds.Tables(2).TableName = "Audio"
                ds.Tables(3).TableName = "scores"

                msds.Tables.Add(ds.Tables(0).Copy)
                msds.Tables.Add(ds.Tables(1).Copy)
                msds.Tables.Add(ds.Tables(2).Copy)
                msds.Tables.Add(ds.Tables(3).Copy)

                msds.Tables(0).TableName = "songs"
                msds.Tables(1).TableName = "email"
                msds.Tables(2).TableName = "Audio"
                msds.Tables(3).TableName = "scores"

                msconnection.Open()
                msadapter = New OleDbDataAdapter(firstSql, msconnection)
                msadapter = New OleDbDataAdapter(secondSql, msconnection)
                msadapter = New OleDbDataAdapter(thirdSql, msconnection)
                msadapter = New OleDbDataAdapter(fourthSql, msconnection)
                mscmdbuild = New OleDbCommandBuilder(msadapter)
                msadapter.Fill(ds)
                msadapter.Update(ds.Tables(0))
                msadapter.Update(ds.Tables(1))
                msadapter.Update(ds.Tables(2))
                msadapter.Update(ds.Tables(3))
                msconnection.Close()
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
Else
            Application.Exit()
        End If
        version.Text = System.String.Format(version.Text, My.Application.Info.Version.Major, My.Application.Info.Version.Minor, My.Application.Info.Version.Build, My.Application.Info.Version.Revision)
    End Sub

Thanks,

BTW, happy new year to all!
 
guys, I can't seem to be able to store the records from all the tables in the dataset (added from the online database to the dataset) to the ms access database.

I don't know why, I have been trying to use the oledCommandBuilder, and use oleddataadapter.update to insert the records from the dataset into the ms access database, but somehow it won't work.

Can someone please help me to solve this one?
 
Copying records from one database to another is actually very easy, but there's one major gotcha for those not completely familiar with ADO.NET, e.g.
VB.NET:
Using sourceConnection As New SqlConnection("source connection string here"),
      destinationConnection As New OleDbConnection("destination connection string here"),
      sourceAdapter As New SqlDataAdapter("SELECT * FROM MyTable", sourceConnection),
      destinationAdapter As New OleDbDataAdapter,
      destinationCommand As New OleDbCommand("INSERT INTO MyTable (Column1, Column2) VALUES (@Column1, @Column2)", destinationConnection)
    destinationAdapter.InsertCommand = destinationCommand
    [B][U]destinationAdapter.AcceptChangesDuringFill = False[/U][/B]

    destinationCommand.Parameters.Add("@Column1", OleDbType.VarChar, 50, "Column1")
    destinationCommand.Parameters.Add("@Column2", OleDbType.VarChar, 50, "Column2")

    Dim table As New DataTable

    sourceAdapter.Fill(table)
    destinationAdapter.Update(table)
End Using
The highlighted line handles the gotcha I mentioned. When you add a new DataRow to a DataTable, as the Fill method does internally, it's RowState is set to Added. By default, the Fill method calls AcceptChanges on the DataTable after populating it. That sets the RowState of every DataRow to Unchanged. When calling Update, DataRows with a RowState of Unchanged are ignored. Rows with a RowState of Added are inserted using the adapter's InsertCommand, rows with a RowState of Modified are updated using the UpdateCommand and rows with a RowState of Deleted are deleted using the DeleteCommand. By setting AcceptChangesDuringFill to False you prevent the adapter calling AcceptChanges, which means that all rows retain their initial RowState of Added, ready to be inserted when you call Update.
 
Thanks I will try it.

Correct me if I am wrong, as I see it I need to repeat the destinationcommand line and the sourceadapter for each table?
 
You can use the same connection each time because it's the same database each time. You could use the same adapter and command each time and just change the SQL code and parameters but I would tend to use new ones each time.
 
I still try to get the first database to be copied, I try to use the code as followed, no error is shown, but the database remains empty
VB.NET:
Try
                Using sourceConnection As New MySqlConnection("Server=" + My.Settings.host + ";Database=" + My.Settings.database + ";Uid=" + My.Settings.username + ";Pwd=" + My.Settings.mysqlpw),
                    destinationConnection As New OleDbConnection("Provider=" + My.Settings.dbaccess + "Data Source = |DataDirectory|\" + My.Settings.msaccess),
                    sourceAdapter As New MySqlDataAdapter("SELECT * FROM songs", sourceConnection),
                    destinationAdapter As New OleDbDataAdapter,
                    destinationCommand As New OleDbCommand("INSERT INTO songs (Id, Songtitle, Genre, Songtext, Audio, Scores) VALUES (@Id, @Songtitle, @Genre, @Songtext, @Audio, @Scores)", destinationConnection)
                    destinationAdapter.InsertCommand = destinationCommand
                    destinationAdapter.AcceptChangesDuringFill = False

                    destinationCommand.Parameters.Add("@Id", OleDbType.Integer, 11, "Id")
                    destinationCommand.Parameters.Add("@Songtitle", OleDbType.VarChar, 200, "Songtitle")
                    destinationCommand.Parameters.Add("@Genre", OleDbType.VarChar, 200, "Genre")
                    destinationCommand.Parameters.Add("@Songtext", OleDbType.VarChar, 200, "Songtext")
                    destinationCommand.Parameters.Add("@Audio", OleDbType.VarChar, 200, "Audio")
                    destinationCommand.Parameters.Add("@Scores", OleDbType.VarChar, 200, "Scores")

                    Dim table As New DataTable

                    sourceAdapter.Fill(table)
                    destinationAdapter.Update(table)
                End Using
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try

Thanks again.
 
My first guess would be that you are looking in the wrong database. Check what value is returned by the Update call, which represents the number of records affected by the save. If that is not zero then the data is being saved and you are indeed looking in the wrong database. In that case, follow the first link in my signature to learn how to manage local data files.

Also, if you're not going to use a single String for your connection string then I would suggest using either String.Format or, better still, a ConnectionStringBuilder from the appropriate ADO.NET provider, e.g. MySqlConnectionStringBuilder. Both, but especially the second option, will reduce the chance of error an make your code more readable.

Finally, it is preferred to use & (the concatenation operator) to join Strings in VB rather than + (the addition operator).
 
Back
Top