简体   繁体   English

基于多单元格逻辑插入新行

[英]Insert new Row based on Multiple Cell Logic

I'm pretty new to VBA and I've searched as best as I can but I still can't find an answer. 我对VBA还是很陌生,我已经尽力进行了搜索,但仍然找不到答案。 I need to write a Macro that will insert a new line based on multiple conditions. 我需要编写一个宏,它将基于多个条件插入新行。 The rows have to be in groups no larger than 5 and separated by carrier. 行必须成组,不超过5个,并用载波分隔。 But if a Container is repeating, it counts as 1 row. 但是,如果容器在重复,则计为1行。

Current: 当前:

Container   Carrier
ABC56   Carrier 1
XOS752  Carrier 1
IOW45   Carrier 1
WOFJ74  Carrier 1
NMC85   Carrier 1
DDJD7   Carrier 1
DFF789  Carrier 1
DFF789  Carrier 1
CSGS    Carrier 1
GSW132  Carrier 1
WYWI78  Carrier 1
WTS758  Carrier 1
MNV74   Carrier2
ADS78   Carrier2
CTDS45  Carrier2
CTDS45  Carrier2
LHKGL78 Carrier2
XJSS772 Carrier2
XJSHS7  Carrier2
OIJS7   Carrier2

Desired: 期望的:

ABC56   Carrier 1
XOS752  Carrier 1
IOW45   Carrier 1
WOFJ74  Carrier 1
NMC85   Carrier 1

DDJD7   Carrier 1
DFF789  Carrier 1
DFF789  Carrier 1
CSGS    Carrier 1
GSW132  Carrier 1
WYWI78  Carrier 1

WTS758  Carrier 1

MNV74   Carrier2
ADS78   Carrier2
CTDS45  Carrier2
CTDS45  Carrier2
LHKGL78 Carrier2
XJSS772 Carrier2

XJSHS7  Carrier2
OIJS7   Carrier2

I will take any direction you have! 我会指引你的方向! I have these two codes separately. 我分别有这两个代码。 One Separates by Carrier and One Separates into 5 row increments. “一个按载波分隔”和“一个分隔成5行增量”。 However, It doens't have all the logic built in. 但是,它并没有内置所有逻辑。

To separate into groups of 5: 分成5组:

Option Explicit
    Sub InsertIT()
    Dim x As Integer
    x = 1 'Start Row
    Do
    Range("A" & x, "B" & x).Insert
    x = x + 6
    Loop
    End Sub

To separate by Carrier: 要按运营商分开:

 Sub InsertRowAtChangeInValue()
       For lRow = Cells(Cells.Rows.Count, "B").End(xlUp).Row To 2 Step -1
          If Cells(lRow, "B") <> Cells(lRow - 1, "B") Then Rows(lRow).EntireRow.Insert
       Next lRow
    End Sub

I copied your sample data, and this macro gives me the output you're looking for. 我复制了示例数据,并且此宏为我提供了您正在寻找的输出。

I used a while loop instead of a for loop because VBA records the value for the end of the for loop when it starts, and the number of rows you need to process changes as you insert rows. 我用了while循环,而不是for循环,因为VBA用于记录的终点值for循环启动时,你需要的行数为您插入行过程变化。

I'm using the concept of a counter that increments only when conditions are met to account for the repeat container and carrier rows. 我使用的计数器概念仅在满足条件时才递增,以说明重复的容器行和载体行。

I'm also using the concept of flag-setting to take the correct action when a carrier change is detected. 我还使用标志设置的概念来在检测到载波改变时采取正确的措施。 As you learn and grow in writing vba, if you choose to use flags, remember to reset them as necessary as I've done here. 随着学习和编写vba的不断发展,如果您选择使用标志,请记住要根据需要重置它们,就像我在这里所做的那样。

Finally, I included the user message at the end as a quick cognitive check for the functionality of the macro. 最后,我在最后加入了用户消息,作为对宏功能的快速认知检查。 Based on the user message, you can quickly scroll to the row indicated and check whether the macro processed the whole sheet. 根据用户消息,您可以快速滚动到指示的行,并检查宏是否处理了整个工作表。 I find it helpful to include these messages to check my work and help my users catch errors. 我发现包含这些消息以检查我的工作并帮助我的用户发现错误很有帮助。

If you have questions, please comment! 如有疑问,请发表评论!

Sub RowInsert()

'Designate your data columns
ContainerCol = "A"
CarrierCol = "B"

'Designate where your data starts
FirstDataRow = 2

'Find last row to process
LastRow = Range(ContainerCol & Rows.Count).End(xlUp).Row

'Initialize variable for row counter
RowCount = 0

'Initialize while loop variable
i = FirstDataRow

'Loop while ContainerCol is populated
While Not IsEmpty(Cells(i, ContainerCol))

    'Check if container and carrier are repeated from previous row. Increment counter if no repetition
    If Cells(i, CarrierCol) <> Cells(i - 1, CarrierCol) Or Cells(i, ContainerCol) <> Cells(i - 1, ContainerCol) Then
        RowCount = RowCount + 1
    End If

    'Check if carrier changes on next row
    changeflag = 0 'Variable to indicate if carrier change detected, flag reset
    If Cells(i, CarrierCol) <> Cells(i + 1, CarrierCol) Then
        changeflag = 1
    End If

    'Insert row if carrier changing or 5 rows complete
    If RowCount >= 5 Or changeflag = 1 Then
        Rows(i + 1).EntireRow.Insert
        i = i + 1 'Increment so that the loop picks up at the right spot on the next iteration
        RowCount = 0 'Reset row counter
    End If

    'Increment loop counter
    i = i + 1

Wend

MsgBox ("Separated rows until blank was found at row " & i - 1 & ".")

End Sub

you could avoid loops exploiting a helper column (column C, in my following example): 您可以避免循环利用辅助程序列(在我的以下示例中为C列):

Sub InsertRows()
    With Range("A2", Cells(Rows.Count, "A").End(xlUp)).Offset(, 4)
        With .Offset(1).Resize(.Rows.Count - 1)
            .FormulaR1C1 = "=IF(RC2<>R[-1]C2,1,"""")"
            .Value = .Value
            .SpecialCells(xlCellTypeConstants).EntireRow.Insert
        End With
        .FormulaR1C1 = "=IF(RC2="""",0,IF(RC1<>R[-1]C1,IF(R[-1]C=5,1,R[-1]C+1), R[-1]C))"
        .Value = .Value
        .Replace what:=5, replacement:=""
        .Resize(.Rows.Count - 1).SpecialCells(xlCellTypeBlanks).Offset(1).EntireRow.Insert
        .ClearContents
    End With
End Sub

and you can change the helper column as you need by simply changing .Offset(, 2) to some other .Offset(, n) 并且您可以根据需要通过简单地将.Offset(, 2)更改为其他一些.Offset(, n)来更改帮助器列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM