【问题标题】:Copy data from one excel sheet to another (complex) using VBA based on column name使用基于列名的 VBA 将数据从一个 Excel 工作表复制到另一个(复杂)
【发布时间】:2015-01-20 05:19:25
【问题描述】:

我是 VBA 的新手,在观看视频和谷歌搜索 5 小时后,我认为这太过分了......非常感谢任何帮助。

所以我有 2 个 Excel 工作表:Sheet1 和 Sheet2。我在 Sheet1 中有一个 Y/N 列,如果 column = "Y",那么我想从 Sheet2 中具有匹配列名的行中复制所有数据。

Sheet1
Product     Price     SalesPerson    Date    Commission     Y/N
  A          $25         John       1/9/15      $3           Y 
  B          $20         John       1/12/15     $2           N  
  B          $15         Brad       1/5/15      $1           Y

Sheet2
Price     Product     Date     Salesperson   

因此,每次 Y/N = Y 时,将匹配的数据复制到 sheet2 并执行此操作,直到 sheet1.col1 为空(循环)。结果是这样的:

Sheet2
Price     Product     Date     Salesperson
 $25         A       1/9/15        John
 $15         B       1/5/15        Brad

这些列不按顺序排列,而且太多,无法手动输入。最后但并非最不重要的是,Y/N 列需要在完成后清除。我试图改变这个没有运气:

Sub CopyHeaders()
Dim header As Range, headers As Range
Set headers = Worksheets("Sheet1").Range("A1:Z1")

For Each header In headers
    If GetHeaderColumn(header.Value) > 0 Then
        Range(header.Offset(1, 0), header.End(xlDown)).Copy Destination:=Worksheets("Sheet2").Cells(2, GetHeaderColumn(header.Value)).End(xlDown).Offset(1, 0)
    End If
Next
End Sub

Function GetHeaderColumn(header As String) As Integer
Dim headers As Range
Set headers = Worksheets("Sheet2").Range("A1:Z1")
GetHeaderColumn = IIf(IsNumeric(Application.Match(header, headers, 0)), Application.Match(header, headers, 0), 0)
End Function

这旨在做一些与我正在尝试做的不同的事情,我认为我无法改变它来为我工作。我该怎么做?

【问题讨论】:

  • 我将做更多的研究并更新它,但我无法让这段代码工作......可能是由于 sheet2 包含不在 sheet1 中的列

标签: vba excel header


【解决方案1】:

好的,现在如果 Sheet2 中的列在 Sheet1 中不存在,它也可以工作。

子 CopySheet() 将 i 调暗为整数 将 LastRow 调暗为整数 暗淡搜索为字符串 将列调暗为整数

Sheets("Sheet1").Activate
Sheets("Sheet1").Range("A1").Select
'Sets an Autofilter to sort out only your Yes rows.
Selection.Autofilter
'Change Field:=5 to the number of the column with your Y/N.
Sheets("Sheet1").Range("$A$1:$G$3").Autofilter Field:=7, Criteria1:="Y"

'Finds the last row
LastRow = Sheets("Sheet1").Cells(Sheets("Sheet1").Rows.Count, "A").End(xlUp).Row

i = 1
'Change the 3 to the number of columns you got in Sheet2
Do While i <= 3
    Search = Sheets("Sheet2").Cells(1, i).Value
    Sheets("Sheet1").Activate
    'Update the Range to cover all your Columns in Sheet1.
    If IsError(Application.Match(Search, Sheets("sheet1").Range("A1:G1"), 0)) Then
        'nothing
    Else
        Column = Application.Match(Search, Sheets("sheet1").Range("A1:G1"), 0)
        Sheets("Sheet1").Cells(2, Column).Resize(LastRow, 1).Select
        Selection.Copy
        Sheets("Sheet2").Activate
        Sheets("Sheet2").Cells(2, i).Select
        ActiveSheet.Paste
    End If
    i = i + 1
Loop

'Clear all Y/N = Y
'Update the Range to cover all your Columns in Sheet1.
Sheets("Sheet1").Activate
Column = Application.Match("Y/N", Sheets("sheet1").Range("A1:G1"), 0)
Sheets("Sheet1").Cells(2, Column).Resize(LastRow, 1).Select
Selection.ClearContents
End Sub

【讨论】:

  • 所以我的 sheet2 确实有不在 sheet1 中的列 :(
  • 即使 sheet2 中存在 sheet1 中不存在的列,也将其更改为工作。
【解决方案2】:

您也可以尝试此操作,前提是列如您上面提到的那样(sheet1 中的 A 到 F,sheet2 中的 A 到 D)。

Sub copies()
    Dim i, j, row As Integer
    j = Worksheets("sheet1").Range("A1").End(xlDown).row
    For i = 1 To j
        If Cells(i, 6) = "Y" Then _
        row = Worksheets("sheet2").Range("A1").End(xlDown).row + 1
        Worksheets("sheet2").Cells(row, 1) = Worksheets("sheet1").Cells(i, 2)
        Worksheets("sheet2").Cells(row, 2) = Worksheets("sheet1").Cells(i, 1)
        Worksheets("sheet2").Cells(row, 3) = Worksheets("sheet1").Cells(i, 4)
        Worksheets("sheet2").Cells(row, 4) = Worksheets("sheet1").Cells(i, 3)
    Next
    Worksheets("sheet1").Range("F:F").ClearContents
End Sub

【讨论】:

    【解决方案3】:

    在进一步研究这个问题时,我正在考虑为标题创建一个静态数组......然后 user3561813 提供了这个 gem(我为我的 if 语句稍微改变了它并循环遍历工作表:

    Sub validatetickets()
    
    Do Until ActiveCell.Value = ""
    If Cells(ActiveCell.Row, 43) = "Y" Then
    
    Dim wsOrigin As Worksheet
    Dim wsDest As Worksheet
    Dim nCopyRow As Long
    Dim nPasteRow As Long
    Dim rngFnd As Range
    Dim rngDestSearch As Range
    Dim cel As Range
    
    Const ORIGIN_ROW_HEADERS = 1
    Const DEST_ROW_HEADERS = 1
    
    
    Set wsOrigin = Sheets("Case")
    Set wsDest = Sheets("Sheet1")
    
    nCopyRow = ActiveCell.Row
    nPasteRow = wsDest.Cells(Rows.Count, 1).End(xlUp).Row + 1
    
    Set rngDestSearch = Intersect(wsDest.UsedRange, wsDest.Rows(DEST_ROW_HEADERS))
    
    For Each cel In Intersect(wsOrigin.UsedRange, wsOrigin.Rows(ORIGIN_ROW_HEADERS))
    On Error Resume Next
        Set rngFnd = rngDestSearch.Find(cel.Value)
    
        If rngFnd Is Nothing Then
            'Do Nothing as Header Does not Exist
        Else
            wsDest.Cells(nPasteRow, rngFnd.Column).Value = wsOrigin.Cells(nCopyRow, cel.Column).Value
        End If
    On Error GoTo 0
    
    Set rngFnd = Nothing
    Next cel
    ActiveCell.Offset(1, 0).Select
    Else: ActiveCell.Offset(1, 0).Select
    End If
    
    Loop
    End Sub
    

    它的工作方式非常巧妙,并且具有很强的可扩展性。不依赖于具有相同列等的两张纸......我可以看到这在未来非常有用。 :)

    【讨论】:

      猜你喜欢
      • 2018-02-08
      • 2013-10-26
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 2017-02-26
      • 2017-02-14
      • 2016-11-19
      • 1970-01-01
      相关资源
      最近更新 更多