我希望能够使用组合框过滤工作表的WBS数据。
选择工作阶段应该只导致具有该工作阶段的产品显示状态In progress
。这个工作阶段以及任何早期的工作阶段也应该是可见的。
此外,如果具有所选工作阶段的产品的状态为Finished
,但包含正在进行的任何早期工作阶段,则该产品也应该可见。那些早期的工作阶段也应该是可见的。此产品的所选工作阶段必须不可见。
如果产品根本没有选定的工作阶段,那么它或任何工作阶段都不应该是可见的。
订单行只有在有可见产品时才可见。
选择之前:
选择后:
以下是我试图做的事情:
Dim ws Worksheet
Set ws = ThisWorkbook.Sheets("DataSheet")
Dim lastRow As Long
lastRow = ws.Cells(Rows.Count, 4).End(xlUp).row
ws.Rows("2:" & lastRow).Select
Selection.EntireRow.Hidden = True
Dim SrchRng As Range, cel As Range
Set SrchRng = ws .Range("A5", "I" & lastRow)
For Each cel In SrchRng
If cel.Range("C1").Text = ComboBox1.Text And cel.Range("E1").Value <> "In progress" Then
cel.EntireRow.Hidden = False
End If
Next
此代码仅显示正在进行的所选工作阶段。我希望产品行,订单行以及所有早期的工作阶段行都可见。
答案 0 :(得分:3)
这是我的尝试。我做了一些假设:
Order x
格式保存订单号,其中x是数字Product x
格式保存产品名称,其中x为x
或y
Work stage x
格式保存工作阶段名称,其中x
是数字Finished
或In progress
Work stage x
格式保存工作阶段名称,其中x
是数字没有空行
Sub ShowHideStages()
Dim oW As Worksheet: Set oW = ThisWorkbook.Worksheets("Sheet9")
Dim iLR As Long: iLR = oW.Cells(Rows.Count, 4).End(xlUp).Row
Dim oCB As OLEObject: Set oCB = oW.OLEObjects("ComboBox1")
Dim iC As Long
Dim iA As Integer
Dim iFirstRow As Integer
Dim iOStartRow As Integer
Dim iPStartRow As Integer
Dim bStageFound As Boolean
Dim bProdFound As Boolean
Dim bHideRow As Boolean
Dim sRowsToHide As String
Dim aTemp As Variant
' Unhide all rows
oW.Rows("2:" & iLR).EntireRow.Hidden = False
' Find the first instance of Order
iFirstRow = Columns("A").Find(what:="*", After:=Columns("A").Cells(1, 1), LookIn:=xlValues).Row
' If dropdown value is empty then skip the process of hiding rows
If Len(Trim(oCB.Object.Text)) > 0 Then
With oW
' Loop through all rows
For iC = iFirstRow To iLR
' Lets loop through current order
bStageFound = False
iOStartRow = iC
Do
iC = iC + 1
sRowsToHide = ""
iPStartRow = iC
bProdFound = False
' Now lets loop through each product
Do
iC = iC + 1
bHideRow = False
' Check if we need to hide the current row
If CInt(Right(Trim(Range("C" & iC).Text), 1)) <= CInt(Right(Trim(oCB.Object.Text), 1)) And LCase(Trim(Range("D" & iC).Text)) = "finished" Then
bHideRow = True
ElseIf CInt(Right(Trim(Range("C" & iC).Text), 1)) > CInt(Right(Trim(oCB.Object.Text), 1)) Then
bHideRow = True
End If
' Check if work stage is the expected stage
If Range("C" & iC).Text = oCB.Object.Text And LCase(Trim(Range("D" & iC).Text)) <> "finished" Then
bProdFound = True
bStageFound = True
End If
' Set rows to hide string
If bHideRow Then
If Len(Trim(sRowsToHide)) = 0 Then
sRowsToHide = CStr(iC)
Else
sRowsToHide = sRowsToHide & "," & CStr(iC)
End If
End If
Loop While Len(Trim(Range("C" & iC).Offset(1, 0).Text)) <> 0
' Check if product was found
If Not bProdFound Then
' It wasn't so set the string to hide product
sRowsToHide = CStr(iPStartRow) & ":" & CStr(iC)
End If
' Hide specified rows .. if specified
If Len(Trim(sRowsToHide)) > 0 Then
If InStr(1, sRowsToHide, ":") > 0 Then
Range(sRowsToHide).EntireRow.Hidden = True
Else
aTemp = Split(sRowsToHide, ",")
For iA = 0 To UBound(aTemp)
Rows(Trim(aTemp(iA))).EntireRow.Hidden = True
Next
End If
sRowsToHide = ""
End If
Loop While Len(Trim(Range("A" & iC).Offset(1, 0).Text)) = 0 And iC < iLR
' Check if order was found
If Not bStageFound Then
' It wasn't so lets set the string to hide the order
sRowsToHide = CStr(iOStartRow) & ":" & CStr(iC)
End If
' Hide the order if we need to
If Len(Trim(sRowsToHide)) > 0 Then
Range(sRowsToHide).EntireRow.Hidden = True
End If
End With
End If
End Sub
注意:UDF也适合ComboBox中的空选择。在这种情况下,显示所有行
答案 1 :(得分:1)
编辑:(v0.3.2)添加了&#34;全部显示&#34;工作阶段选择。
似乎很容易做到,但结果有点棘手。
在遍历行时需要保存两个行索引:当前订单行和当前产品行。只有这样才能正确显示订单,如果显示任何产品。
请注意,常量声明和长变量名称使代码自我记录。
<强> v0.3.2:强>
Show All
- 如果您将另一个项目添加到组合框中并且不以&#34;工作阶段&#34;开头,则选择它会显示所有行。此项目也可以为空白。<强>代码:强>
Option Explicit
'v0.3.2
Private Sub ComboBox1_Change()
Const l_Order_ As String = "Order "
Const l_Work_stage_ As String = "Work stage "
Const l_In_progress As String = "In progress"
Const i_Orders As Long = 1
Const i_Products As Long = 2
Const i_WorkStages As Long = 3
Const i_Progress As Long = 5
Dim rngCurrentRow As Range
Dim lngFirstDataRow As Long
Dim lnglastDataRow As Long
Dim lngCurrentOrderRow As Long
Dim lngCurrentProductRow As Long
Dim boolShowProduct As Boolean
Application.ScreenUpdating = False
' No need for sheet name since Me = active sheet
lngFirstDataRow = WorksheetFunction.Match(l_Order_ & "*", Me.Columns(i_Orders), 0)
lnglastDataRow = WorksheetFunction.Match("*", Me.Columns(i_Progress), -1)
With Range(Me.Rows(lngFirstDataRow), Me.Rows(lnglastDataRow))
If Not ComboBox1.Text Like l_Work_stage_ & "*" Then
.EntireRow.Hidden = False
GoTo ExitSub:
Else
.EntireRow.Hidden = True
Set rngCurrentRow = .Rows(1)
End If
End With
' Loop through all data rows
Do
If rngCurrentRow.Columns(i_Orders) <> vbNullString Then
lngCurrentOrderRow = rngCurrentRow.Row
Set rngCurrentRow = rngCurrentRow.Offset(1)
End If
If rngCurrentRow.Columns(i_Products) <> vbNullString Then
lngCurrentProductRow = rngCurrentRow.Row
Set rngCurrentRow = rngCurrentRow.Offset(1)
End If
boolShowProduct = False
' Loop through consecutive non-empty progress/work stage rows
Do Until rngCurrentRow.Columns(i_Progress) = vbNullString
If rngCurrentRow.Columns(i_WorkStages) <= ComboBox1.Text _
And rngCurrentRow.Columns(i_Progress) = l_In_progress _
Then
boolShowProduct = True
Rows(rngCurrentRow.Row).Hidden = False
Else
' Ignore
End If
Set rngCurrentRow = rngCurrentRow.Offset(1)
Loop
If rngCurrentRow.Columns(i_WorkStages).Offset(-1) < ComboBox1.Text Then
' Re-hide previous shown work stages for this product
Range(Rows(lngCurrentProductRow), Rows(rngCurrentRow.Row)).Hidden = True
ElseIf boolShowProduct Then
Rows(lngCurrentOrderRow).Hidden = False
Rows(lngCurrentProductRow).Hidden = False
End If
Loop Until rngCurrentRow.Row > lnglastDataRow
ExitSub:
Application.ScreenUpdating = True
End Sub
注意:如果您对我的变量命名约定感到好奇,那么它基于RVBA。