【问题标题】:VBA Excel- Copying Rows based on two columns having matching dataVBA Excel-基于具有匹配数据的两列复制行
【发布时间】:2018-09-01 02:25:53
【问题描述】:

我在进行核对时遇到了问题,我的一些资产子项与父母的使用状态、所有权等不符。我需要将所有父母拉到一个新表中,以手动验证所有数据是否正确。这是我的问题的第一部分。

Example

如上所示。

在第 4997 行,两个 EQ 编号匹配。这是父行。我需要将 B 列和 C 列中具有匹配 EQ 编号的所有行复制到单独的工作表中。然后我将手动编辑它们,以便所有其他列与我们的实际书籍准确无误。

这是我的第一个问题。

除此之外,还有一个单独的问题。

然后我需要在单独的工作表中获取所有已更改的信息,并将原始工作表中的旧父信息替换为新的父信息。 从那里开始,我需要让所有孩子都反映相同的信息。正如您在示例中看到的,第 4997 行上的父级读取为已租用,但其下方的所有子级读取为可用。 我需要所有子级的 E、F、G、H、I 和 J 列,以反映这些列中与父级相同的信息。

所有子代在列 C 中反映与父代相同的 EQ 编号。EQ0005212。

这是一个很大的列表,有 1000 多个父母。

我找到了与我想做的类似的事情,但它并不完全符合我的需要。

Option Explicit

Sub Test()

Dim rngCell As Range
Dim lngLstRow As Long
Dim keywords() As String
Dim maxKeywords, i, j, k As Integer


maxKeywords = 6
ReDim keywords(1 To maxKeywords)

keywords(1) = "_LC"
keywords(2) = "_LR"
keywords(3) = "_LF"
keywords(4) = "_W"
keywords(5) = "_R"
keywords(6) = "_RW"

lngLstRow = ActiveSheet.UsedRange.Rows.Count

For j = 1 To lngLstRow
  For i = 1 To maxKeywords
    If keywords(i) = Right(Sheets("Results").Range("L" & j).Value,     
Len(keywords(i))) Or _
      keywords(i) = Right(Sheets("Results").Range("M" & j).Value, 
Len(keywords(i))) Then
        k = k + 1
          Rows(j & ":" & j).Copy
            Sheets("sheet1").Select
              Range("A" & k).Select
                ActiveSheet.Paste
    End If
  Next i
Next j

End Sub

如果您能解决第一个问题,我们将不胜感激,但如果您能找到第二个问题的解决方案,我将永远欠您的债。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    嗯,我已经解决了你的第一个问题,直到明天我才能解决第二个问题,如果到那时没有人这样做,我有一个想法。 编辑:请参阅下面的编辑,我保证我会回来 :)

    Sub findParent()
        Dim masterWs As New Worksheet
        Dim masterEndRc As Long
        Set masterWs = Sheets("Sheet1")
    
        Dim parentWs As New Worksheet
        Set parentWs = Sheets("Sheet2")
    
        Dim masterCounter As Long
        Dim parentCounter As Long
        parentCounter = 1
        masterCounter = 1
        Dim colBStr As String 'set up temp variables, you could compare values directly
        Dim colCstr As String 'but call me crazy, i think that this way is more accurate
    
        masterEndRc = masterWs.UsedRange.Rows.Count
    
        Do
            colBStr = masterWs.Cells(masterCounter, "B").Value 'Load the value into the temp variables
            colCstr = masterWs.Cells(masterCounter, "C").Value
    
            If colBStr = colCstr Then
                masterWs.Cells(masterCounter, "B").EntireRow.Cut parentWs.Cells(parentCounter, "A")
                parentWs.Cells(parentCounter, "E").Value = masterCounter 'Make this the first empty column, this is so that we can find its original row
                'for reinsert later
                parentCounter = parentCounter + 1
            End If
            masterCounter = masterCounter + 1
        Loop While masterCounter <= masterEndRc
    End Sub
    

    编辑

    好的,第二个问题解决了 :) 确保更改任何变量以匹配您的工作表,例如列和工作表名称。运行上面宏下的第一个子程序,然后运行下面的第二个子程序。

    Sub restoreParent()
        Dim masterWs As New Worksheet
        Dim masterEndRc As Long
        Set masterWs = Sheets("Sheet1")
    
        Dim parentWs As New Worksheet
        Set parentWs = Sheets("Sheet2")
        Dim parentEndRc As Long
        Dim parentCounter As Long
        Dim oldRowLong As Long
        Dim rowColl As New Collection 'for storing of the parent row numbers for use while changing child rows later
        parentEndRc = parentWs.UsedRange.Rows.Count
        parentCounter = 1
    
        Do
            oldRowLong = parentWs.Cells(parentCounter, "E").Value
            rowColl.Add oldRowLong
            parentWs.Cells(parentCounter, "B").EntireRow.Cut masterWs.Cells(oldRowLong, "A")
            parentCounter = parentCounter + 1
        Loop While parentCounter <= parentEndRc
    
        changeChildRows rowColl, masterWs
    End Sub
    
    Function changeChildRows(rowColl As Collection, masterWs As Worksheet)
        Dim nextChildRow As Long
        Dim childRowCounter As Long
        Dim parentRow As Variant
        Dim firstChild As Boolean
        firstChild = True
    
        For Each parentRow In rowColl
            childRowCounter = parentRow
            Do
                If firstChild = True Then
                    nextChildRow = parentRow + 1
                    If masterWs.Cells(parentRow, "C").Value = masterWs.Cells(nextChildRow, "C") Then
                        masterWs.Cells(nextChildRow, "D").Value = masterWs.Cells(parentRow, "D").Value 'Make sure to change these column values to match yours
                    End If
                    firstChild = False
                ElseIf firstChild = False Then
                    nextChildRow = nextChildRow + 1
                    If masterWs.Cells(parentRow, "C").Value = masterWs.Cells(nextChildRow, "C") Then
                        masterWs.Cells(nextChildRow, "D").Value = masterWs.Cells(parentRow, "D").Value 'Make sure to change these column values to match yours
                    End If
                End If
            childRowCounter = childRowCounter + 1
            Loop Until masterWs.Cells(childRowCounter, "C").Value <> masterWs.Cells(parentRow, "C").Value
            firstChild = True
        Next parentRow
    End Function
    

    【讨论】:

      【解决方案2】:

      如果您不重复此操作,我建议您不要使用 VBA。

      只需添加一个带有公式的列:=IF(B1 = C1;1;0)(拖动它)或更简单的 =B1=C1。如果它们匹配,您将获得 1(否则为 0),然后您可以过滤所有父母并复制到新的工作表/文件。

      编辑父母后,在您的表格中的 E、F、G、H、I 和 J 列中只需放置 INDEX MATCH 公式(或更糟糕的 VLookup)(当然是拖动它们)。您应该将 C 列与该编辑表中的父母编号进行比较(您可以选择 B 或 C,因为如果您使用的是 INDEX MATCH,它们是相同的,VLookup 不是那么方便)。有很多很好的教程如何使用这些功能。

      如果你真的想要vba,基本上可以记录下来,稍微修改一下。

      【讨论】:

        猜你喜欢
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多