用JSA做表格分段排序

wils
wils Lv.2 潜力创作者

Lv.2潜力创作者

昨天有朋友问,类似下表中,有合并单元格的情况下,如何将每个月的xyz按照z进行排序

年度

月份

x

y

z

2025

11月

a

a

2

b

b

1

c

c

3

12月

d

d

3

e

e

2

f

f

1

想了半天,对于这种需要在原表上进行修改的情况,似乎特别适合写JS宏处理

正好借此介绍一下简单的套路,吸引更多朋友来讨论JS宏

function tt()
{
    const r = Range(`B${Rows.Count}`).End(xlUp).Row
    let i = 2
    while (i <= r) {
        const m = Range(`B${i}`).MergeArea
        const n = m.Offset(0, 1).Resize(m.Rows.Count, 3)
        n.Value2 = n.Value2.sort((x, y) => parseFloat(y[2]) - parseFloat(x[2]))
        i += m.Rows.Count
    }
}
🔔

const r = Range(`B${Rows.Count}`).End(xlUp).Row

这是个套路,`B${Rows.Count}`实际就是"B1048576",即B列最后一行,然后End(xlUp)就相当于在表格里按ctrl + 向上,也就是跳转到B列有数据的最后一行,最后获得这一行的行号,存入变量r

🔔

let i = 2

while (i <= r) {

这是个最常用的循环,变量i表示现在关注第几行,我们要从第2行开始处理到第r行

🔔

const m = Range(`B${i}`).MergeArea

MergeArea属性用来获取当前单元格所在合并单元格的整体范围,当i是2,也就是获取B2:B4这个范围

🔔

const n = m.Offset(0, 1).Resize(m.Rows.Count, 3)

和常用公式里的offset和resize类似,这里将上面的范围m,向右移动1列,然后扩展为3列,当i是2,也就是获取到C2:E4范围

🔔

n.Value2 = n.Value2.sort((x, y) => parseFloat(y[2]) - parseFloat(x[2]))

这也是套路,Value2获取到的是范围里的数值组成的二维数组,这也是JS比VBA方便的一点,JS里的二维数组是十分灵活的,这里先取得C2:E4里值组成的二维数组,第一维里对应每一行,这里对每一行进行排序,依据是每一行里第三个元素转为浮点数的值,最后将排序后的数据写入原位

🔔

i += m.Rows.Count

完成一次之后,关注的行号要加上合并单元格范围的行数,也就是行数从2变成了5,之后继续下一次循环


其实,常见的JS宏都是这个套路,用各种循环,逐个处理表格中的各种对象,可以是表格的行列,也可以是图片等等,在循环的过程中,用Value2等属性读写数据,就这么简单

有更多需求时,在这样的结构里做修改是十分方便的


尤其是这种原地修改表格的情况,只要想清楚要怎么循环,写JS宏处理,要比写公式简单清晰很多,也希望更多朋友关注讨论JS宏

海南省
浏览 207
收藏
4
分享
4 +1
+1
全部评论