代码之家  ›  专栏  ›  技术社区  ›  yourleftleg

如果在此范围内的日期可以在单独的范围内找到,请删除行

  •  1
  • yourleftleg  · 技术社区  · 6 年前

    我有一个Excel工作簿,就像一个数据库,每周都会更新历史数据。使用一个单独的sub,我将导出作为工作表拉入书本。我找到了导出中的唯一日期。然后查看历史数据,如果历史日期与其中一个导出日期匹配,则删除历史中的行。最后,我将导出复制并粘贴到“历史数据”选项卡中。

    下面的代码按我所希望的方式工作,但在代码块之后我有一些问题:

    Sub AddNewData()
    
    'This will take what's in Export and put it in to Historical
    
    Dim Historical As Worksheet
    Dim Export As Worksheet
    Dim exportdates As Range
    
    Set Historical = ThisWorkbook.Worksheets("Historical")
    Set Export = ThisWorkbook.Worksheets("Export")
    
    'Pulling unique values of dates from this range and pasting to M1:
    Export.Range("B2:B" & Export.Cells(Export.Rows.Count, 1).End(xlUp).Row).AdvancedFilter _
        Action:=xlFilterCopy, CopyToRange:=Export.Range("M1"), Unique:=True
    
    'Originally I was thinking I could make this a list of some sort vlookup or match?
    'As of now, though, it goes unused...:
    Set exportdates = Export.Range("M1:M" & Export.Cells(Export.Rows.Count, 13).End(xlUp).Row)
    
    For r = Historical.Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1
        If Historical.Cells(r, 2).Value = exportdates(1, 1).Value Or _
            Historical.Cells(r, 2).Value = exportdates(2, 1).Value Or _
            Historical.Cells(r, 2).Value = exportdates(3, 1).Value _
            Then Historical.Rows(r).Delete
    Next
    
    'Copying and pasting Export data to Historical tab
    Export.Range("A2:J" & Export.Cells(Export.Rows.Count, 1).End(xlUp).Row).Copy
    Historical.Range("A" & Historical.Cells(Historical.Rows.Count, 1).End(xlUp).Row + 1).PasteSpecial xlPasteValues
    
    Application.CutCopyMode = False
    
    End Sub
    

    1) 是否可以使用exportdates范围以某种方式压缩IF语句?

    2) 当我的日期仅仅是每个月的第一个日期时,这对于几百行数据来说是很好的,但是我还有一个导出,它将每天作为日期,我必须与一个不同的选项卡匹配每日信息。那个有数千行。我不相信这个宏会比简单地按日期排序和删除我自己更有效率吗?我是否可以将IF语句更改为更具包容性,如问题1?

    非常感谢。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Vityata    6 年前

    每当需要使用VBA删除Excel中的多行时,最佳做法是将这些行指定给一个范围,并在末尾删除该范围。

    因此,您的代码应该在这一部分进行重构:

    For r = Historical.Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1
        If Historical.Cells(r, 2).Value = exportdates(1, 1).Value Or _
            Historical.Cells(r, 2).Value = exportdates(2, 1).Value Or _
            Historical.Cells(r, 2).Value = exportdates(3, 1).Value _
            Then Historical.Rows(r).Delete
    Next
    

    这是一个可以用于重构的简单示例(只需确保编写几次 1 在里面 Range("A1:A20") 要了解其工作原理,请执行以下操作:

    Public Sub TestMe()
    
        Dim deleteRange As Range
        Dim cnt         As Long
    
        For cnt = 20 To 1 Step -1
            If Cells(cnt, 1) = 1 Then
                If Not deleteRange Is Nothing Then
                    Set deleteRange = Union(deleteRange, Cells(cnt, 1))
                Else
                    Set deleteRange = Cells(cnt, 1)
                End If
            End If
        Next cnt
    
        deleteRange.EntireRow.Select
        Stop
        deleteRange.EntireRow.Delete
    
    End Sub
    

    运行代码后,它会在 Stop 签名您会看到要删除的行已被选中。一旦您继续 F5级 它们将被删除。考虑删除 停止 .Select 代码中的行。

    如何加速代码的一些一般性想法: https://stackoverflow.com/a/49514930/5448626