简体   繁体   English

VB.NET(Excel两栏>条件组合框)

[英]VB.NET (Excel Two Columns > Conditional Comboboxes)

I'm searching for nearly two hours to find a solution on the following. 我正在搜索将近两个小时,以找到以下解决方案。 In Excel I have two columns (One Column for Master Records and one Column for Slave Records). 在Excel中,我有两列(主记录为一列,从记录为一列)。 Basically, in Combobox1 I want to populate all the Master Records. 基本上,我想在Combobox1中填充所有主记录。 If a selection is made for MasterRecord A, I want Combobox2 to only show me the SlaveRecords belonging to A and not the other records belonging to other Master Records. 如果选择了MasterRecord A,我希望Combobox2仅显示属于A的SlaveRecords,而不显示属于其他Master Record的其他记录。

在此处输入图片说明

I have the Interop Assembly added and Excel opened (there is a connection already). 我添加了Interop程序集并打开了Excel(已经存在连接)。 Your help is much appreciated! 非常感谢您的帮助!

Private Sub Combobox2_Populate()
    'Start Excel Script to populate ComboBox2
    Dim excel As Application = New Application
    Dim w As Workbook = excel.Workbooks.Open(Filename:=databasestatus, [ReadOnly]:=True)
    Dim sheet As Worksheet = w.Sheets("AIR_NL_1")
    Dim StartRow As Integer
    Dim TotalRows As Integer
    ComboBox2.Items.Clear()
    sheet.UsedRange.AutoFilter(Field:=9, Criteria1:=ComboBox1.SelectedItem, Operator:=XlAutoFilterOperator.xlFilterValues)
    TotalRows = sheet.Range("A1").CurrentRegion.Rows.Count
    For StartRow = 3 To TotalRows
        If XlCellType.xlCellTypeVisible = True Then
            ComboBox2.Items.Add(sheet.Range("H:H").Cells(StartRow, 1).Text)
        End If
    Next
    w.Close(SaveChanges:=False)
End Sub    

This might help you, or at least give you a basic idea: 这可能会帮助您,或者至少给您一个基本的想法:

Private Function ExcelToDataTable(ByVal fileExcel As String, _ 
                                  Optional ByVal columnToExtract As String = "*", _
                                  ) As System.Data.DataTable
    Dim dt As New System.Data.DataTable
    Try
        Dim MyConnection As System.Data.OleDb.OleDbConnection
        Dim MyCommand As OleDbDataAdapter
        Dim fileExcelType As String

        'Chose the right provider
        If IO.Path.GetExtension(fileExcel.ToUpper) = ".XLS" Then
            fileExcelType = "Excel 8.0"
            MyConnection = _
            New System.Data.OleDb.OleDbConnection _
            ("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & fileExcel & "';Extended Properties=" & fileExcelType & ";")
        Else
            fileExcelType = "Excel 12.0"
            MyConnection = _ 
            New System.Data.OleDb.OleDbConnection _
            ("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & fileExcel & "';Extended Properties=" & fileExcelType & ";")
        End If

        'Open excel connection
        MyConnection.Open()

        'Populate DataTable
        Dim myTableName = MyConnection.GetSchema("Tables").Rows(0)("TABLE_NAME")
        MyCommand = New OleDbDataAdapter(String.Format("SELECT " & columnToExtract & " FROM [{0}] ", myTableName), MyConnection)
        MyCommand.TableMappings.Add("Table", columnToExtract)
        MyCommand.Fill(dt)
        MyConnection.Close()
    Catch ex As Exception
        Err.Clear()
    End Try
    Return dt
End Function

As you can see, we have an optional parameter called myWhereStatement. 如您所见,我们有一个名为myWhereStatement的可选参数。

What does it mean? 这是什么意思? You can specify its value when you call the function, otherwise its value will be an empty string 您可以在调用函数时指定其值,否则其值为empty string

After that we can call ExcelToDataTable inside our Sub in order to populate the ComboBox as shown below: 之后,我们可以在Sub内部调用ExcelToDataTable ,以填充ComboBox ,如下所示:

Private Sub Combobox_Populate()
    Dim filePath As String = "your_file_path"
    ComboBox1.DataSource = ExcelToDataTable(filePath, "MasterRecord") 
End Sub

Now you have your ComboBox1 filled with data, but the ComboBox2 is still empty. 现在,您的ComboBox1充满了数据,但是ComboBox2仍然为空。

We are going to handle the event of ComboBox1_SelectedValueChanged that means that every time you select an Item from the ComboBox1 it will programmatically fill the ComboBox2 with the propper items as shown below. 我们将处理ComboBox1_SelectedValueChanged事件,这意味着每次您从ComboBox1选择一个项目时,它将以编程方式用适当的项目填充ComboBox2 ,如下所示。

Private Sub ComboBox1_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedValueChanged
    Dim slaveRecords As System.Data.DataTable = ExcelToDataTable(filePath)
    Dim dt As New DataTable
    dt.Columns.Add("SlaveRecords")
    For i As Integer = 0 To slaveRecords.Rows.Count
        If ComboBox1.SelectedItem Is slaveRecords.Rows(i).Item(0) Then
            dt.Rows.Add(slaveRecords.Rows(i).Item(1))
        End If
    Next
    ComboBox2.DataSource = dt
End Sub

Remarks 备注

As you can see the first call of ExcelToDataTable has only 2 parameters while the second one has 3 parameters. 如您所见,第一次调用ExcelToDataTable仅具有2个参数,而第二次调用具有3个参数。 That's the optional parameter feature! 那是可选的参数功能!

NB NB

As you can see I'm using alot of _ because of better code formatting. 如您所见,由于更好的代码格式,我使用了许多_ It means that a single statement will continue across multiple lines 这意味着一条语句将跨多行继续

If something isn't 100% clear ot you have any dubt feel free to ask in the comments below. 如果不是100%清楚的事情,您可以在下面的评论中随意提出疑问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM