动态相同项目行转列

需求:今天中午朋友圈有人问怎么把快速填充数据,我看了一下是行转列的问题,就写了一段宏代码,记录一下。

图1需求

分析一下需求:就是把相同项目的列数据转换为一行数据,每个项目数量并不固定(图1)。

话不多说直接上结果(图3),简单处理了一下,生成的原生的有点丑,哈哈哈

图2原生结果

图3最终结果

实现过程:

  • 首先想到的是VLOOKUP函数,但是他只能查找到第一次出现的值,不符合要求,放弃。
  • 写代码,代码如下
Sub MergeProjectData()
    
    
    Dim dict As Object
    Dim dataRng As Range, headerRow As Range
    Dim arrData, arrResult()
    Dim i As Long, j As Long, k As Long
    Dim projectCol As Long, maxCount As Long
    Dim key As Variant, delimiter As String
    Dim wsSource As Worksheet, wsDest As Worksheet
    
    ' ========== 用户配置 ==========
    Set wsSource = ThisWorkbook.Sheets("Sheet6")  ' 原始数据表
    Set wsDest = ThisWorkbook.Sheets.Add(After:=wsSource) ' 结果输出到新表
    projectCol = 1   ' 项目名称所在列号(A列=1,B列=2...)
    delimiter = "|"  ' 明细分隔符
    ' =============================
    
    ' 获取数据区域
    Set headerRow = wsSource.UsedRange.Rows(1)
    Set dataRng = wsSource.UsedRange.Offset(1).Resize(wsSource.UsedRange.Rows.Count - 1)
    arrData = dataRng.Value
    
    ' 创建字典存储项目数据
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' 遍历原始数据
    For i = 1 To UBound(arrData, 1)
        Dim projectName As String
        projectName = arrData(i, projectCol)
        
        ' 跳过空项目
        If projectName = "" Then GoTo NextRow
        
        ' 记录最大明细行数
        If dict.Exists(projectName) Then
            dict(projectName)("count") = dict(projectName)("count") + 1
            If dict(projectName)("count") > maxCount Then maxCount = dict(projectName)("count")
        Else
            dict.Add projectName, CreateObject("Scripting.Dictionary")
            dict(projectName).Add "count", 1
            maxCount = Application.Max(maxCount, 1)
            
            ' 初始化项目首行数据
            For j = 1 To UBound(arrData, 2)
                dict(projectName).Add j, arrData(i, j)
            Next j
        End If
        
        ' 添加明细数据(从第二列开始)
        For j = 1 To UBound(arrData, 2)
            If j <> projectCol Then
                Dim currentKey As String
                currentKey = j & "_" & dict(projectName)("count")
                dict(projectName).Add currentKey, arrData(i, j)
            End If
        Next j
NextRow:
    Next i
    
    ' 构建结果数组
    ReDim arrResult(1 To dict.Count, 1 To UBound(arrData, 2) + (maxCount - 1) * (UBound(arrData, 2) - 1))
    
    ' 填充结果数据
    k = 1
    For Each key In dict.keys()
        ' 写入首列数据
        For j = 1 To UBound(arrData, 2)
            arrResult(k, j) = dict(key)(j)
        Next j
        
        ' 写入合并明细
        Dim detailCount As Long
        detailCount = dict(key)("count")
        
        For detailCount = 2 To dict(key)("count")
            For j = 1 To UBound(arrData, 2)
                If j <> projectCol Then
                    Dim targetCol As Long
                    targetCol = UBound(arrData, 2) + (detailCount - 2) * (UBound(arrData, 2) - 1) + (j - 1)
                    arrResult(k, targetCol) = dict(key)(j & "_" & detailCount)
                End If
            Next j
        Next detailCount
        k = k + 1
    Next key
    
    ' 输出结果
    With wsDest
        ' 写入标题(自动扩展列)
        headerRow.Copy .Range("A1")
        For i = 2 To maxCount
            For j = 1 To UBound(arrData, 2)
                If j <> projectCol Then
                    .Cells(1, .Columns.Count).End(xlToLeft).Offset(0, 1) = _
                        headerRow.Cells(1, j).Value & i
                End If
            Next j
        Next i
        
        ' 写入数据
        .Range("A2").Resize(dict.Count, UBound(arrResult, 2)) = arrResult
        
        ' 格式优化
        .UsedRange.WrapText = False
        .UsedRange.EntireColumn.AutoFit
        .Cells(1, 1).Select
    End With
    
    MsgBox "合并完成!共处理 " & dict.Count & " 个项目", vbInformation
End Sub
  • 注意事项

    ' ========== 用户配置 ==========

    Set wsSource = ThisWorkbook.Sheets("Sheet6")  ' 原始数据表

    Set wsDest = ThisWorkbook.Sheets.Add(After:=wsSource) ' 结果输出到新表

    projectCol = 1   ' 项目名称所在列号(A列=1,B列=2...)

    delimiter = "|"  ' 明细分隔符

' =============================

第一行代码,ThisWorkbook.Sheets("Sheet6"),看一下自己的数据是在哪一个sheet,就把sheet6改成对应sheet;

第三行代码,projectCol = 1,要分组的项目名称在第几列就把1改成几。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值