Excel·VBA表格横向、纵向相互转换

这篇具有很好参考价值的文章主要介绍了Excel·VBA表格横向、纵向相互转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Excel·VBA表格横向、纵向相互转换,excel,vba,excel,vba,横向转换,纵向转换
如图:对图中区域 A1:M6 横向表格,转换成区域 A1:C20 纵向表格,即 B:M 列转换成每2列一组按行写入,并删除空行。同理,反向操作就是纵向表格转换成横向表格

横向转纵向

实现方法1

本文图1中,按“交期和交货数量”每5行2列为一组,依次按行写入,即按“交期”顺序排列

Sub 表格横向转纵向1()
    '分段转换,转换列之前同名不连续;不使用动态获取每行最后一列是考虑到部分选中拆分
    Dim num_col&, title_row&, del_empty As Boolean, rng As Range, del_rng As Range
    Dim first_col&, resize_r&, resize_c&, keep_rng, arr, brr, b$, r&, i&, j&
'--------------------参数填写:num_col、title_row都为数字,选中后才可运行代码
    num_col = 2    '需要拆分的数据每行固定的列数
    title_row = 1  '表头行数
    del_empty = True  '是否删除空行
    If Selection.Count = 1 Then Debug.Print "未选中列,无法运行代码": Exit Sub
    Set rng = Intersect(ActiveSheet.UsedRange, Selection)  'intersect语句避免选择整列造成无用计算
    '选中区域开始列号,转换行数、列数
    first_col = rng.column: resize_r = rng.Rows.Count - title_row: resize_c = rng.Columns.Count
    If resize_c Mod num_col <> 0 Then Debug.Print "选中列数不可平分": Exit Sub
    
    With ActiveSheet
        keep_rng = .Cells(title_row + 1, 1).Resize(resize_r, first_col - 1)  '不变区域
        arr = .Cells(title_row + 1, first_col).Resize(resize_r, resize_c)    '转换区域
        r = title_row + 1  '写入行号
        For i = num_col + 1 To UBound(arr, 2) Step num_col
            r = r + resize_r: .Cells(r, 1).Resize(resize_r, first_col - 1) = keep_rng
            For j = 1 To num_col
                brr = Application.index(arr, , i + j - 1)  '按列拆分
                .Cells(r, first_col + j - 1).Resize(resize_r, 1) = brr
            Next
        Next
        If del_empty Then  '删除空行
            For i = title_row + 1 To r + resize_r
                brr = .Cells(i, first_col).Resize(1, num_col)
                If num_col > 1 Then  'brr是否为数组
                    b = Join(WorksheetFunction.Transpose(WorksheetFunction.Transpose(brr)), "")
                ElseIf num_col = 1 Then
                    b = brr
                End If
                If Len(b) = 0 Then
                    If del_rng Is Nothing Then
                        Set del_rng = .Rows(i)
                    Else
                        Set del_rng = Union(del_rng, .Rows(i))
                    End If
                End If
            Next
            If Not del_rng Is Nothing Then del_rng.Delete  '删除行
        End If
        .Cells(1, first_col + num_col).Resize(1, resize_c - num_col).EntireColumn.Delete  '删除选中列
    End With
End Sub
转换结果

本文图1(转换前不含7-20行),选中 B:M 列,运行代码得到如下图结果: D:M 列被删除
Excel·VBA表格横向、纵向相互转换,excel,vba,excel,vba,横向转换,纵向转换

实现方法2

本文图1中,按“产品规格”每个产品后面6组“交期和交货数量”转换为每6行2列,依次按行写入,即按“产品”顺序排列

以下代码使用了数组行列数转换函数,调用了wraparr函数,代码详见《Excel·VBA单元格区域行列数转换函数》(如需使用代码需复制)

Sub 表格横向转纵向2()
    '按行转换,转换列之前同名连续;不使用动态获取每行最后一列是考虑到部分选中拆分
    Dim num_col&, title_row&, del_empty As Boolean, rng As Range, del_rng As Range
    Dim first_col&, last_row&, resize_r&, resize_c&, keep_rng, arr, brr, b$, r&, i&, j&
'--------------------参数填写:num_col、title_row都为数字,选中后才可运行代码
    num_col = 2    '需要拆分的数据每行固定的列数
    title_row = 1  '表头行数
    del_empty = True  '是否删除空行
    If Selection.Count = 1 Then Debug.Print "未选中列,无法运行代码": Exit Sub
    Set rng = Intersect(ActiveSheet.UsedRange, Selection)  'intersect语句避免选择整列造成无用计算
    '选中区域开始列号、结束行号,转换行数、列数
    first_col = rng.column: last_row = rng.Rows.Count
    resize_r = rng.Rows.Count - title_row: resize_c = rng.Columns.Count: r = resize_c / num_col
    If resize_c Mod num_col <> 0 Then Debug.Print "选中列数不可平分": Exit Sub
    
    With ActiveSheet
        For i = last_row To title_row + 1 Step -1  '倒序循环
            keep_rng = .Cells(i, 1).Resize(1, first_col - 1)  '不变区域
            arr = .Cells(i, first_col).Resize(1, resize_c)    '转换区域
            arr = wraparr(arr, "row", r)  '调用函数将arr转换为r行num_col的数组
            .Cells(i + 1, 1).Resize(r - 1, 1).EntireRow.Insert  '插入行
            .Cells(i, 1).Resize(r, first_col - 1) = keep_rng
            .Cells(i, first_col).Resize(r, num_col) = arr
        Next
        If del_empty Then  '删除空行
            j = (last_row - title_row) * r + title_row  '总行数
            For i = title_row + 1 To j
                brr = .Cells(i, first_col).Resize(1, num_col)
                If num_col > 1 Then  'brr是否为数组
                    b = Join(WorksheetFunction.Transpose(WorksheetFunction.Transpose(brr)), "")
                ElseIf num_col = 1 Then
                    b = brr
                End If
                If Len(b) = 0 Then
                    If del_rng Is Nothing Then
                        Set del_rng = .Rows(i)
                    Else
                        Set del_rng = Union(del_rng, .Rows(i))
                    End If
                End If
            Next
            If Not del_rng Is Nothing Then del_rng.Delete  '删除行
        End If
        .Cells(1, first_col + num_col).Resize(1, resize_c - num_col).EntireColumn.Delete  '删除选中列
    End With
End Sub
转换结果

本文图1(转换前不含7-20行),选中 B:M 列,运行代码得到如下图结果: D:M 列被删除
Excel·VBA表格横向、纵向相互转换,excel,vba,excel,vba,横向转换,纵向转换

纵向转横向

使用自定义函数转换,具体说明见注释(key_col(0)为开始列号,之前的都为字典键,之后的都为待转换数据)

Function 纵向转横向(ByVal data_arr, ByVal key_col)  '按非key_col列为键横向合并数组
    '转换函数,arr为待转换数组(从1开始计数二维数组),key_col为列号数组(从0开始计数一维数组)
    '返回结果,从1开始计数二维数组;key_col(0)为开始列号,key_col(1)为结束列号,键在开始列号之前
    Dim dict As Object, num_col&, delimiter$, i&, j&, r&, c&, k$, max_c&, rr&, cc&
    If Not IsArray(data_arr) Or Not IsArray(key_col) Then Debug.Print "错误!参数都为数组": Exit Function
    Set dict = CreateObject("scripting.dictionary")
    num_col = key_col(1) - key_col(0) + 1: delimiter = Chr(28)  '分隔符
    ReDim res(1 To UBound(data_arr), 1 To UBound(data_arr) * num_col)
    
    For i = LBound(data_arr) To UBound(data_arr)
        k = ""
        For j = 1 To key_col(0) - 1
            k = k & delimiter & data_arr(i, j)
        Next
        If Not dict.Exists(k) Then
            r = r + 1: dict(k) = Array(r, key_col(0))
            For j = 1 To key_col(0) - 1
                res(r, j) = data_arr(i, j)
            Next
        Else
            c = dict(k)(1) + num_col: dict(k) = Array(dict(k)(0), c)
            max_c = WorksheetFunction.Max(max_c, c)  '最大列数
        End If
        rr = dict(k)(0): cc = dict(k)(1) - 1
        For j = key_col(0) To key_col(1)
            cc = cc + 1: res(rr, cc) = data_arr(i, j)
        Next
    Next
    ReDim result(1 To r, 1 To max_c + num_col - 1)  '去除res数组多余部分
    For i = 1 To UBound(result)
        For j = 1 To UBound(result, 2)
            result(i, j) = res(i, j)
        Next
    Next
    纵向转横向 = result
End Function

转换结果

对“横向转纵向”无论是方法1还是方法2,生成的结果进行如下转换,生成的“纵向转横向”结果都一致,如下图

Sub 表格纵向转横向()
    Dim arr, brr
    arr = [a2:c20]: brr = 纵向转横向(arr, Array(2, 3))
    [d1].Resize(UBound(brr), UBound(brr, 2)) = brr
End Sub

Excel·VBA表格横向、纵向相互转换,excel,vba,excel,vba,横向转换,纵向转换
多列键也可使用自定义函数转换,更具通用性

Sub 表格纵向转横向()
    Dim arr, brr
    arr = [a2:d20]: brr = 纵向转横向(arr, Array(3, 4))
    [f1].Resize(UBound(brr), UBound(brr, 2)) = brr
End Sub

Excel·VBA表格横向、纵向相互转换,excel,vba,excel,vba,横向转换,纵向转换
附件:《Excel·VBA表格横向、纵向相互转换(附件)》

扩展阅读:
《excelhome-多列转3列》
《excel吧-3列转多列》文章来源地址https://www.toymoban.com/news/detail-624980.html

到了这里,关于Excel·VBA表格横向、纵向相互转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • EXCEL VBA从入门到精通 第九章:Excel VBA高级编程技巧

    介绍Excel VBA中的API编程,以及如何利用它们来访问Windows系统的功能。 Excel VBA提供了访问Windows系统API的功能,通过调用API函数可以访问Windows系统底层的功能和资源,例如操作系统、文件系统、网络、注册表等。API函数可以是Windows操作系统内置的函数,也可以是Windows DLL文件中

    2024年02月02日
    浏览(49)
  • EXCEL VBA从入门到精通 第一章:VBA入门

    介绍VBA的定义,作用和优点。 VBA(Visual Basic for Applications)是一种编程语言,是微软Office套件中的一个重要组成部分,主要用于自动化处理Office中的各种操作,包括Excel、Word、PowerPoint、Outlook等。 VBA是一种基于VB(Visual Basic)语言的编程语言,它具有简单易学、功能强大、灵

    2024年02月07日
    浏览(58)
  • 掌握 Microsoft Excel 宏和 Excel VBA

    掌握 Microsoft Excel 宏和 Excel VBA 基于项目的 Excel VBA(Visual Basic for Applications)和 Excel 宏课程 课程英文名:Master Microsoft Excel Macros and Excel VBA 此视频教程共27.0小时,中英双语字幕,画质清晰无水印,源码附件全 课程编号:286 百度网盘地址:https://pan.baidu.com/s/1ivLIGKt_3R0wncmCswMTR

    2024年02月05日
    浏览(44)
  • Excel+VBA帮助

     目录 一、VBA 入门知识 1、激活工作簿 2、创建新工作簿 3、打开工作簿 4、用编号引用工作表 5、用名称引用工作表 6、将文档保存为 Web 页 7、用 A1 样式的记号引用单元格和单元格区域 8、用编号引用单元格 9、引用行或列 10、用快捷记号引用单元格 11、引用命名单元格区域

    2024年02月05日
    浏览(48)
  • Excel VBA 语法基础

    VBA(Visual Basic for Applications)是一种用于宏编程和自动化任务的编程语言,广泛应用于 Microsoft Office 套件中的各种应用程序,如 Excel、Word 和 PowerPoint。掌握 VBA 基础语法可以帮助您通过编写自定义的宏来增强和自动化这些应用程序的功能。 本文将介绍 Excel VBA 的基础语法,帮

    2024年02月09日
    浏览(43)
  • 【一】Excel VBA开发 初探

    1、点击Excel左上角的【文件】,然后点击文件下方的【选项】 2、【Excel选项】中点击【自定义功能区】,右边勾选【开发工具】,点击【确定】  3、返回excel sheet 页面。点击【开发工具】,我们将看到三个我们开发过程中必用的按钮,分别是:【Visual Basic】、【宏】、【录制

    2024年02月11日
    浏览(46)
  • VBA技术资料MF36:VBA_在Excel中排序

    【分享成果,随喜正能量】一个人的气质,并不在容颜和身材,而是所经历过的往事,是内在留下的印迹,令人深沉而安谧。所以,优雅是一种阅历的凝聚;淡然是一段人生的沉淀。时间会让一颗灵魂,变得越来越动人。控制自己的脾气,做一个有修养的人。。 我给VBA的定义

    2024年02月15日
    浏览(50)
  • VBA技术资料MF35:VBA_在Excel中过滤数据

    【分享成果,随喜正能量】好马好在腿,好人好在嘴。不会烧香得罪神,不会讲话得罪人。慢慢的你就会发现,一颗好心,永远比不上一张好嘴。。 我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。

    2024年02月14日
    浏览(37)
  • VBA技术资料MF43:VBA_Excel中自动填充

    【分享成果,随喜正能量】以时寝息,当愿众生,身得安隐,心无动乱。愿我们都能,梦见幸福!在踉跄中前进,在跌倒后跃进,逐渐强大.。 我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的

    2024年02月12日
    浏览(32)
  • EXCEL VBA获取幸运数字号码

    以下就是VBA幸运号码产生的程序,复制粘贴到VBA代码框即可运行

    2024年01月21日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包