如何使用搜索按钮将excel列表框作为数据网格进行协作并显示在文本框中?

如何使用搜索按钮将excel列表框作为数据网格进行协作并显示在文本框中?,excel,listbox,userform,vba,Excel,Listbox,Userform,Vba,我有这个代码来显示我在工作表中的所有数据,并将它们加载到列表框中。单击列表框中的列时,如何显示并同时修改文本框中的数据 Private Sub Dloadbtn_Click() 'Load Diret Colo data into Direct Colo Listbox data grid. Dim ws As Worksheet Dim rng As Range Dim hd As Range Dim i As Long, j As Long, rw As Long Dim Myarray

我有这个代码来显示我在工作表中的所有数据,并将它们加载到列表框中。单击列表框中的列时,如何显示并同时修改文本框中的数据

Private Sub Dloadbtn_Click()

'Load Diret Colo data into Direct Colo Listbox data grid.

Dim ws As Worksheet
Dim rng As Range
Dim hd As Range
Dim i As Long, j As Long, rw As Long
Dim Myarray() As String

'~~> Change your sheetname here
Set ws = Sheets("Colodbs")

'~~> Set you relevant range here
Set rng = ws.Range("A1:N10000")

With Me.Dlistbox
    .Clear
    .ColumnHeads = False
    .ColumnCount = rng.Columns.count

    ReDim Myarray(rng.Rows.count, rng.Columns.count)

    rw = 0

    For i = 1 To rng.Rows.count
        For j = 0 To rng.Columns.count
            Myarray(rw, j) = rng.Cells(i, j + 1)
        Next
        rw = rw + 1
    Next

    .List = Myarray

    '~~> Set the widths of the column here. Ex: For 5 Columns
    '~~> Change as Applicable
    .ColumnWidths = "50;70;30;50;30;120;120;30;150;30;50;50;70;200"
    .TopIndex = 0
End With
End Sub

Private Sub DSearchbtn_Click()

Dim i As Long
Dim rno As Integer
i = 0

Do While Colodbs.Cells(i + 1, 1).Value <> ""

        If Colodbs.Cells(i + 1, 1).Value = FbSNtxt.Text Then

            rno = Colodbs.Cells(i + 1, 1).Row
            GoTo Condition
        Else
        rno = 0

        End If
    i = i + 1
Loop

Condition:
If rno <> 0 Then
    Colodbs.Cells(rno, 2).Value = FbSNtxt.Text
Else
    MsgBox ("No Such number is found")
End If
End Sub
Private Sub-Dloadbtn_Click()
'将Diret Colo数据加载到Direct Colo Listbox数据网格中。
将ws设置为工作表
变暗rng As范围
Dim hd As范围
尺寸i为长,j为长,rw为长
Dim Myarray()作为字符串
“~~>在此处更改您的姓名
设置ws=Sheets(“Colodbs”)
“~~>在此处设置相关范围
设置rng=ws.范围(“A1:N10000”)
和我一起去吧
清楚的
.ColumnHeads=False
.ColumnCount=rng.Columns.count
ReDim Myarray(rng.Rows.count、rng.Columns.count)
rw=0
对于i=1到rng.Rows.count
对于j=0到rng.Columns.count
Myarray(rw,j)=随机单元(i,j+1)
下一个
rw=rw+1
下一个
.List=Myarray
“~~>在此处设置列的宽度。例:5列
“~~>根据需要进行更改
.ColumnWidths=“50;70;30;50;30;120;120;30;150;30;50;50;70;200”
.TopIndex=0
以
端接头
专用子数据搜索按钮单击()
我想我会坚持多久
作为整数的Dim rno
i=0
Do While Colodbs.Cells(i+1,1).Value“”
如果Colodbs.Cells(i+1,1).Value=FbSNtxt.Text,则
rno=Colodbs.Cells(i+1,1).Row
转到条件
其他的
rno=0
如果结束
i=i+1
环
条件:
如果rno为0,则
Colodbs.Cells(rno,2).Value=FbSNtxt.Text
其他的
MsgBox(“未找到此类编号”)
如果结束
端接头

在列表框中获取单击值并写入文本框

您的操作说明:“当我单击列表框内的列时,如何显示并同时将数据修改到我的文本框中?”

实际上,您的问题是如何在列表框中获取单击的列索引。使用助手函数
getColIndex()
可以接收这些基本信息,并通过当前列表索引的
list
属性轻松获取单击的数据值

在下面的代码示例中,我使用listbox
MouseUp
事件[1]通过
x
参数获取单击的列索引,该参数基于加载数据到listbox时创建的累积列宽数组显示listbox内点的位置[2]使用单击的数据值修改文本框
FbSNtxt
dListBox.List(Me.dListBox.ListIndex,ColIndex)

用一种巧妙的方法放大评论

为了通过列表框
x
位置获得正确的列索引,需要显示►整个列表框宽度并将其包装到一个滚动框(参见加载过程中的列表框和框设置
Dloadbtn\u Click()

用户表单声明负责人

Option Explicit

Dim cumulWidths() As Double      ' cumulated column widths
Dim ColIndex      As Integer     ' current column index
A.通过列表框鼠标点击事件解决方案

在我看来,最好使用►
MouseUp
事件,通过ist
x
参数获取列表框内的水平位置(以点为单位),因为您仅在那里获得实际的列表索引(而不在
MouseDown
事件中)。此外,它在任何情况下都会被触发,而
click
事件只在同一行中触发一次

Private Sub dListBox_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
' Purpose: find search value in first column and write it to corresponding row in range (column B)
' Escape if no data
  If dListBox.ListIndex < 0 Then Exit Sub
' [1] get the column index via helper function getColIndex
  ColIndex = getColIndex(X)
' [2] get clicked data in column ColIndex and write it into textbox (i.e. modify latest value)
  FbSNtxt.Text = Me.dListBox.List(Me.dListBox.ListIndex, ColIndex)
End Sub
C.加载程序

Private Sub DSearchbtn_Click()
' Purpose: find search value in first column and write it to corresponding row in range (column B)
' Method:  calls procedure dSearch
  dSearch
End Sub

Private Sub dSearch()
' Purpose: find value in first column and write it to corresponding row in range (column B)
' Note:  called a) by dListBox_DblClick or b) DSearchbtn_Click()
If Me.dListBox.ListCount = 0 Then Exit Sub
Dim i As Long, bFound As Boolean
'Dim Colodbs As Worksheet
'Set Colodbs = ThisWorkbook.Worksheets("Colodbs")
For i = 0 To Me.dListBox.ListCount - 1
    If Me.dListBox.List(i, 0) = FbSNtxt.Text Then
       ' write to cell in found row (i+1, Column B)
         Colodbs.Cells(i + 1, 2).Value = FbSNtxt.Text
       ' correct ListBox value in Column B
         Me.dListBox.List(i, 1) = FbSNtxt.Text
       bFound = True: Exit For
    End If
Next i
If Not bFound Then
   MsgBox FbSNtxt.Text & " ColIndex " & ColIndex & " not found.", vbInformation
End If
End Sub
改进的CommandButton代码通过在一条语句中分配范围并使用子过程initcumuldwidths来加快加载过程

Private Sub Dloadbtn_Click()
'Purpose: Load Diret Colo data into Direct Colo Listbox data grid.

Dim ws  As Worksheet
Dim rng As Range
Dim hd  As Range
Dim Myarray As Variant

'~~> Change your sheetname here
Set ws = ThisWorkbook.Worksheets("Colodbs")

'~~> Set yourrelevant range here
Set rng = ws.Range("A1:N10000")

With Me.dListBox
    .Clear
    .ColumnHeads = False
    .ColumnCount = rng.Columns.Count

    ' -----------------------------------------------------
    ' Variant a): assign data to array and array to listbox
    ' -----------------------------------------------------
    '    Myarray = rng
    '    .List = Myarray

    ' -----------------------------------------------------
    ' Variant b): assign data in one step to listbox
    ' -----------------------------------------------------
      .List = rng.Value2
    '~~> Set the column widths of the column here.
      .ColumnWidths = "50;70;30;50;30;120;120;30;150;30;50;50;70;200"
      .TopIndex = 0

    ' =====================================================
    ' calls subprocedure to cumulate column widths
    ' -----------------------------------------------------
      initCumulWidths
    ' set total width of listbox to max as it gets shown within a frame
      .Width = cumulWidths(UBound(cumulWidths)) + 16
    ' set scroll width within frame
      Frame1.ScrollWidth = .Width ' Frame1.InsideWidth * 4

End With

End Sub
►由上述命令按钮单击事件调用的子过程,以获取累积宽度

此子过程读取点中描述的列宽,并将累积值分配给Userform模块声明头中定义的数组

Private Sub initCumulWidths()
' Purpose: calculate cumulated widths and assign values to common userform variable cumulWidths
' Method:  splits ColumnWidths property of listbox and sums converted Point values
' Note: called by above Dloadbtn_Click() event
  Dim a: a = Split(Me.dListBox.ColumnWidths, ";")
  Dim previous As Double, i As Integer
  ReDim cumulWidths(UBound(a))
  For i = 0 To UBound(a)
      cumulWidths(i) = val(Replace(a(i), " Pt", "")) + previous
      previous = cumulWidths(i)
  Next i
  If UBound(a) > 0 Then
     Debug.Print cumulWidths(UBound(a))
  End If
End Sub
附加说明


由于您在搜索过程中没有将
Colodbs
声明为工作表,我假设您使用的是
CodeName
属性而不是对象。

我不太明白您所说的“当我单击列表框中的列时,如何显示并同时修改文本框中的数据?”-你能描述一下想要的步骤和结果吗?1., 2., 3. ... 顺便说一句,通过一个单元格一个单元格的循环来填充数据数组非常耗时。通过将列表框中单击的值包装到►滚动框。顺便说一句,我改进了代码以加快加载过程(参见上面的注释),但没有改变将搜索值写回原始范围B列的方式。尽量避免使用
GoTo
语句-在以前的基本时间也被称为意大利面代码。如果没有,你会很容易失去轨道;今天,这些陈述只出现在错误处理中。@Ronald Morre-如果我的回答能解决你的问题,我会很高兴听到的。如果是这样,我们也会邀请您帮助其他用户,通过将其标记为已接受来确定有用的解决方案(参见)
Private Sub initCumulWidths()
' Purpose: calculate cumulated widths and assign values to common userform variable cumulWidths
' Method:  splits ColumnWidths property of listbox and sums converted Point values
' Note: called by above Dloadbtn_Click() event
  Dim a: a = Split(Me.dListBox.ColumnWidths, ";")
  Dim previous As Double, i As Integer
  ReDim cumulWidths(UBound(a))
  For i = 0 To UBound(a)
      cumulWidths(i) = val(Replace(a(i), " Pt", "")) + previous
      previous = cumulWidths(i)
  Next i
  If UBound(a) > 0 Then
     Debug.Print cumulWidths(UBound(a))
  End If
End Sub