When creating an if statement is it possible to simplify a line if you want to test for multiple possibilities?

Cynolycus 255 Reputation points
2023-02-28T13:48:51.55+00:00

I have a DataGridView for which I have created validating code and message boxes that work.

I don't know if it's possible but I was trying to make the code generic so that it can be used for multiple DataGridViews in the same application or copied to another application and used with few changes.

I'm referencing the column header text to avoid using column indexes as they are specific to location and Datagridview which would not be good for multiple uses.

What I think is a problem is that you repeat the same thing time after time and I believe that there must be a simplified way of doing this that I don't know about. I had considered an array but if there is already a way then why bother.

The specific line is where the same object or variable can have multiple different values and you end up writing it over and over again and you may need to do it more than once. eg. If x = "Frog" or X = "Snake" or X = "Bird" or X = "Horse" or X = "Dog" etc.

I would have thought there was another way like e.g. If X = (Frog,Snake,Bird,Horse,Dog)

The variable X isn't so bad and I think I have seen a way to do it with a variable but I'm using

"sender.Columns(i).HeaderText = "Lat Shift" Or" and this would become quite lengthy if you wanted to add several columns.

Is there a better way than this? Can you create a list with the same attribute, in this case columns that are numeric or columns that must have a value, and just reference it once?

For Each c As DataGridViewCell In sender.CurrentRow.Cells

            Dim i As Int16 = c.ColumnIndex
            AryMsg(i) = sender.Columns(i).HeaderText

            If IsDBNull(c.Value) Then
                'All columns that must contain text are added here by their column header with the appropriate message.
                If sender.Columns(i).HeaderText = "Map Name" Then
                    AryMsg(i) = AryMsg(i) & ": The Map must have a name."
                    'All columns that must contain numerical values are added here by their column header.
                ElseIf sender.Columns(i).HeaderText = "Lat Shift" Or sender.Columns(i).HeaderText = "Lon Shift" Or sender.Columns(i).HeaderText = "Lat Multiplier" Or sender.Columns(i).HeaderText = "Lon Multiplier" Then
                    AryMsg(i) = AryMsg(i) & ": Cannot be blank."
                Else
                    'All other entries are allowed null values and will display the following message.
                    AryMsg(i) = AryMsg(i) & " is Blank."
                End If
            ElseIf Not IsNumeric(c.Value) Then
                'All columns that must contain text are added here by their column header.
                If sender.Columns(i).HeaderText = "Map Name" Then
                    AryMsg(i) = AryMsg(i) & " is """ & (c.Value) & """."
                    'All columns that must contain numerical values are added here in case the cell contains text.
                ElseIf sender.Columns(i).HeaderText = "Lat Shift" Or sender.Columns(i).HeaderText = "Lon Shift" Or sender.Columns(i).HeaderText = "Lat Multiplier" Or sender.Columns(i).HeaderText = "Lon Multiplier" Then
                    AryMsg(i) = AryMsg(i) & ": Must be a number."
                End If
            ElseIf IsNumeric(c.Value) Then
                AryMsg(i) = AryMsg(i) & " is """ & (c.Value) & """."
            End If

            If Not IsDBNull(c.Value) Then
                IntColCountDn -= 1
            End If
        Next
VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,568 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. LesHay 7,126 Reputation points
    2023-02-28T15:30:02.2033333+00:00

    Hi

    I do not understand your question, but you mention multiple DataGridViews (hopefully you have datasources as datatables?)

    Anyway, here is a stand alone example that will allow differentiation between various DataGridViews, and based on user selection, displays a Label with identity info on User selection.

    There may be a need (not shown here) to cycle through cells in a row, or columns in a DGV etc and that is quite simple. Combined with the code shown here, you could deal with any DGV in the same way (you are right in using column names rather than indexes - a necessity with multiple possible varieties being used)

    ' Form1 with
    ' DGV1, DGV2, DGV3 And DGV4 (all blank)
    ' and a Label1
    Public Class Form1
      Dim dt1, dt2, dt3, dt4 As New DataTable
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        With dt1
          .Columns.Add("Col1-1", GetType(String))
          .Columns.Add("Col2-1", GetType(String))
          .Columns.Add("Col3-1", GetType(String))
        End With
        dt2 = dt1.Clone
        dt3 = dt1.Clone
        dt4 = dt1.Clone
    
        dt1.Rows.Add("1-111", "1-222", "1 - 333")
        dt2.Rows.Add("2-111", "2-222", "2 - 333")
        dt3.Rows.Add("3-111", "3-222", "3 - 333")
        dt4.Rows.Add("4-111", "4-222", "4 - 333")
    
        DGV1.DataSource = dt1
        DGV2.DataSource = dt2
        DGV3.DataSource = dt3
        DGV4.DataSource = dt4
      End Sub
      Private Sub DGV1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGV1.CellClick, DGV2.CellClick, DGV3.CellClick, DGV4.CellClick
        Dim DGV As DataGridView = DirectCast(sender, DataGridView)
    
    
        Label1.Text = DGV.Name & "  Column " & e.ColumnIndex.ToString & "  Row " & e.RowIndex.ToString & "  value = " & DGV(e.ColumnIndex, e.RowIndex).Value.ToString
    
    
      End Sub
    End Class
    

  2. Cynolycus 255 Reputation points
    2023-03-01T13:31:23.0466667+00:00

    I found a way of doing what I wanted, I don't know if it's the best way but it works. It eliminates the repeated text in the code but more importantly it makes it easier to adapt for other uses. I think I may have strayed from the original project idea and started experimenting just to see what can be done.

    All possibilities are added to the array and are then not needed for the rest of the code. I have four such arrays used to store headers for Numeric Nulls allowed, Numeric no Nulls, Strings no Nulls and Strings that can be null. I currently only use two, the others were only to prove the concept. I don't know what effect searching the arrays will have with regards to the efficency of the code.

    Public Class Form2
    
    'Create an array containing the headers of all Numeric columns that must NOT be NULL
    Dim ArryNumericColsNotNull As Array = {"Map ID", "Lat Shift", "Lon Shift", "Lat Multiplier", "Lon Multiplier"}
    

    I used a variable to store the type of information in the column. Numeric, No Nulls allowed. If I need to I can then use the text of the string, or string within a string, "NumericNotNull" for other uses. At this time I have no idea what I would use it for but it's there if I need it.

    " For Each c As DataGridViewCell In sender.CurrentRow.Cells
    
        Dim StrColHeader As String = ""
        For index = 0 To ArryNumericColsNotNull.GetUpperBound(0)
            If sender.Columns(i).HeaderText = ArryNumericColsNotNull(index).ToString Then
                StrColHeader = "NumericNotNull"
            End If
        Next
    

    I will add my validation code in these areas.

       If StrColHeader = "NumericNotNull" Then
          e.Cancel = True
          AryMsg(i) = AryMsg(i) & ": Must be a number."
       End If
    

    Using this idea I have cut the code to around 1/2 of it's original size because I have been able to either eliminate some code or include it here with less code.

    Unless there is a better way I think I will stick with this and see how it goes.

    0 comments No comments