【问题标题】:Copy Data from One workbook to another using column header使用列标题将数据从一个工作簿复制到另一个工作簿
【发布时间】:2016-12-20 23:14:12
【问题描述】:

有没有人有一段代码可以根据列标题从一个 excel WB 复制到另一个?

更新: 对不起,我是这个网站的新手,希望你能原谅我的无知。

这是我根据其他人的帖子尝试过的代码(谢谢你,Simon!)。

Sub copy_cols()

    Set SourceWS = Workbooks("Source.xlsx").Worksheets(1)
    Set TargetWS = Workbooks("Business Loader V7.1.xlsx").Worksheets(2)

For Each rgCell In SourceWS.Range("A1:AX1")

TargetWS.Columns(GetColumn(TargetWS, rgCell.Value)) = _
 SourceWS.Columns(GetColumn(SourceWS, rgCell.Value))
' I Have also tried this with no success:
' TargetWS.Columns(GetColumn(TargetWS, rgCell.Value)) = _
 SourceWS.Columns(GetColumn(SourceWS, rgCell.Column))

End Sub

Function GetColumn(GCSheet As Worksheet, ColumnName As String) As Integer
    Dim intCol As Integer

    On Error Resume Next
    intCol = Application.WorksheetFunction.Match(ColumnName, GCSheet.Rows(1), 0)
    If Err.Number <> 0 Then
        GetColumn = 0
    Else
        GetColumn = intCol
    End If
End Function

我在 TargetWS.Cells 的第一行和第 5 行(不包括计数时的空格)收到错误“ByRef 参数类型不匹配”......

我也有这个......它有效,但我必须添加一堆 .End(xlDown) 来解决丢失的信息,以便复制整个列(不仅仅是复制到下一个有值的单元格)。你有更好的系统来解决这个问题吗?

Sub CopyHeaders()
    Dim header As Range, headers As Range

    Set SourceWS = Workbooks("Source.xlsx").Worksheets(1)
    Set TargetWS = Workbooks("Business Loader V7.1.xlsx").Worksheets(2)

    Set headers = SourceWS.Range("A1:AX1")

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

如您所见,我必须为每个空白单元格添加 .End(xlDown)。提前感谢您提供的任何帮助。

【问题讨论】:

  • 向我们提供更多信息以及您迄今为止所做的尝试
  • 在该单元格分配下添加一个 .value 即 ....cells.value = ....cells.value 您还错误地使用了 GetColumn 函数:获取列标题,不要只是使用 rgcell.value,使用类似 sourcews.cells(1,rgcell.column).value ... 这将为您提供当前单元格的列标题
  • @Simon 谢谢,我完全糊涂了,但我会试着整理一下你所说的。您是指上面的代码还是下面列出的其他代码之一?
  • 是的,指的是上面。抱歉,我想我错过了您的代码... rgCell.value 是我可以看到的列标题....所以您要复制整个列?使用 wsDestination.columns(GetColumn(...)) = wsSource.columns(GetColumn(...))
  • @Simon,Simon,我已经更新了代码,但在上面找到的第一个代码的第 9 行出现“ByRef 参数类型不匹配”错误。 intDestRow 和 intSourceRow 有什么作用?我尝试了几个不同版本的编辑 '(GetColumn(STUFF)) = ' 行,但我似乎无法做到这一点。

标签: vba excel


【解决方案1】:

以下代码应该可以根据您的需要进行更改...

Sub CopyByHeader()

    Dim SourceWS As Worksheet
    Set SourceWS = Workbooks("Source.xlsx").Worksheets(1)
    Dim SourceHeaderRow As Integer: SourceHeaderRow = 1

    Dim TargetWS As Worksheet
    Set TargetWS = Workbooks("Business Loader V7.1.xlsx").Worksheets(2)
    Dim TargetHeader As Range
    Set TargetHeader = TargetWS.Range("A1:AX1")

    Dim RealLastRow As Long
    Dim SourceCol As Integer

    SourceWS.Activate            
    For Each Cell In TargetHeader
        SourceCol = SourceWS.Rows(SourceHeaderRow).Find _
            (Cell.Value, LookIn:=xlValues, LookAt:=xlWhole).Column
        If SourceCol <> 0 Then
            RealLastRow = SourceWS.Columns(SourceCol).Find("*", LookIn:=xlValues, _
                 SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
            SourceWS.Range(Cells(SourceHeaderRow + 1, SourceCol), Cells(RealLastRow, _
                  SourceCol)).Copy
            TargetWS.Cells(2, Cell.Column).PasteSpecial xlPasteValues
        End If
    Next

End Sub

更新:一些错误的标题不在源表或空列中。 还值得注意的是,使用此代码 - 您必须打开“Source.xlsx”才能从中读取。

更新代码:

Sub CopyByHeader()

    Dim CurrentWS As Worksheet
    Set CurrentWS = ActiveSheet

    Dim SourceWS As Worksheet
    Set SourceWS = Workbooks("Source.xlsx").Worksheets(1)
    Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
    Dim SourceCell As Range

    Dim TargetWS As Worksheet
    Set TargetWS = Workbooks("Business Loader V7.1.xlsx").Worksheets(2)
    Dim TargetHeader As Range
    Set TargetHeader = TargetWS.Range("A1:AX1")

    Dim RealLastRow As Long
    Dim SourceCol As Integer

    SourceWS.Activate
    For Each Cell In TargetHeader
        If Cell.Value <> "" Then
            Set SourceCell = Rows(SourceHeaderRow).Find _
                (Cell.Value, LookIn:=xlValues, LookAt:=xlWhole)
            If Not SourceCell Is Nothing Then
                SourceCol = SourceCell.Column
                RealLastRow = Columns(SourceCol).Find("*", LookIn:=xlValues, _
                SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
                If RealLastRow > SourceHeaderRow Then
                    Range(Cells(SourceHeaderRow + 1, SourceCol), Cells(RealLastRow, _
                        SourceCol)).Copy
                    TargetWS.Cells(2, Cell.Column).PasteSpecial xlPasteValues
                End If
            End If
        End If
    Next

    CurrentWS.Activate

End Sub

【讨论】:

  • 我无法让它工作。在第 14 行有一个错误“对象变量或未设置块变量”。在我的 VBA 中, Cell.Value 没有对单元格部分进行大写,所以它看起来像 (cell.Value... 而不是 (Cell.Value...
  • 我已将 SourceWS.Activate 行添加到代码中。这可能是错误的原因;它在工作表之间的单个工作簿中对我有用,但请检查它是否适用于您的工作簿
  • 嗨@Flephal,我觉得这好像很接近,但是在“SourceWS.Range(Cells(...”行)给我带来了一些麻烦。错误消息是“Method 'Range '对象'_Worksheet'失败”。
  • 更改为去掉对“SourceWS”的要求。在代码中。多年来,我发现跨工作表的代码要正常工作可能有点麻烦,因为似乎可行的编码并不能正常工作......希望现在编辑应该可以工作!!!
  • 嗨@Flephal,对不起,我的朋友,我在你编辑代码之前编辑了帖子说:“谢谢!它就像一个梦!谢谢谢谢谢谢。 “但由于某种原因,编辑没有坚持下去。我的问题是我没有将 Source.xlsx 作为最重要的 excel 工作簿,当我单击 WB 并使其处于活动状态时,它运行良好。
【解决方案2】:
Function GetColumn(GCSheet As Worksheet, ColumnName As String) As Integer
    Dim intCol As Integer

    On Error Resume Next
    intCol = Application.WorksheetFunction.Match(ColumnName, GCSheet.Rows(1), 0)
    If Err.Number <> 0 Then
        GetColumn = 0
    Else
        GetColumn = intCol
    End If
End Function

将其用于您的源工作表和目标。您也可以使用“查找”。这假设您的列在第 1 行。

那么这只是一种情况

wsDestination.cells(intDestRow, GetColumn(wsDestination, "ColumnName")).value = _
    wsSource.cells(intSourceRow,GetColumn(wsSource, "ColumnName")).value

【讨论】:

  • 或'对于SourceHeader中的每个rgCell,Destination.cells(intDestRow, GetColumn(wsDestination, rgCell.value) = wsSource.cells(intSourceRow, rgCell.column)
  • 嗨@Simon,感谢cmets,我还没有尝试实现你的代码。我有一个答案我想听听你的意见,但是我不能
  • hmm 可能没有足够的代表来回答你自己的问题或其他什么......看看你的进展,如果你仍然坚持,我想一起发一个新帖子:)
  • 非常感谢您提供的所有帮助,我已经编辑了原始帖子,以便您更好地了解我要实现的目标。再次感谢,非常感谢您的帮助。
  • @Flephal!有用!!!!!!!非常感谢!!!这是最好的。现在,如果我只能让“GetColumn”功能从上面工作,我将成为一个快乐的人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 2017-02-26
相关资源
最近更新 更多