Excel·VBA螺旋数组函数

2023-11-16

数字1-12从左上角顺时针依次输出的即为螺旋数组,如下图
在这里插入图片描述

1,由外到内顺时针的螺旋数组

实现方法1

从左上角开始,每一层按顶行、右列、底行、左列顺序依次赋值

代码思路

以数字1-30为例
在这里插入图片描述
观察可知,每行依次填入该层列数-1个数字(上图黄色/绿色部分),同理每列依次填入该层行数-1个数字(上图无色部分)。在遍历每层时,顶行的行号和左列的列号等于层数,底行的行号和右列的列号随着层数的递增而递减,由此编写代码如下

螺旋数组函数代码

将一维数组转为二维螺旋数组也可输出由内到外逆时针的螺旋数组

Function spiral(ByVal arr, ByVal num_rows&, ByVal num_cols&)
    '将一维数组转为二维螺旋数组,num_rows返回行数num_cols返回列数,大于1(数组从1开始计数)
    '可输出由外到内顺时针,也可倒序输出由内到外逆时针
    Dim i&, n&, w&, max_num&, max_n&, last_row&, last_col&
    '转为从1开始计数,检查参数num_rows、num_cols
    If LBound(arr) = 0 Then arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))
    If num_rows * num_cols <> UBound(arr) Then
        Debug.Print "参数错误": Exit Function
    Else
        max_num = UBound(arr): ReDim result(1 To num_rows, 1 To num_cols)
    End If
    '初始值,n当前写入层数,max_n最大层数
    n = 1: max_n = WorksheetFunction.RoundUp(WorksheetFunction.Min(Array(num_rows, num_cols)) / 2, 0)
    last_row = num_rows - n + 1: last_col = num_cols - n + 1
    Do
        For i = n To last_col - 1  '该层顶行
            w = w + 1: result(n, i) = arr(w)
        Next
        For i = n To last_row - 1  '该层右列
            w = w + 1: result(i, last_col) = arr(w)
        Next
        For i = last_col To n + 1 Step -1  '该层底行
            w = w + 1: result(last_row, i) = arr(w)
        Next
        For i = last_row To n + 1 Step -1  '该层左列
            w = w + 1: result(i, n) = arr(w)
        Next
        If n < max_n Then n = n + 1
        last_row = num_rows - n + 1: last_col = num_cols - n + 1  '更新值
        If n = max_n And n = last_row Then  '最后一行
            For i = n To last_col
                w = w + 1: result(n, i) = arr(w)
            Next
        ElseIf n = max_n And n = last_col Then  '最后一列
            For i = n To last_row
                w = w + 1: result(i, n) = arr(w)
            Next
        End If
    Loop Until w >= max_num
    spiral = result
End Function

举例

Sub 螺旋数组测试()
    Dim a&, n&, m&, i&
    a = 49: n = 7: m = 7: tm = Timer
    ReDim arr(1 To a)
    For i = 1 To a
        arr(i) = i
    Next
    brr = spiral(arr, n, m)
    [a1].Resize(UBound(brr), UBound(brr, 2)) = brr
    Debug.Print "用时:" & Format(Timer - tm, "0.00")  '耗时
End Sub

在这里插入图片描述
输出由内到外逆时针的螺旋数组,仅需将arr数组倒序后传递给spiral函数

Sub 螺旋数组测试()
    Dim a&, n&, m&, i&, j&
    a = 49: n = 7: m = 7: tm = Timer
    ReDim arr(1 To a)
    For i = a To 1 Step -1
        j = j + 1: arr(j) = i
    Next
    brr = spiral(arr, n, m)
    [a1].Resize(UBound(brr), UBound(brr, 2)) = brr
    Debug.Print "用时:" & Format(Timer - tm, "0.00")  '耗时
End Sub

在这里插入图片描述

已测试参数
在这里插入图片描述

实现方法2

从左上角开始,根据每一层待赋值的坐标变化规律进行赋值

代码思路

以数字1-30为例
在这里插入图片描述
观察可知,每行依次填入该层列数-1个数字(上图黄色/绿色部分),同理每列依次填入该层行数-1个数字(上图无色部分),每往内一层可用行列数比外层少2,如此依次填完所有数字。(其中29-30的行比上一行19-21的行仅减少1个,是因为最后一层填入剩余数字)
每一层中数组坐标,先向右再向下(递增),然后向左再向上(递减),递增递减的代码方式有2种写法,如下

螺旋数组函数代码

将一维数组转为二维螺旋数组:2种代码形式,效果一致;第2种代码先定义递增递减顺序的(step_arr),更易理解

'Function spiral(ByVal arr, ByVal num_rows&, ByVal num_cols&)
'    '将一维数组转为二维螺旋数组,num_rows返回行数num_cols返回列数,大于1(数组从1开始计数)
'    Dim r&, c&, w&, mode_row As Boolean, max_n&, max_r&, max_c&, step_n&, last_row&, x&
'    '转为从1开始计数,检查参数num_rows、num_cols
'    If LBound(arr) = 0 Then arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))
'    If num_rows * num_cols <> UBound(arr) Then
'        Debug.Print "参数错误": Exit Function
'    Else
'        max_n = UBound(arr): ReDim result(1 To num_rows, 1 To num_cols)
'    End If
'    '初始值,先按行写入;max_r和max_c都为当前行列数-1
'    r = 0: c = 0: max_r = num_rows - 1: max_c = num_cols - 1: step_n = 1
'    mode_row = True: last_row = num_rows: x = 2  '最外层循环结束时的行号为2,次外层为3,以此类推
'    Do
'        If mode_row = True Then  '按行写入
'            r = r + step_n
'            If r = last_row And max_r > 0 Then step_n = -1 Else step_n = 1
'            If c > 0 Then c = c - step_n
'            For i = 1 To max_c
'                w = w + 1: c = c + step_n: result(r, c) = arr(w)
'            Next
'            mode_row = False
'        Else    '按列写入
'            If r = last_row Then step_n = -1 Else step_n = 1
'            c = c + step_n
'            If r > 0 Then r = r - step_n
'            For i = 1 To max_r
'                w = w + 1: r = r + step_n: result(r, c) = arr(w)
'            Next
'            mode_row = True
'            If r = x And step_n = -1 Then  '每层循环结束后,更新值
'                x = x + 1: max_r = max_r - 2: max_c = max_c - 2
'                step_n = 1: last_row = last_row - 1
'                If max_r > 0 And max_c > 0 Then
'                    r = r - 1: c = c + 1
'                ElseIf max_r = 0 And max_c >= 0 Then
'                    max_c = max_c + 1: mode_row = True: r = r - 1: c = c + 1
'                ElseIf max_c = 0 And max_r > 0 Then
'                    max_r = max_r + 1: mode_row = False
'                End If
'            End If
'        End If
'    Loop Until w >= max_n
'    spiral = result
'End Function

Function spiral(ByVal arr, ByVal num_rows&, ByVal num_cols&)
    '将一维数组转为二维螺旋数组,num_rows返回行数num_cols返回列数,大于1(数组从1开始计数)
    Dim r&, c&, w&, mode_row As Boolean, max_n&, max_r&, max_c&, step_n&, last_row&, x&, n&
    '转为从1开始计数,检查参数num_rows、num_cols
    If LBound(arr) = 0 Then arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))
    If num_rows * num_cols <> UBound(arr) Then
        Debug.Print "参数错误": Exit Function
    Else
        max_n = UBound(arr): ReDim result(1 To num_rows, 1 To num_cols)
    End If
    '初始值,先按行写入;max_r和max_c都为当前行列数-1
    r = 0: c = 0: max_r = num_rows - 1: max_c = num_cols - 1: step_n = 1
    step_arr = Array(, 1, 1, -1, -1)
    mode_row = True: last_row = num_rows: x = 2  '最外层循环结束时的行号为2,次外层为3,以此类推
    Do
        If mode_row = True Then  '按行写入
            r = r + step_n: n = n + 1: step_n = step_arr(n)
            If c > 0 Then c = c - step_n
            For i = 1 To max_c
                w = w + 1: c = c + step_n: result(r, c) = arr(w)
            Next
            mode_row = False
        Else    '按列写入
            n = n + 1: step_n = step_arr(n): c = c + step_n
            If r > 0 Then r = r - step_n
            For i = 1 To max_r
                w = w + 1: r = r + step_n: result(r, c) = arr(w)
            Next
            mode_row = True
            If r = x And step_n = -1 Then  '每层循环结束后,更新值
                x = x + 1: max_r = max_r - 2: max_c = max_c - 2
                n = 0: step_n = 1: last_row = last_row - 1
                If max_r > 0 And max_c > 0 Then
                    r = r - 1: c = c + 1
                ElseIf max_r = 0 And max_c >= 0 Then  '都=0,即返回正方形奇数数组
                    max_c = max_c + 1: mode_row = True: r = r - 1: c = c + 1
                ElseIf max_c = 0 And max_r > 0 Then
                    max_r = max_r + 1: mode_row = False
                End If
            End If
        End If
    Loop Until w >= max_n
    spiral = result
End Function

测试结果与实现方法1一致

2,由外到内逆时针的螺旋数组

实现方法与上面的 实现方法1 一样
将一维数组转为二维螺旋数组也可输出由内到外顺时针的螺旋数组

Function spiral_0(ByVal arr, ByVal num_rows&, ByVal num_cols&)
    '将一维数组转为二维螺旋数组,num_rows返回行数num_cols返回列数,大于1(数组从1开始计数)
    '可输出由外到内逆时针,也可倒序输出由内到外顺时针
    Dim i&, n&, w&, max_num&, max_n&, last_row&, last_col&
    '转为从1开始计数,检查参数num_rows、num_cols
    If LBound(arr) = 0 Then arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))
    If num_rows * num_cols <> UBound(arr) Then
        Debug.Print "参数错误": Exit Function
    Else
        max_num = UBound(arr): ReDim result(1 To num_rows, 1 To num_cols)
    End If
    '初始值,n当前写入层数,max_n最大层数
    n = 1: max_n = WorksheetFunction.RoundUp(WorksheetFunction.Min(Array(num_rows, num_cols)) / 2, 0)
    last_row = num_rows - n + 1: last_col = num_cols - n + 1
    Do
        For i = n To last_row - 1  '该层左列
            w = w + 1: result(i, n) = arr(w)
        Next
        For i = n To last_col - 1  '该层底行
            w = w + 1: result(last_row, i) = arr(w)
        Next
        For i = last_row To n + 1 Step -1  '该层右列
            w = w + 1: result(i, last_col) = arr(w)
        Next
        For i = last_col To n + 1 Step -1  '该层顶行
            w = w + 1: result(n, i) = arr(w)
        Next
        If n < max_n Then n = n + 1
        last_row = num_rows - n + 1: last_col = num_cols - n + 1  '更新值
        If n = max_n And n = last_row Then  '最后一行
            For i = n To last_col
                w = w + 1: result(n, i) = arr(w)
            Next
        ElseIf n = max_n And n = last_col Then  '最后一列
            For i = n To last_row
                w = w + 1: result(i, n) = arr(w)
            Next
        End If
    Loop Until w >= max_num
    spiral_0 = result
End Function

举例

与 实现方法1 类似,可输出由外到内逆时针,也可倒序输出由内到外顺时针
同类参数举例
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Excel·VBA螺旋数组函数 的相关文章

  • 在用户窗体终止/关闭 VBA 时调用数组

    我有一个问题 我想在用户窗体关闭时将用户窗体的内容存储在数组中 我认为我的语法正确 但似乎不会在用户窗体初始化时重新填充 我尝试将数组放入其自己的模块中 但这也不起作用 有人愿意启发我吗 示例代码 Public Sub DPArrayStu
  • 使用 python 中的公式函数使从 Excel 中提取的值的百分比相等

    import xlrd numpy excel Users Bob Desktop wb1 xlrd open workbook excel assignment3 xlsx sh1 wb1 sheet by index 0 colA co
  • Excel 公式从单元格中获取字符串值并按字母顺序对其字符进行排序

    你能帮我制作一个 Excel 公式 从单元格中获取字符串值并按字母顺序对其字符进行排序吗 Ex 原始单元格值 BACR 已排序的字符单元格 ABCR 编辑 2022 年 4 月 29 日 随着 Office 365 Excel 中引入的动态
  • 使用 Python Pandas 获取多个值来制作表格

    使用我的代码 我可以将两个 Excel 数据库连接到 1 中 问题是它只显示收入列 而不显示列展示次数 为了更清楚 我留下了代码和示例 我尝试过 df1 df1 pivot index Cliente columns Fecha value
  • 如何使用 ssis 2008 循环遍历 Excel 文件并获取工作表名称

    我正在尝试将 Excel 文件中的数据加载到 SQL 数据库表中 该文件的工作表名称不是静态的 工作表名称包含 yyyymmdd 它会随每个文件而变化 我按照提供的解决方案进行操作如何使用 SSIS 包循环遍历 Excel 文件并将其加载到
  • 如何使用Excel的墨迹工具添加手写签名?

    我想在我公司的一些表格中添加手写数字签名 目标是选择一个文档 添加签名 通过使用绘图板 这可以使用 Excel 的墨水工具完成 并将文件作为 PDF 存储在服务器中 这将消除打印然后扫描表格以获得签名的必要性 我使用 Excel 作为文件操
  • 将 Excel 数字日期重新格式化为 R 日期

    希望将从 Excel 中提取的列重新格式化为包含数字 Excel 格式 例如 40182 的数据框 as date 40182 origin 1899 12 30 format b Y Returns 1 2070 年 1 月 5 日 我正
  • VBA复制单元格值和格式

    我如何修改以下代码以便不仅复制值而且复制字体样式 例如大胆或不大胆 谢谢 Private Sub CommandButton1 Click Dim i As Integer Dim a As Integer a 15 For i 11 To
  • 根据单元格值返回图像(100 张图像和可变单元格)

    我正在尝试为我制作一个 TFT 云顶之弈 表 并想让它看起来更好 为此 我想添加游戏中冠军的图像 当我输入名称时 图像应该出现在下面 我找到了一种将所有图像插入 Excel 工作表 100 的方法 并且还成功制作了一个动态图像 插入 IND
  • 将整个工作表复制到 Excel 2010 中的新工作表

    我发现了类似的问题 涉及复制一个工作簿中的整个工作表并将其粘贴到另一个工作簿 但我感兴趣的是简单地复制整个工作表并将其粘贴到同一工作簿中的新工作表 我正在将 2003 xls 文件转换为 2010 xlsm 用于在工作表之间复制和粘贴的旧方
  • VBA FreeLibrary 不卸载 DLL

    当我使用完一个 DLL 文件后 我需要删除它 代码完成后清理 我尝试在 Excel VBA 中使用 LoadLibrary 和 FreeLibrary 但无论我做什么 Excel exe 都会坚持 DLL 文件 Public Declare
  • 自动电子邮件生成无法解析多个收件人

    我有一个 VBA 脚本 可以创建并保存草稿电子邮件 为了添加收件人 它从链接的 Excel 表中提取一个字符串并将其添加到 Recipients 对象中 对于只有单一收件人的电子邮件 这就像一个魅力 用户所需要做的就是打开草稿 花 5 秒钟
  • VBA - 如何从网站下载.xls并将数据放入Excel文件

    我设法使用 VBA 达到准备从网络下载 Excel 文件的程度 但我无法弄清楚如何实际下载该文件并将其内容放入我正在使用的 Excel 文件中 有什么建议么 谢谢 这是到目前为止的代码 Sub GetData Dim IE As Inter
  • 两个数组相乘 - 区域小数分隔符问题

    Background 刚才 我回答了一个问题 我必须将两个相同大小的数组相乘 但是我注意到我的本地小数分隔符存在一个特殊问题 Sample Code Sub Sample Dim arr1 As Variant arr2 As Varian
  • 在 BIRT 中导出的 Excel 中表格单元格的文本换行

    我在 eclipse 中使用 BIRT 4 4 1 来生成报告 我想包装表头的文本 它在网络查看器中工作正常 但是当我导出到 Excel 时 表单元格文本在一行中 并且文本也溢出 我不想使单元格宽度等于内容 我想根据其容器宽度来换行文本 我
  • 从 Excel 数据为列中的每个不同值创建 CSV 文件?

    我有一个 Excel 其供应商代码 数字 作为其中一列 VENDORITEM DESCRIPTION PRICE PRICEGROUP VENDOR NUMBER PRODUCT CATEGORY HNM36789 30ML FLUID C
  • 从 excel/vba 生成电子邮件到 Outlook 时,我的电子邮件签名不会出现?

    您好 我使用 Ron De Bruin 的精彩网站创建了 VBA 代码 该代码可以从 Excel 文件生成向特定用户发送的电子邮件 唯一的问题是我的签名没有出现在每封电子邮件上 而且我似乎找不到如何在代码中添加它 有人可以建议吗 正如你所知
  • SQL查询从表的每条记录生成多条记录

    我有一个包含 3000 条记录的表 使用其中的每一条记录 我必须生成大约 200 条记录 总共 600k 条记录 并通过 SQL Server 2012 将它们插入到第二个表中 我尝试使用 VBA 执行此操作 从第一个表中选择数据 计算 然
  • 电子邮件正文为空,没有 .Display

    我读过这个 VBA Outlook 2010 收到邮件 正文为空 https stackoverflow com questions 42348518 vba outlook 2010 received mail body is empty
  • 调用 UDF 时公式中使用的值的数据类型错误

    我一直在努力找出这里出了什么问题 我有两个包含字符串值的列 我使用第三列调用工作表中的 UDF 但最终得到 Value 并出现错误 公式中使用的值的数据类型错误 Eg Col I Col J File1 Y File1 N File2 Y

随机推荐

  • 数据库相关知识和进阶知识

    目录 MySQL与Orcale EXPLAIN介绍 EXPLAIN 可以分析慢查询原因 查看MySQL存储空间大小 MySQL事务锁不执行严格的校验
  • Retrofit实现文件上传和下载【二】

    概述 通过前一篇的博客介绍 我们已经对Retrofit的使用有了一个大概的了解 今天来讲讲利用Retrofit进行文件的上传和下载 文件上传 服务器使用的是SSH框架 因此这里是以struts2的方式来获取数据的 我这里定义了三个字段用来接
  • Java发送手机短信验证码

    本次使用的是阿里云的短信服务 1 添加短信签名 签名名称要用的 在阿里云产品中搜 短信服务 gt 免费开通 gt 国内消息 2 添加短信模板 模版CODE需要用的 就在添加签名的旁边 3 创建用户 用户令牌和密码需要用的 然后选择 开始使用
  • bug复刻,解决方案---在改变div层级关系时,导致传参失败

    问题描述 在优化页面时 为了实现网页顶部遮挡效果 内容滚动 顶部导航栏不随着一起滚动 并且覆盖 做法是将内容都放在一个div里面 为这个新的div设置样式 margin top width heigh等 网页效果的确实现了 但是出现的新的问
  • Chisel实验笔记(一)

    最近在学习Risc v 其中伯克利大学开源了一款兼容Risc v指令集的处理器Rocket 而Rocket处理器是采用Chisel编写的 所以要学习Chisel Chisel的简单介绍如下 Chisel Constructing Hardw
  • 基于Arduino的音乐动感节奏灯

    1 音乐动感节奏灯是个什么东西 前段时间听音乐觉得无聊 便想着音乐光听也没意思啊 能不能 看见 音乐呢 于是谷歌了一番 发现还真有人做了将音乐可视化的东西 那就是音乐节奏灯 说的简单点就是LED灯光颜色亮度等随着音乐的节奏而发生变化 看了下
  • 最新机器人工程专业毕设选题推荐

    文章目录 1前言 2 如何选题 3 机器人工程 毕设 选题推荐 4 最后 1前言 近期不少学弟学妹询问学长关于机器人工程专业工程专业相关的毕设选题 学长特意写下这篇文章以作回应 以下是学长亲手整理相关的毕业设计选题 都是经过学长精心审核的题
  • Python-声明变量

    Python如何声明变量 在 Python 中 定义变量非常简单 只需要为变量赋一个值即可自动创建该变量 并推断出变量的数据类型 变量名可以是任意字母 数字或下划线组成 但是不能以数字开头 例如 定义名为 name 的变量 并将字符串 To
  • event类型 php,深入解析PHP的Laravel框架中的event事件操作

    有时候当我们单纯的看 Laravel 手册的时候会有一些疑惑 比如说系统服务下的授权和事件 这些功能服务的应用场景是什么 其实如果没有经历过一定的开发经验有这些疑惑是很正常的事情 但是当我们在工作中多加思考会发现有时候这些服务其实我们一直都
  • 服务器的协议端口在哪里设置,服务器的远程端口号在哪里设置

    服务器的远程端口号在哪里设置 内容精选 换一换 Linux云服务器一般采用SSH连接方式 使用密钥对进行安全地无密码访问 但是SSH连接一般都是字符界面 有时我们需要使用图形界面进行一些复杂操作 本文以Ubuntu 18 04操作系统为例
  • 飞旭体质健康测试云平台学生体质测试管理系统

    飞旭体测数据管理云平台是由体测设备 微信小程序和云平台构成 用户通过设备测试后 数据传输至云端 由云平台对数据进行针对性的统计分析 平台功能包括管理员分级管理 学生体质测试 学生体质测试成绩查询 测试数据管理统计分析 数据上报管理等内容 具
  • 15 周带你学好大一C语言!最详细C语言学习路线

    要学习 C 语言的读者抓紧时间看一下 我按照C语言学习视频的目录整理了一条以 周为单位时间 的学习路线 希望在开学后能按照这个进度去学习一遍 有要学习 C 语言的读者也可以参照 可能有些知识学习起来比较困难 比如说二进制这种涉及到底层方面的
  • iperf linux移植

    参考链接 1 iperf的git地址 windows版下载地址 git clone https github com esnet iperf git 2 下载到ubuntu上 3 找到交叉工具包的位置 opt arm ca9 linux g
  • 绘制复杂的层次的原理图

    一 绘制总体的区域块模块 1 新建一个PCB项目 在new中的project选择PCB 2 在项目中新建一个sheet文件 schemetic 然后找到place中的sheet Symbol Actions 3 修改每一个绿块的名称和文件名
  • 阻止移动端 touchmove 与 scroll 事件冲突

    在移动端开发过程中 如果要实现一个元素或按钮的拖动定位 会出现很多坑 例如 元素上下移动过程中 会触发 body 的 scroll 事件 导致整体的位置偏移 这时就需要 阻止移动端 touchmove 与 scroll 事件冲突 一 解决思
  • 【致敬未来的攻城狮计划】--RA2E1 开发板测评(3)按键输入

    前言 1 首先感谢 李肯前辈的活动 从而申请到了RA2L1开发板的测评 2 本文主要介绍按键输入的内容 3 学习本文需要准备的前提 致敬未来的攻城狮计划 RA2E1 开发板测评 1 keil环境配置 致敬未来的攻城狮计划 RA2L1 开发板
  • 自助Linux之问题诊断工具strace

    引言 Oops 系统挂死了 Oops 程序崩溃了 Oops 命令执行报错 对于维护人员来说 这样的悲剧每天都在上演 理想情况下 系统或应用程序的错误日志提供了足够全面的信息 通过查看相关日志 维护人员就能很快地定位出问题发生的原因 但现实情
  • 去除li前面小点点

    li list style type none
  • 3. 性能测试之目标评估

    文章目录 前言 一 模型1 根据日活计算目标QPS 1 原则 2 事例 二 模型2 根据压测数据评估最大支撑并发 1 原则 2 事例 3 备注 三 模型3 根据压测数据评估服务器资源 1 策略 2 备注 四 模型4 评估用户并发或峰值并发
  • Excel·VBA螺旋数组函数

    目录 1 由外到内顺时针的螺旋数组 实现方法1 代码思路 螺旋数组函数代码 举例 实现方法2 代码思路 螺旋数组函数代码 2 由外到内逆时针的螺旋数组 举例 数字1 12从左上角顺时针依次输出的即为螺旋数组 如下图 1 由外到内顺时针的螺旋