【问题标题】:Loop through Autofilter Criteria VBA not starting with first available result?循环通过 Autofilter Criteria VBA 不是从第一个可用结果开始?
【发布时间】:2018-09-23 20:07:20
【问题描述】:
This script is used to filter column I data, copy it and move it to a new worksheet based on the first visible cell in I2 (header is I1). Afterwards, I would want to Loop it to go through the rest of the autofilter criteria without actually referencing anything, just running through the list. It seems to be working but it unselects all the data in Column I and doesn't name the sheet properly because the data results in blank rows. Can anyone help me? 

我只需要代码即可:

按列 I(经理)自动筛选,选择所有单元格,创建新工作表,将过滤后的经理数据从原始数据粘贴到该新工作表中,根据 I 列中的第一个可见单元格值(经理名称)命名工作表,然后循环通过过滤器列表的其余部分,而不必引用经理名称,只是一个 Next 类型的循环功能,直到整个列表已经运行。

   Sub Format()



   Set My_Range = Worksheets("Sheet1").Range("A1:I" & LastRow(Worksheets("Sheet1")))
   Set Name = FirstVisibleValue(ActiveSheet, 2, 9)

Cells.Select


 Do


    'Filter and set the filter field and the filter criteria :
    My_Range.AutoFilter Field:=9, Criteria1:=ActiveCell.Value



    'Add a new Worksheet
    Set WSNew = Worksheets.Add(After:=Sheets("Sheet1"))

    WSNew.Name = Name


        'Copy/paste the visible data to the new worksheet
        My_Range.Parent.AutoFilter.Range.Copy

        With WSNew.Range("A1")

            .PasteSpecial xlPasteValues
            Cells.Select
        End With





    'Close AutoFilter
    My_Range.Parent.AutoFilterMode = False

    'Restore ScreenUpdating, Calculation, EnableEvents, ....
    My_Range.Parent.Select
    ActiveWindow.View = ViewMode
    If Not WSNew Is Nothing Then WSNew.Select
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .Calculation = CalcMode
    End With

Loop

End Sub


Function LastRow(sh As Worksheet)
    On Error Resume Next
    LastRow = sh.Cells.Find(What:="*", _
                            After:=sh.Range("A1"), _
                            Lookat:=xlPart, _
                            LookIn:=xlValues, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlPrevious, _
                            MatchCase:=False).Row
    On Error GoTo 0
End Function

【问题讨论】:

  • 这里有很多问题,我想说的第一是可读性 - 我会摆脱你添加的所有效率(所有 With Application 位),你肯定不需要这些,因为你没有工作代码,而且它占用了你宏的一半以上。此外,您需要明确引用您的范围(Workbooks("Book1").Worksheets("Sheet1").Range("A1:I" & LastRow(Worksheets("Sheet1")) 等。到处使用 ActiveSheetActiveCell 会搞砸你。
  • 我刚刚编辑了代码,您能帮我识别 I2 中的第一个可见单元格以便正确命名工作表吗?

标签: vba excel


【解决方案1】:

试试这个 - 减少很多不必要的东西并清理一下。为了确保我们还没有该经理的工作表,我们使用 UDF WorksheetExists()

我也尽量避免 Do/Loop 循环 - 只需对 I 的整个列使用 For 循环。

Option Explicit
Sub Format()

Dim sht As Worksheet, WSNew As Worksheet
Dim My_Range As Range
Dim i As Long, lastrow As Long

Set sht = ThisWorkbook.Worksheets("Sheet1")
lastrow = sht.Cells(sht.Rows.Count, "I").End(xlUp).Row
Set My_Range = sht.Range("A1:I" & lastrow)

For i = 2 To lastrow

    If WorksheetExists(sht.Range("I" & i).Value) = False Then

        Set WSNew = Worksheets.Add(After:=Sheets("Sheet1"))
        WSNew.Name = sht.Range("I" & i).Value

        My_Range.AutoFilter Field:=9, Criteria1:=sht.Range("I" & i).Value

        My_Range.Parent.AutoFilter.Range.Copy
        WSNew.Range("A1").PasteSpecial xlPasteValues

    End If

Next i

My_Range.Parent.AutoFilterMode = False
Application.CutCopyMode = False
End Sub
Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function

【讨论】:

  • 逗号消失了吗?尝试将其移动到自己的行中Dim WSNew As Worksheet
  • 这行代码没有定义:If WorksheetExists(sht.Range("I" & i).Value) = False Then
  • 如何在 Dim 部分定义它?
  • @NicholasM 您的工作表名称是“Sheet1”吗?您无需再定义任何内容,只需确保将该函数包含在模块的底部即可。
  • @dwirony2 好的,所以它运行了第一个过滤的项目,然后在函数部分的这一行上显示了类型不匹配错误:WorksheetExists = Evaluate("ISREF('" & sName & "' !A1)")
猜你喜欢
  • 1970-01-01
  • 2020-01-26
  • 2016-09-27
  • 2018-09-23
  • 2018-07-27
  • 2015-11-28
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多