Как рассчитать в DataGridView право ряда ячеек быть ниже или выше некоторых пределов - PullRequest
0 голосов
/ 14 марта 2020

Я бы хотел посчитать приемлемость некоторых размеров продукта. четвертый столбец DataGridView заполняется значениями «Подходит» или «Не подходит» в зависимости от значений (длины, ширины и высоты), выраженных в столбцах 1, 2, 3 той же строки.

Во-первых, я читаю данные из файла CSV и заполняю DGV:

Public Class Form1
Dim OpenFileDialog1 = New OpenFileDialog
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim fname As String = ""
    OpenFileDialog1.InitialDirectory = "c:\desktop"
    OpenFileDialog1.Filter = "CSV files(*.csv)|*.csv"
    OpenFileDialog1.FilterIndex = 2
    OpenFileDialog1.RestoreDirectory = True
    If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
        fname = OpenFileDialog1.FileName
    End If
    txtpathfile.Text = fname
    Dim TextLine As String = ""
    Dim SplitLine() As String


    If System.IO.File.Exists(fname) = True Then                         'CARICA CSV
        Dim objReader As New System.IO.StreamReader(txtpathfile.Text, Encoding.ASCII)
        Do While objReader.Peek() <> -1
            TextLine = objReader.ReadLine()
            SplitLine = Split(TextLine, ";")
            Me.DataGridView1.Rows.Add(SplitLine)
        Loop
    Else
        MsgBox("File Does Not Exist")
    End If


End Sub

Затем я хочу рассчитать соответствие размеров всех продуктов, чтобы они были меньше или равны 600 (длина ), 400 (ширина) и 600 (высота).

Пример: у меня есть продукт (строка) с длиной = 600, шириной = 300 и высотой = 400. Результат будет отображаться в четвертом столбце из той же строки "Подходит". Это должно быть сделано для всех продуктов, отображаемых в DGV.

Я попытался выполнить цикл всех ячеек, но мне это не удалось. Сейчас я пытаюсь вычислить хотя бы выбранную строку, но она не работает.

Кто-то может мне помочь ?

Вот я:

   Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

    Dim c1 As Integer
    Dim c2 As Integer
    Dim c3 As Integer
    Dim c4 As String


    c1 = DataGridView1.CurrentRow.Cells(1).Value
    c2 = DataGridView1.CurrentRow.Cells(2).Value
    c3 = DataGridView1.CurrentRow.Cells(3).Value
    c4 = DataGridView1.CurrentRow.Cells(4).Value

    **'controll null or empty values**
    If String.IsNullOrEmpty(c1) OrElse String.IsNullOrEmpty(c2) OrElse String.IsNullOrEmpty(c3) Then Exit Sub
    If Not IsNumeric(c1) OrElse Not IsNumeric(c2) OrElse Not IsNumeric(c3) Then Exit Sub

    **'control dimensions**
    If c1 <= 800 And c2 <= 600 And c3 <= 600 Then
        c4 = "Suitable"
    End If

End Sub

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Используйте выражение столбца данных, чтобы упростить свою жизнь. Здесь мы также используем TextFieldParser для чтения CSV:

Public Class Form1
    Dim ofd = New OpenFileDialog

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim ofd = New OpenFileDialog


        ofd.InitialDirectory = "c:\desktop"
        ofd.Filter = "CSV files(*.csv)|*.csv"
        If (ofd.ShowDialog() <> Windows.Forms.DialogResult.OK) Then
            Return
        End If


        Using csv As New Microsoft.VisualBasic.FileIO.TextFieldParser(ofd.FileName)
            csv.TextFieldType = FileIO.FieldType.Delimited
            csv.SetDelimiters(",")

            Dim dt As New DataTable()

            'Change the order of these so it is correct
            dt.Columns.Add("Width", GetType(Int32))
            dt.Columns.Add("Height", GetType(Int32))
            dt.Columns.Add("Length", GetType(Int32))

            Dim sdc = dt.Columns.Add("Suitability")
            sdc.Expression = "IIF([Width] <= 800 And [Height] <= 600 And [Length] <= 600, 'Suitable' ,'Unsuitable')"

            Dim line = 0
            While Not csv.EndOfData
                Try
                    line += 1
                    Dim fields = csv.ReadFields()
                    Dim ro = dt.NewRow()
                    ro(0) = Convert.ToInt32(fields(0))
                    ro(1) = Convert.ToInt32(fields(1))
                    ro(2) = Convert.ToInt32(fields(2))
                    dt.Rows.Add(ro)
                Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                    MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
                Catch ex as FormatException
                    MsgBox("Some bad data could not be converted to integer, near line " & line & " and it will be skipped")
                End Try
            End While

            DataGridView1.DataSource = dt
        End Using
  End Sub

Вот его основные особенности:

  • Используйте TextFieldParser для чтения вашего CSV, а не для прокрутки собственного
  • Используйте таблицу данных, а не помещайте значения в таблицу данных напрямую
  • Создайте столбцы как тип INTEGER в таблице данных
  • Вы можете использовать EXPRESSION столбца данных для вычисления пригодности - он будет автоматически установить значение столбца с данными на основе значений в других столбцах.
  • Вы даже можете обновить вид сетки, введя его, и последний столбец автоматически изменится с Подходящий / Неподходящий в зависимости от

Учтите также, что ширина / высота / длина являются относительно относительными (если только пакет ДОЛЖЕН быть определенным образом выше), поэтому кажется жестоким отклонять пакет, который был введен как 600x600x800, при его переворачивании означает, что он будет 800x600x600 и, следовательно, приемлемым, поэтому рассмотрите СОРТИРОВКУ размеров, прежде чем назначить их, чтобы наибольшее измерение было в первом столбце:

        While Not csv.EndOfData
            Try
                Dim fields = csv.ReadFields()

                Dim sizes(2) as Integer
                For i as Integer = 0 to 2 
                  sizes(i) = Convert.ToInt32(fields(i))
                Next i
                Array.Sort(sizes)

                Dim ro = dt.NewRow()
                ro(0) = sizes(2) 'the largest after sorting
                ro(1) = sizes(1)
                ro(2) = sizes(0)
                dt.Rows.Add(ro)

            Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
            End Try
        End While

Другие пункты:

  • Я точно не знаю, какой столбец в вашем CSV - ширина / высота / длина, но, возможно, это не так
  • Пожалуйста, переименуйте ваши компоненты после того, как вы поместите их в форму. Нет ничего сложнее, чем попытаться помочь человеку, написавшему большую форму с 50 надписями, 50 текстовыми полями и 20 кнопками, которые называются Label1..50, TextBox1..50 et c. Переименование занимает секунды и делает ваш код понятным!
0 голосов
/ 14 марта 2020

Что ж, вы можете заставить DGV установить для вас значения четвертого столбца, обработав событие DataGridView.CellFormatting , поэтому вам не нужно делать это вручную, нажав эту кнопку.

Предполагая, что индексы столбцов Length, Width и Height равны 0, 1, 2 соответственно, и нам нужно установить значения индекса 3.

'...
'Declare variables for the max values allowed...
Private ReadOnly MaxLength As Integer = 600
Private ReadOnly MaxWidth As Integer = 400
Private ReadOnly MaxHeight As Integer = 600
'...

Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
    Dim s = DirectCast(sender, DataGridView)
    Dim length, width, height As Integer

    If e.RowIndex > -1 AndAlso
        Not Enumerable.Range(0, 2).Any(Function(i) s(i, e.RowIndex).Value Is Nothing) AndAlso
        Integer.TryParse(s(0, e.RowIndex).Value.ToString, length) AndAlso
        Integer.TryParse(s(1, e.RowIndex).Value.ToString, width) AndAlso
        Integer.TryParse(s(2, e.RowIndex).Value.ToString, height) Then
        s(3, e.RowIndex).Value = If(length <= MaxLength AndAlso width <= MaxWidth AndAlso height <= MaxHeight,
                "Suitable", "Unsuitable")
    End If

End Sub

Это все это.

Однако, и по любым неизвестным причинам вам нужно сделать это вручную нажатием кнопки, затем вам нужно обработать событие Click следующим образом:

Dim dgv = DataGridView1
Dim length, width, height As Integer

For Each r In dgv.Rows.Cast(Of DataGridViewRow).
Where(Function(x) Not Enumerable.Range(0, 2).Any(Function(i) x.Cells(i).Value Is Nothing))

    If Integer.TryParse(r.Cells(0).Value.ToString, length) AndAlso
    Integer.TryParse(r.Cells(1).Value.ToString, width) AndAlso
    Integer.TryParse(r.Cells(2).Value.ToString, height) Then
        r.Cells(3).Value = If(length <= MaxLength AndAlso width <= MaxWidth AndAlso height <= MaxHeight,
            "Suitable", "Unsuitable")
    End If
Next
...