excel 工作表到ListBox1到另一个工作表

h5qlskok  于 2023-10-22  发布在  其他
关注(0)|答案(3)|浏览(130)

有一个非常简单的ListBox 1显示Sheet 5中的数据。沿着用于显示来自Sheet 5的数据的代码,是用于将数据保存到另一个工作表(Sheet 9)的代码。我的问题是,按照ListBox 1显示将数据放在正确的行和列上。
这是Sheet 5中ListBox 1显示的图像:

这是第5页的原始数据图像:

这是第5页的原始数据文本:

Month       || Color    || Time
August      || Red      || 0:00:12
August      || Blue     || 0:00:02
September   || Blue     || 0:00:03
October     || Yellow   || 0:01:00
October     || Green    || 0:00:10

这是Sheet 9的原始图像(ListBox 1数据保存到其中[临时-因为我有一个想要的Sheet 9输出]):

这是我的整个表单代码:

Option Explicit
Private Sub UserForm_Initialize()
With Worksheets("Sheet5")
    Dim c As Range
    Dim i As Long
    For Each c In .Range("A2:A100")
        With Me.ListBox1
            .ColumnHeads = True
            .ColumnCount = 3
            .ColumnWidths = "75;75;75;75"
            .AddItem
            .List(i, 0) = c
            .List(i, 1) = c.Offset(, 1)
            .List(i, 2) = Format(c.Offset(, 2), "hh:mm:ss")
            i = i + 1
        End With
    Next c
End With

    Dim shT As Worksheet, cT As Range
    Set shT = ThisWorkbook.Sheets("Sheet9")
    Dim nT As Long
    shT.Range("B2: M2").ClearContents
    shT.Range("B3: M3").ClearContents
    'shT.Range("B4: M4").ClearContents
    'shT.Range("B5: M5").ClearContents
            
    For nT = 1 To Me.ListBox1.ListCount - 1
        'LOCATE
        Set cT = shT.Range("1:1").Find(Me.ListBox1.List(nT, 0), , xlValues, xlWhole)
        If Not cT Is Nothing Then
            cT.Offset(1, 0).value = ListBox1.List(nT, 1)
            cT.Offset(2, 0).value = ListBox1.List(nT, 2)
        End If
    Next nT
End Sub

这是我上面代码的当前结果。当列表框1中显示绿色标记时,不显示下面的红色标记。本工作表中的第1行和A列都是手动编码的。这不是我想要的Sheet 9输出。我只是显示我正在使用的代码的当前输出。

这是我想要的输出下面按照ListBox 1显示,这是可能的吗?如果是这样,那么应该在上面的代码中做什么修改,才能以这种方式在Sheet 9中保存?第1行和第A列仍然是手动编码的(换句话说,只有动态时间将根据ListBox 1中显示的正确月份和颜色保存在工作表中):

感谢你的评分

3pvhb19x

3pvhb19x1#

Pivot数据

  • IMO,你面临着一个XY问题,即。你使用列表框作为“中间人”来将源转向目的地。您应该通过简单地透视源数据来实现这一点。
    主要
Private Sub UserForm_Initialize()

    Dim wb As Workbook: Set wb = ThisWorkbook
    
    ' Return the values from the source data range
    ' in the source data array ('sData').
    Dim sws As Worksheet: Set sws = wb.Sheets("Sheet5")
    Dim strg As Range: Set strg = sws.Range("A1").CurrentRegion ' table
    Dim sdrg As Range
    Set sdrg = strg.Resize(strg.Rows.Count - 1).Offset(1) ' data
    Dim sData() As Variant: sData = sdrg.Value
    
    ' Pass the source data array to the 'PopulateListbox' method (procedure).
    PopulateListbox sData
    
    ' Reference the destination table range (has headers).
    Dim dws As Worksheet: Set dws = wb.Sheets("Sheet9")
    Dim dtrg As Range: Set dtrg = dws.Range("A1").CurrentRegion ' table
    
    ' Pass the source data array and the destination table range
    ' to the 'PopulateSheet9' method (procedure).
    PopulateSheet9 sData, dtrg
    
End Sub

帮助-列表框

Sub PopulateListbox(Data() As Variant)

    With Me.ListBox1

        ' Do these 3 only once!
        .ColumnHeads = True
        .ColumnCount = 3
        .ColumnWidths = "75;75;75;75"

        Dim r As Long

        For r = 1 To UBound(Data, 1)
            .AddItem
            .List(r - 1, 0) = Data(r, 1)
            .List(r - 1, 1) = Data(r, 2)
            .List(r - 1, 2) = Format(Data(r, 3), "hh:mm:ss")
        Next r

    End With

End Sub

The Help - Pivot

  • 请注意,一个更有效的解决方案是将Application.Match的“功能”替换为将月份和颜色写入字典,以便分别搜索列和行索引。
Sub PopulateSheet9(sData() As Variant, ByVal dtrg As Range)
    
    ' Determine the number of rows and columns
    ' of the destination values ('Time').
    Dim drCount As Long: drCount = dtrg.Rows.Count - 1
    Dim dcCount As Long: dcCount = dtrg.Columns.Count - 1
    
    ' Reference the 'elements' of the destination table.
    
    ' Column Labels
    Dim drgMonths As Range: Set drgMonths = dtrg.Resize(1, dcCount).Offset(, 1)
    ' Row Labels
    Dim drgColors As Range: Set drgColors = dtrg.Resize(drCount, 1).Offset(1)
    ' Values
    Dim drgValues As Range:
    Set drgValues = dtrg.Resize(drCount, dcCount).Offset(1, 1)
    
    ' Clear previuos values data.
    drgValues.ClearContents ' to preserve the 'Time' formatting (not '.Clear'!)
    
    ' Write the matching values to the destination values array.
    
    Dim dData() As Variant: ReDim dData(1 To drCount, 1 To dcCount) '
    ' In this case, the same as 'dData = drgValues.Value')
    
    Dim DateIndex As Variant, ColorIndex As Variant, sr As Long
    
    For sr = 1 To UBound(sData, 1)
        DateIndex = Application.Match(sData(sr, 1), drgMonths, 0)
        ColorIndex = Application.Match(sData(sr, 2), drgColors, 0)
        If IsNumeric(DateIndex) And IsNumeric(ColorIndex) Then
             dData(ColorIndex, DateIndex) = sData(sr, 3)
        End If
    Next sr

    ' Write the values from the destination array to the destination range.
    drgValues.Value = dData

End Sub
5n0oy7gb

5n0oy7gb2#

请试试下一条路。它使用数组,主要在内存中工作,即使在更大的范围内也很快:

Sub ExtractColorTime()
  Dim shT As Worksheet, rngHead As Range, rngCol As Range, lastR As Long
  Dim mtchR, mtchC, arr, arrLst, nT As Long, rngRet As Range
  
  Set shT = ThisWorkbook.Sheets("Sheet9")
  lastR = shT.Range("A" & shT.rows.count).End(xlUp).Row
  Set rngHead = shT.Range("B1:M1")       'headers range
  Set rngCol = shT.Range("A2:A" & lastR) 'colors range
  
  Set rngRet = shT.Range("B2:M" & lastR) 'the range where to return
  rngRet.ClearContents
  arr = rngRet.value 'place the range in an array to be returned at once
  
  arrLst = ListBox1.List 'place the list box intems in an array for faster processing
            
    For nT = 0 To UBound(arrLst) 'iterate between the list array rows
        mtchR = Application.match(arrLst(nT, 0), rngHead, 0) 'match the header column (month)
        mtchC = Application.match(arrLst(nT, 1), rngCol, 0)  'match the color row
        If IsNumeric(mtchR) And IsNumeric(mtchC) Then 'if buth matches exist:
            arr(mtchC, mtchR) = Format(arrLst(nT, 2), "hh:mm:ss") ' place the well formatted time in its correct position
        End If
    Next
    
    'drop the array content at once:
    rngRet.value = arr
    
    MsgBox "Ready..."
End Sub
w7t8yxp5

w7t8yxp53#

试试看吧

Dim shT As Worksheet, cT As Range, cC As Range
    Set shT = ThisWorkbook.Sheets("Sheet9")
    Dim nT As Long
    shT.Range("B2:M1000").ClearContents
    For nT = 0 To Me.ListBox1.ListCount - 1
        'Locate month
        Set cT = shT.Range("1:1").Find(Me.ListBox1.List(nT, 0), , xlValues, xlWhole)
        'Locate color
        Set cC = shT.Range("A:A").Find(Me.ListBox1.List(nT, 1), , xlValues, xlWhole)
        If Not (cT Is Nothing Or cC Is Nothing) Then
            shT.Cells(cC.Row, cT.Column).Value = ListBox1.List(nT, 2)
            ' OR
            ' cT.Offset(cC.Row - 1, 0).Value = ListBox1.List(nT, 2)
        End If
    Next nT

相关问题