excel - 删除未使用的表格行
问题描述
我有一张包含 6 个表格的表格,每个表格使用 B:N 列。B 列包含每张桌子从凌晨 1 点到凌晨 12 点的小时数。我需要删除单元格下方包含单元格 AF2 上特定值的所有行。例如,AF2 包含 5PM。应删除每张表 B 列中下午 5 点以下的所有行。所有桌子都有标题,例如第一张桌子是收银员,第二张桌子是服务员,依此类推。
这是我到目前为止所拥有的:
Set sh = Sheets("report")
valueToFind = sh.Range("AF2").Value
Do
Set Cell1 = sh.Range("B:B").Find(What:=valueToFind, LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Cell1 Is Nothing Then Exit Do
Set Cell2 = sh.Range(Cell1.Address & ":B" & sh.UsedRange.Rows.Count).End(xlDown)
If IsEmpty(Cell1.Offset(1, 0)) Then
Exit Sub
Else
Rows(Cell1.Row & ":" & Cell2.Row).Delete
End If
Loop
此代码的问题在于,它还删除了单元格 AF2 上指示的时间的行,当它应该向下移动一个单元格然后删除从该行开始向下移动时。
有什么建议么?
解决方案
请在尝试此代码之前备份您的书:
阅读代码的注释并根据您的需要进行调整。(注释/取消注释删除先前范围值中的内容的行)
编辑:见下面的两个版本
版本 1
此代码复制源工作表中的值,然后循环遍历表(listobjects)并随着您要查找的时间删除行下方的行
Public Sub CopyTablesDeleteRows()
' Declare objects
Dim mainSheet As Worksheet
Dim evalSheet As Worksheet
Dim evalTable As ListObject
Dim sourceRange As Range
Dim destinationRange As Range
Dim filterCell As Range
Dim foundCell As Range
' Declare other variables
Dim mainSheetName As String
Dim reportSheetName As String
Dim sourceRangeAddress As String
Dim filterCellAddress As String
' Adjust these next lines to fit your needs
mainSheetName = "Main report"
reportSheetName = "report"
sourceRangeAddress = "B2:N84"
filterCellAddress = "AF2"
Set mainSheet = ThisWorkbook.Worksheets(mainSheetName)
' This is the source range where tables are located
Set sourceRange = mainSheet.Range(sourceRangeAddress)
Set evalSheet = ThisWorkbook.Worksheets(reportSheetName)
Set destinationRange = evalSheet.Range(sourceRangeAddress)
Set filterCell = evalSheet.Range(filterCellAddress)
' Delete previous values
destinationRange.Clear
' Copy source range to destination
sourceRange.Copy destinationRange
' Loop through each table in the worksheet
For Each evalTable In evalSheet.ListObjects
' Find the filter cell value in the table's first column (see ListColumns(1) in next line)
Set foundCell = evalTable.ListColumns(1).DataBodyRange.Find(What:=Format(filterCell.Value, "hh:mm AM/PM"), _
LookIn:=xlValues, lookat:=xlWhole, _
searchorder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
' If filter cell value is found inside table's column
If Not foundCell Is Nothing Then
' Delete rows from that cell to the last one in table
evalTable.DataBodyRange.Rows(foundCell.Row - evalTable.HeaderRowRange.Row + 1 & ":" & evalTable.DataBodyRange.Rows.Count).Delete
End If
Next evalTable
End Sub
版本 2
此代码适用于复制粘贴值格式(意味着您失去了结构化表格功能),然后根据搜索的时间值查找结束行和开始行,最后删除范围(代码很长,因为您定位 12:00 的方式AM 在表格底部,有些表格没有全天营业时间)
Public Sub DeleteRows()
Dim reportSheet As Worksheet
Dim reportSheetName As String
Dim valueToFindRangeAddr As String
Dim lookInColumn As String
Dim valueToFind As Date
Dim lastRow As Long
Dim startRow As Long
Dim endRow As Long
Dim generalCounter As Long
Dim counter As Long
Dim rangeCounter As Long
Dim deleteRangeRows() As Variant
Dim rangeRows() As Variant
reportSheetName = "report"
valueToFindRangeAddr = "AF2"
lookInColumn = "B"
' Initialize objects
Set reportSheet = ThisWorkbook.Worksheets(reportSheetName)
valueToFind = reportSheet.Range(valueToFindRangeAddr).Value2
' Get last cell with values in lookInColumn
lastRow = reportSheet.Cells(reportSheet.Rows.Count, reportSheet.Columns(lookInColumn).Column).End(xlUp).Row
If Format(valueToFind, "hh:mm AM/PM") = Format(TimeValue("12:00 AM"), "hh:mm AM/PM") Then
MsgBox "Value to find is last time in tables"
Exit Sub
End If
For generalCounter = lastRow To 1 Step -1
ReDim Preserve deleteRangeRows(rangeCounter)
startRow = 0
endRow = 0
' Get row of last cell with time
For counter = generalCounter To 1 Step -1
If IsTime(reportSheet.Range(lookInColumn & counter).Value) = True Then
endRow = counter
Exit For
End If
Next counter
' Get row of cell with value to find
For counter = endRow - 1 To 1 Step -1
If reportSheet.Range(lookInColumn & counter).Value = valueToFind Then
startRow = counter + 1
Exit For
ElseIf IsTime(reportSheet.Range(lookInColumn & counter).Value) = False Then
Exit For
End If
Next counter
If startRow > 0 And startRow <= endRow Then
deleteRangeRows(rangeCounter) = Array(startRow, endRow)
rangeCounter = rangeCounter + 1
generalCounter = counter
Else
generalCounter = counter + 1
End If
Next generalCounter
' Delete rows ranges recorded
For counter = 0 To UBound(deleteRangeRows) - 1
startRow = deleteRangeRows(counter)(0)
endRow = deleteRangeRows(counter)(1)
reportSheet.Rows(startRow & ":" & endRow).Delete
Next counter
MsgBox "Finished"
End Sub
' Credits: https://stackoverflow.com/a/52805191/1521579
Function IsTime(Expression As Variant) As Boolean
If IsDate(Expression) Then
IsTime = (Int(CSng(CDate(Expression))) = 0)
End If
End Function
让我知道它是否有效,并记得标记答案以帮助他人
推荐阅读
- java - 找不到空指针异常
- python - 尝试/排除问题 Python 2.7
- c# - 如何从控制器显示一个简单列表以在视图的选择元素中查看?
- css - 如何找出重复的内联 CSS 样式?
- node.js - 如何检测用户是否已经在我的网站上使用社交帐户进行了签名并且现在想要创建一个普通帐户?
- azure - 没有运行时 Azure 服务总线传入请求
- java - 在 Java 8 中使用流按 Map 值分组
- angular-dart - 在 AngularDart 中路由到 webdev 服务
- airflow - 气流:第一个操作员完成后如何并行启动操作员
- ios - Branch.io 链接 Facebook 问题