【问题标题】:Insert rows based on two or more conditions in Excel在 Excel 中根据两个或多个条件插入行
【发布时间】:2021-01-23 03:27:54
【问题描述】:

每一行都有一个ID和一系列的多种灯(类型)和功率(瓦)

我需要根据以下条件选择值并以特定方式将它们插入到主工作表中:

  1. 如果在同一行中有 2 个灯的功率(瓦​​特)和类型相同,则应在另一张表的类型列中插入灯串类型+功率。

  2. 如果同一行中存在不同功率(瓦特)或类型的灯,则应在第一行下方插入具有相同 ID 的其他类型的灯。例如:

你们能帮帮我吗?

【问题讨论】:

  • 我想知道是否有办法制作 VBA 代码是的,请发布您尝试过的内容,以及您卡在哪里
  • 这个宏不容易。您发布的信息还不够。可以有多少列数据? .. 要执行此宏,您需要将所有类型的灯和功率相互比较。如果假设有 5 个类型/瓦特列,那么您需要将 1 与 2、1 与 3、.. 直到 5.. 然后 2 与 1、2 与 3、2 与 4... 进行比较。然后用第二个条件重新做一遍。
  • E、H 和 K 列中的数字是多少?
  • @Gassz 可以存在的最大数据列数为 10(对于每个瓦特和类型),此数字之前的灯类型和瓦特是灯的数量。
  • @EvilBlueMonkey 灯的数量。

标签: excel vba multiple-columns rows


【解决方案1】:

试试这个代码:

Sub SubTotals()
    
    'Declarations.
    Dim DblResultCounter As Double
    Dim DblCounter01 As Double
    Dim RngStartingCell As Range
    Dim RngFirstData As Range
    Dim RngIDList As Range
    Dim RngID As Range
    Dim RngTarget As Range
    Dim StrResult() As String
    Dim StrWatts As String
    Dim StrType As String
    
    'Creating a new worksheet.
    ActiveSheet.Copy After:=ActiveSheet
    
    'Settings.
    Set RngStartingCell = Range("A1")
    Set RngFirstData = Range("F2")
    StrWatts = "WATTS"
    StrType = "TYPE"
    
    'Setting RngIDList.
    Set RngIDList = Range(RngStartingCell.Offset(1, 0), RngStartingCell.End(xlDown))
    
    'Covering each cell in RngIDList.
    For Each RngID In RngIDList
        
        'Setting RngTarget as the last cell on the right with data.
        Set RngTarget = Cells(RngID.Row, Columns.Count).End(xlToLeft)
        
        'Covering all the columns with data.
        Do Until RngTarget.Column <= RngFirstData.Column
            
            'Searching for the next columns with StrWatts and StrType as headers.
            Do Until Cells(RngStartingCell.Row, RngTarget.Column).Value = StrWatts And _
                     Cells(RngStartingCell.Row, RngTarget.Column - 1).Value = StrType
                Set RngTarget = RngTarget.Offset(0, -1)
            Loop
            
            'Reporting the results.
            DblResultCounter = DblResultCounter + 1
            ReDim Preserve StrResult(1 To 3, 1 To DblResultCounter)
            StrResult(1, DblResultCounter) = RngID.Value
            StrResult(2, DblResultCounter) = RngTarget.Offset(0, -1).Value & RngTarget.Value
            StrResult(3, DblResultCounter) = RngTarget.Offset(0, -2).Value
            
            Set RngTarget = RngTarget.Offset(0, -1)
        Loop
    Next
    
    'Setting RngTarget as the last of the cell in RngIdList.
    Set RngTarget = RngIDList.Cells(RngIDList.Rows.Count, 1)
    
    'Covering the whole list from the bottom up.
    Do Until RngTarget.Row = RngStartingCell.Row
        
        'Covering each value in StrResult().
        For DblCounter01 = 1 To DblResultCounter
            
            'Checking if the IDs match.
            If RngTarget.Value = StrResult(1, DblCounter01) Then
                
                'Reporting the results.
                RngTarget.Offset(1, 0).EntireRow.Insert
                RngTarget.Offset(1, 0).Value = StrResult(1, DblCounter01)
                RngTarget.Offset(1, 1).Value = StrResult(3, DblCounter01)
                RngTarget.Offset(1, 2).Value = StrResult(2, DblCounter01)
                
            End If
        Next
        
        Set RngTarget = RngTarget.Offset(-1, 0)
    Loop
    
    'Sorting the list.
    With ActiveSheet.Sort
        .SortFields.Clear
        .SortFields.Add Key:=RngTarget.EntireColumn, _
                        SortOn:=xlSortOnValues, _
                        Order:=xlAscending, _
                        DataOption:=xlSortNormal
        .SortFields.Add Key:=RngTarget.Offset(0, 2).EntireColumn, _
                        SortOn:=xlSortOnValues, _
                        Order:=xlAscending, _
                        DataOption:=xlSortNormal
        .SetRange Range(RngStartingCell, Cells(RngStartingCell.Row, Columns.Count).End(xlToLeft)).EntireColumn
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
        .SortFields.Clear
    End With
    
    'Setting RngTarget as the last cell of the list.
    Set RngTarget = RngStartingCell.End(xlDown)
    
    'Covering the whole list from the bottom up.
    Do Until RngTarget.Address = RngStartingCell.Address
        
        'Checking if the actual row has the same item as the row above.
        If RngTarget.Offset(0, 0).Value = RngTarget.Offset(-1, 0).Value And _
           RngTarget.Offset(0, 2).Value = RngTarget.Offset(-1, 2).Value Then
            
            'Making one row of the two.
            RngTarget.Offset(0, 1).Value = RngTarget.Offset(0, 1).Value + RngTarget.Offset(-1, 1).Value
            RngTarget.Offset(-1, 0).EntireRow.Delete
            
        Else
            Set RngTarget = RngTarget.Offset(-1, 0)
        End If
        
    Loop
    
    'Setting RngTarget as the last cell of the list.
    Set RngTarget = RngStartingCell.End(xlDown)
    
    'Covering the whole list from the bottom up.
    Do Until RngTarget.Address = RngStartingCell.Address
        
        'Counting how many rows with the ID reported in RngTarget are in the list.
        DblCounter01 = Excel.WorksheetFunction.CountIf(Range(RngStartingCell, RngTarget), RngTarget.Value)
        
        'Checking if there is more than 1 row with the same ID.
        If DblCounter01 > 1 Then
            
            'Cut-pasting the source data.
            RngTarget.EntireRow.Resize(1, Columns.Count - 3).Offset(0, 3).Cut RngTarget.Offset(-DblCounter01 + 1, 3)
            Set RngTarget = RngTarget.Offset(-DblCounter01, 0)
            RngTarget.Offset(DblCounter01, 0).EntireRow.Delete
        Else
            Set RngTarget = RngTarget.Offset(-DblCounter01, 0)
        End If
        
    Loop
    
    
End Sub

它会创建一个包含您正在寻找的结果的新工作表。如果您不希望它出现在新工作表中,而是想编辑源工作表本身,只需删除行 ActiveSheet.Copy After:=ActiveSheet

这个任务很可能用更短的代码来完成。我选择了更长的方法,因为我想使用大量的基本命令;这样你就可以从中学到更多基本的东西。

【讨论】:

  • 这对我很有帮助。十分感谢!我将继续学习 VBA,这将非常有用。
  • 我只有一个问题。这段代码对我帮助很大,但我试图对其进行编辑,以便我可以添加除 ID、QUANTITY 和 LAMP 之外的更多列,其中包含与 ID 一样的信息将被复制。换句话说,我试图找到一种方法来创建更多包含数据的列,并且这些数据会在必要时像 ID 一样被复制。我应该编辑代码的哪一部分才能做到这一点?
  • 我会说任何关于StrResult() 的事情。如果要将数据保留在较大报告的一侧,您可能还需要将数据向右移动(因此还要更改 RngFirstData 设置)。可以肯定的是,我需要详细信息。在这种情况下,这将是另一个问题。您可以尝试编辑,如果遇到困难,您可能会提出另一个问题。
  • 嗨,有没有一种方法可以在不对工作表进行排序的情况下编写此代码?我试图改变这一点,但每次我这样做都没有任何反应。
  • 通常当我需要维护需要临时排序的列表的顺序时,我会创建一个额外的列并用递增的值填充它。然后我对整个事情进行排序,完成后我使用所述列恢复原始顺序。这对你有用吗?
猜你喜欢
  • 1970-01-01
  • 2020-06-11
  • 2022-08-19
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 1970-01-01
相关资源
最近更新 更多