Member 12712519 Ответов: 1

Как я могу динамически отображать несколько меток со значениями одна под другой без повторений?


Я пытаюсь создать приложение, которое ищет строку в определенном столбце файла excel, и если строка найдена, отобразите соответствующее значение столбца для Ex: скажем, я ищу строку в столбце файла excel "N", если строка, которую я ищу, найдена, то отобразите значение столбца "E"той же строки.Дело в том, что мой код отображает одно значение несколько раз в нескольких метках второй формы.

Что я уже пробовал:

Форма 1:

Imports Excel = Microsoft.Office.Interop.Excel
 Imports Microsoft.Office.Interop.Excel
 Imports System.Globalization
 Imports System.Runtime.InteropServices

 Public Class Form1
    Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim xlApp As Excel.Application
        Dim xlWorkBook As Excel.Workbook
        Dim xlWorkSheet As Excel.Worksheet
        Dim range As Excel.Range
        Dim Obj As Object
        Dim pass As String

        If OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
            Dim sr As New System.IO.StreamReader(OpenFileDialog1.FileName)
            MessageBox.Show("You have selected" + OpenFileDialog1.FileName)
            'sr.Close()
        End If

        xlApp = New Excel.Application
        xlWorkBook = xlApp.Workbooks.Open(OpenFileDialog1.FileName)
        xlWorkSheet = xlWorkBook.Worksheets("sheet1")

        range = xlWorkSheet.UsedRange
        For rCnt = 1 To range.Rows.Count
            For cCnt = 14 To range.Columns.Count
             If xlWorkSheet.Cells(rCnt, cCnt).value = "3" Or  xlWorkSheet.Cells(rCnt, cCnt).value = "4" Or xlWorkSheet.Cells(rCnt, cCnt).value = "5" Or xlWorkSheet.Cells(rCnt, cCnt).value = "6" Or xlWorkSheet.Cells(rCnt, cCnt).value = "7" Or xlWorkSheet.Cells(rCnt, cCnt).value = "8" Or xlWorkSheet.Cells(rCnt, cCnt).value = "9" Or xlWorkSheet.Cells(rCnt, cCnt).value = "10" Then

                    Obj = CType(range.Cells(rCnt, "E"), Excel.Range)
                    'MessageBox.Show(Obj.value)

                    Foo = Obj.value
                    Form2.Show()
                End If
            Next
        Next

        xlWorkBook.Close()
        xlApp.Quit()
        releaseObject(xlApp)
        releaseObject(xlWorkBook)
        releaseObject(xlWorkSheet)
    End Sub

    Private Sub releaseObject(ByVal obj As Object)
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub
End Class  



Формы Form2:

Imports System.Linq
Imports System.Drawing

Public Class Form2
    Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
        Dim label As New Label()
        Dim count As Integer = Panel1.Controls.OfType(Of Label)().ToList().Count

        label.Location = New Point(10, (25 * count))
        'label.Size = New Size(40, 20)
        label.Name = "label_" & (count + 1)
        label.Text = Foo '& (count + 1)
        label.AutoSize = True
        Panel1.Controls.Add(label)

        Dim button As New Button()
        button.Location = New System.Drawing.Point(250, 25 * count)
        button.Size = New System.Drawing.Size(60, 20)
        button.Name = "Print" & (count + 1)
        button.Text = "Print" '& (count + 1)
        AddHandler button.Click, AddressOf Button_Click
        Panel1.Controls.Add(button)
        MessageBox.Show(Foo)
    End Sub

    Private Sub Button_Click(sender As Object, e As EventArgs)
        Dim button As Button = TryCast(sender, Button)
        MessageBox.Show(button.Name + " clicked")
    End Sub
End Class



МОДУЛЬ:

Module Module1

    Public Foo As String

End Module

Ralf Meier

Задумывались ли вы об использовании DataGridView (который почти похож на Excel-лист) для отображения ваших данных ?

Member 12712519

Нет, сэр, так как я новичок в visual basic. Не могли бы вы мне помочь?

Ralf Meier

Да ... конечно.
Сначала возьмите элемент управления DataGridView и поместите его в свою форму.
Теперь добавьте столбцы по мере необходимости для вашего проекта-расположите их по мере необходимости для вас.
Теперь вы можете вставлять свои данные с добавлением строк.

Я предлагаю вам сначала сделать эти шаги, и когда у вас появится новая точка, в которой вы застряли, вы дадите мне обратную связь (или зададите новый вопрос)

CHill60

Кстати-будьте осторожны, как вы помечаете свои вопросы. Я взял это, потому что я регулярно проверяю сообщения на VB6. Это не VB6.

1 Ответов

Рейтинг:
0

CHill60

У вас есть пара проблем с вашим кодом.
Во-первых, вы пытаетесь показать Form2 внутри цикла, а во-вторых, вы показываете его в немодальном состоянии. Другими словами, обработка цикла продолжается после Form2.Показать линию.

@Ralf_Meier дал отличное предложение использовать Практическое руководство[^]. Это упрощает весь код для разработки размера элементов управления, позиций, добавления их в коллекцию.

Вот рабочий пример. Я также внес некоторые другие коррективы в код, так что следите за комментариями, объясняющими почему.

Public Class Form1
    Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim xlApp As Application
        Dim xlWorkBook As Workbook
        Dim xlWorkSheet As Worksheet
        Dim range As Range

        'You can make the OpenFileDialog look and behave nicely for the user
        OpenFileDialog1.Filter = "Excel files (*.xls*)|*.xls*|All files (*.*)|*.*"
        OpenFileDialog1.FileName = ""
        If OpenFileDialog1.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
            Exit Sub
        End If

        Dim sr As New IO.StreamReader(OpenFileDialog1.FileName)
        MessageBox.Show("You have selected" + OpenFileDialog1.FileName)

        'Get all of the results before attempting to show the form
        Dim listOfResults = New List(Of String)()

        xlApp = New Excel.Application
        xlWorkBook = xlApp.Workbooks.Open(OpenFileDialog1.FileName)
        xlWorkSheet = xlWorkBook.Worksheets(1) 'It's safer to access "the first worksheet" in case a user has renamed it.

        range = xlWorkSheet.UsedRange
        For rCnt = 1 To range.Rows.Count
            For cCnt = 14 To range.Columns.Count
                Dim tst As String = xlWorkSheet.Cells(rCnt, cCnt).Value.ToString()

                'This is a neat way of saying "is my value in a list of possible values"
                If (New String() {"4", "5", "6", "7", "8", "9", "10"}).Contains(tst) Then
                    Dim foo As String = range.Cells(rCnt, "E").Value.ToString()
                    listOfResults.Add(foo)
                End If
            Next
        Next

        xlWorkBook.Close()
        xlApp.Quit()
        releaseObject(xlApp)
        releaseObject(xlWorkBook)
        releaseObject(xlWorkSheet)

        'Only show Form2 after we have everything we're looking for
        If listOfResults.Count > 0 Then
            Form2.PopulateForm2(listOfResults)
        End If
        Form2.ShowDialog()

    End Sub
И Форма 2...
Public Class Form2
    'Note this is a public method on this class
    Public Sub PopulateForm2(results As List(Of String))

        'This could be done in the designer
        DataGridView1.Columns.Clear()
        DataGridView1.Columns.Add(New DataGridViewColumn())
        DataGridView1.Columns.Add(New DataGridViewButtonColumn())
        DataGridView1.AllowUserToAddRows = False

        DataGridView1.Rows.Clear()
        For count As Integer = 0 To results.Count - 1

            Dim dr As DataGridViewRow = New DataGridViewRow()
            Dim dc As DataGridViewCell = New DataGridViewTextBoxCell()
            dc.Value = results(count)
            dr.Cells.Add(dc)

            Dim button As DataGridViewButtonCell = New DataGridViewButtonCell()
            button.Value = "Print" '& (count + 1)
            dr.Cells.Add(button)

            DataGridView1.Rows.Add(dr)
        Next

    End Sub
    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

        If e.ColumnIndex = 1 Then 'i.e. the button
            Dim dgv = CType(sender, DataGridView)
            MessageBox.Show(String.Format("button {0} clicked. Associated Text is {1}", e.RowIndex.ToString(), dgv.Rows(e.RowIndex).Cells(0).Value))
        End If
    End Sub
End Class

Обратите внимание, что мне не пришлось подключать событие нажатия кнопки-я использовал событие CellContentClick для DataGridView и просто проверил, что пользователь нажал на мою ячейку кнопки (ColumnIndex = 1)