首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Excel VBA:从前5行/单元格中筛选和复制

Excel VBA:从前5行/单元格中筛选和复制
EN

Stack Overflow用户
提问于 2015-04-14 16:59:54
回答 6查看 9.1K关注 0票数 2

我有一个数据表,在F列中按降序排序。然后,我需要复制前5行,但只需要从A、B、D和F列(而不是头)中复制数据。看照片。

代码语言:javascript
复制
Sub top5()

Sheets("Sheet1").Select

If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If


ActiveSheet.Range("$A$4:$T$321").AutoFilter Field:=3, Criteria1:="Dave"
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields. _
    Clear
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add _
    Key:=Range("F4:F321"), SortOn:=xlSortOnValues, Order:=xlDescending, _
    DataOption:=xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With

' This copy-paste part does what its supposed to, but only for the specific 
' cells.  Its not generalised and I will have to repeat this operation
' several times for different people
Sheets("Sheet1").Select
Range("A3:B15").Select
Selection.Copy

Sheets("Sheet2").Select
Range("A3").Select
ActiveSheet.Paste

Sheets("Sheet1").Select
Range("D3:D15").Select
Application.CutCopyMode = False
Selection.Copy

Sheets("Sheet2").Select
Range("C3").Select
ActiveSheet.Paste

Sheets("Sheet1").Select
Range("F3:F15").Select
Application.CutCopyMode = False
Selection.Copy

Sheets("Sheet2").Select
Range("D3").Select
ActiveSheet.Paste
Application.CutCopyMode = False

End Sub

我想过尝试使用可见单元函数来修改下面的代码片段,但是我被困住了,在网络上找不到适合我的东西。

代码语言:javascript
复制
' This selects all rows (plus 1, probably due to offset), I only want parts of from the top 5.
Sheets("Sheet1").Select
ActiveSheet.Range("$A$4:$B$321").Offset(1, 0).SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("Sheet2").Select
Range("A3").Select
ActiveSheet.Paste

Sheets("Sheet1").Select
ActiveSheet.Range("$D$4:$D$321").Offset(1, 0).SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("Sheet2").Select
Range("C3").Select
ActiveSheet.Paste

我希望我的榜样是合理的,我真的很感谢你的帮助!

注意:两个表中的标题名称只是相同的,以表明数据是相同的。头不应该被复制。此外,在第二个表中还有一个额外的列/空白。解决方案应包括这一点。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2015-04-29 23:49:18

首先,有几点是有帮助的:

  • 您应该参考代码名旁边的工作表,以避免重命名问题。
  • 如果您想使用VBA,那么我的建议是避免像瘟疫一样合并的单元格。它们会对代码造成破坏。如果可能的话使用格式单元格.对齐.水平中心交叉选择
  • 在可能的情况下,我还向避环提供建议,并将其作为一个良好的实践练习,利用内置函数中的优秀功能。

这是我的解决办法。保持简单。如果你需要进一步的帮助,现在就让我。

代码语言:javascript
复制
Sub HTH()

    Dim rCopy As Range

    With Sheet1.AutoFilter.Range
        '// Set to somewhere blank and unused on your worksheet
        Set rCopy = Sheet1.Range("A" & Rows.Count - (.Rows.Count))
        .SpecialCells(xlCellTypeVisible).Copy rCopy
    End With

    With rCopy.Offset(1).Resize(5) '// Offset to avoid the header
        .Resize(, 2).Copy Sheet2.Range("A5")
        .Offset(, 3).Resize(, 1).Copy Sheet2.Range("D5")
        .Offset(, 5).Resize(, 1).Copy Sheet2.Range("F5")
        .CurrentRegion.Delete xlUp '// Delete the tempory area
    End With

    Set rCopy = Nothing

End Sub
票数 2
EN

Stack Overflow用户

发布于 2015-04-14 17:48:06

一个快速的方法是使用UnionIntersect只复制您想要的单元格。如果您正在粘贴值(或者数据不是要开始的公式),这将很好地工作。考虑到这一点,它构建了一系列列,以便继续使用Union,然后使用带有头5行和头2行的Intersect。结果是只复制了您想要的格式完整的数据。

编辑只处理可见的行,抓取标题,然后在标题行下面的前5行()。

代码语言:javascript
复制
Sub CopyTopFiveFromSpecificColumns()

    'set up the headers first to keep
    Dim rng_top5 As Range
    Set rng_top5 = Range("3:4").EntireRow

    Dim int_index As Integer
    'start below the headers and keep all the visible cells
    For Each cell In Intersect( _
        ActiveSheet.UsedRange.Offset(5), _
        Range("A:A").SpecialCells(xlCellTypeVisible))

        'add row to keepers
        Set rng_top5 = Union(rng_top5, cell.EntireRow)

        'track how many items have been stored
        int_index = int_index + 1
        If int_index >= 5 Then
            Exit For
        End If
    Next cell

    'copy only certain columns of the keepers
    Intersect(rng_top5, _
        Union(Range("A:A"), _
                Range("B:B"), _
                Range("D:D"), _
                Range("F:F"))).Copy

    'using Sheet2 here, you can set to wherever, works if data is not formulas
    Range("Sheet2!A1").PasteSpecial xlPasteAll

    'if the data contains formulas, use this route
    'Range("Sheet2!A1").PasteSpecial xlPasteValues
    'Range("Sheet2!A1").PasteSpecial xlPasteFormats

End Sub

以下是在与上面的图片相同的范围内设置的一些虚拟数据的结果。

复制范围可见的Sheet1

Sheet2与粘贴数据

票数 1
EN

Stack Overflow用户

发布于 2015-04-26 13:58:35

您问题的第一部分,选择top5可见单元格相对容易,复制和粘贴是问题所在。你看,你不能粘贴一个范围,即使它不是均匀的,到非均匀的范围。因此,您需要编写自己的粘贴函数。

第1部分-获取Top5行

我使用了与@Byron类似的技术。注意,这仅仅是一个返回Range对象并接受String的函数,它表示您的非均匀范围(如果您愿意,可以将参数类型更改为Range )。

代码语言:javascript
复制
Function GetTop5Range(SourceAddress As String) As Range
    Dim rngSource As Range
    Dim rngVisible As Range
    Dim rngIntersect As Range
    Dim rngTop5 As Range

    Dim i As Integer
    Dim cell As Range

    Set rngSource = Range(SourceAddress)
    Set rngVisible = rngSource.SpecialCells(xlCellTypeVisible).Cells
    Set rngIntersect = Intersect(rngVisible, rngVisible.Cells(1, 1).EntireColumn)

    i = 1
    For Each cell In rngIntersect
        If i = 1 Then
            Set rngTop5 = cell.EntireRow
            i = i + 1
        ElseIf i > 1 And i < 6 Then
            Set rngTop5 = Union(rngTop5, cell.EntireRow)
            i = i + 1
        Else
            Exit For
        End If
    Next cell

    Set GetTop5Range = Intersect(rngTop5, rngVisible)
End Function

第2部分-创建自己的粘贴函数

因为Excel总是将复制的范围粘贴成统一的,所以您需要自己动手。此方法本质上将源区域分解为列并单独粘贴它们。该方法接受Range类型的参数Range(按Top5范围表示),接受Range类型的TopLeftCornerRange,后者表示粘贴的目标单元格。

代码语言:javascript
复制
Sub PasteRange(SourceRange As Range, TopLeftCornerRange As Range)
    Dim rngColumnRange As Range

    Dim cell As Range

    Set rngColumnRange = Intersect(SourceRange, SourceRange.Cells(1, 1).EntireRow)

    For Each cell In rngColumnRange
        Intersect(SourceRange, cell.EntireColumn).Copy
        TopLeftCornerRange.Offset(0, cell.Column - 1).PasteSpecial xlPasteValuesAndNumberFormats
    Next cell

    Application.CutCopyMode = False
End Sub

第3部分-运行过程

代码语言:javascript
复制
Sub Main()
    PasteRange GetTop5Range("A2:B33,D2:D33"), Range("A35")
End Sub

就这样。

在我的项目中,和您一样,我在A、B和D列中有源数据,结果被粘贴到从A35开始的范围。

结果:

希望这能有所帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29633244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档