首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Excel中根据ComboBox显示/隐藏WBS项

在Excel中根据ComboBox显示/隐藏WBS项
EN

Stack Overflow用户
提问于 2017-09-04 12:52:27
回答 2查看 652关注 0票数 1

我希望能够使用组合框过滤工作表的WBS数据。

选择工作阶段应该只导致具有该工作阶段的产品显示In progress状态可见。这一工作阶段,以及更早的进展阶段,也应是可见的。

此外,如果具有所选工作阶段的产品的状态为Finished,但包含正在进行的任何早期工作阶段,则它也应该是可见的。这些早期的工作阶段也应该是可见的。此产品所选择的工作阶段不得可见。

如果一个产品根本没有选定的工作阶段,那么它和它的任何工作阶段都不应该是可见的。

订单行只有在具有可见产品的情况下才应是可见的。

选择前的

选择后的

以下是我所做的努力:

代码语言:javascript
运行
复制
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

此代码只显示正在进行的选定工作阶段。我希望产品行、订单行和进度阶段前面的所有行都是可见的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-04 17:01:41

编辑: (v0.3.2)添加了“显示所有”工作阶段选项。

做起来似乎很容易,但结果却有点棘手。

在遍历行时,需要保存两个行索引:当前订单行和当前产品行。只有这样,您才能正确地显示订单,如果有任何产品显示。

注意,常量声明和长变量名使代码自文档化。

v0.3.2:

  • Show All --如果将另一项添加到不以“工作阶段”开头的组合框中,则选择它将显示所有行。此项目也可以是空的。

代码:

代码语言:javascript
运行
复制
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的。

票数 1
EN

Stack Overflow用户

发布于 2017-09-05 11:19:23

这是我的尝试。我作了一些假设:

  1. 列A持有Order x格式的序号,其中x是一个数字
  2. 列B以Product x格式保存产品名称,其中x为xy
  3. 列C以Work stage x格式保存工作阶段名称,其中x是一个数字
  4. D列将工作阶段状态保存为FinishedIn progress
  5. ComboBox以Work stage x格式保存工作阶段名称,其中x是一个数字。
  6. 没有空行 子ShowHideStages() Dim oW作为工作表: 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 Integer Dim iA iC As Integer Dim iOStartRow As Integer Dim iOStartRow As Integer Dim iPStartRow As Integer Dim bStageFound As Boolean bHideRow As Boolean bHideRow As String Dim bHideRow作为变体‘Unhide all row(“2:”&)= False’查找iFirstRow =列(“A”).Find(what:=“*”)的第一个实例After:=Columns(A).Cells(1,1),LookIn:=xlValues).Row‘如果下拉值为空,则跳过隐藏行的过程,如果Len(Trim(oCB.Object.Text)) >0,则使用oW’循环遍历iC = iFirstRow To iLR‘Lets循环,通过当前顺序bStageFound = False iOStartRow = iC Do。iC = iC +1 sRowsToHide = "“iPStartRow = iC bProdFound = False‘现在让循环遍历每个产品Do iC = iC +1 bHideRow = False‘检查是否需要隐藏当前行如果CInt(右(Trim(范围(“C”& iC).Text),1) <= CInt(右(Trim(oCB.Object.Text),1)和LCase(Trim(范围(“D”& iC).Text)) = "finished“,然后bHideRow = True ElseIf CInt(右(Trim(”C“& iC).Text),1)>CInt(右(Trim(”D“&iC).Text))>CInt(右(”C“&iC).Text),1)然后bHideRow = True End如果‘检查工作阶段是否为预期阶段--如果范围(“C”& iC).Text = oCB.Object.Text和LCase(Trim(“D”&iC).Text) <>“完成”bProdFound = True bStageFound = True如果‘将行设置为隐藏字符串,如果bHideRow,则如果Len(Trim( sRowsToHide )) =0,则sRowsToHide= CStr(iC)sRowsToHide = sRowsToHide & ",“& CStr(iC)结束If结束If循环,而Len(Trim(范围(”C“& iC).Offset(1,(.Text)) <> 0‘检查是否找到产品,如果没有bProdFound,那么’它没有如此设置字符串隐藏产品sRowsToHide = CStr(iPStartRow) & ":“& CStr(iC)结束如果‘隐藏指定的行.如果指定Len(Trim(sRowsToHide)) >0,则如果InStr(1,sRowsToHide,":“) >0,则范围(SRowsToHide).EntireRow.Hidden= True Else aTemp = Split(sRowsToHide ),)对于iA =0 To UBound(aTemp)行(Trim(aTemp(IA).EntireRow.Hidden= True下一端如果sRowsToHide = "“如果循环而透镜(Trim(范围(“A”&iC)).Offset(1,(.Text))=0和iC < iLR‘检查是否找到了订单,如果没有找到bStageFound,那么’不需要设置字符串来隐藏order sRowsToHide = CStr(iOStartRow) & ":“& CStr(iC)如果需要的话,请隐藏顺序。如果Len(Trim(sRowsToHide)) >0,那么范围(SRowsToHide).EntireRow.Hidden=真结束如果结束如果结束

注意到:UDF也适用于ComboBox中的空选择。在这种情况下,将显示所有行。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46037514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档