与之前的文章《Excel·VBA螺旋数组函数》将一维数组转为二维螺旋数组
本文将数组转为S形排列的二维数组,类似考场座位S形顺序
vbnet
Function S形排列(ByVal arr, ByVal num_rows&, ByVal num_cols&, Optional ByVal mode$ = "row")
'将数组arr转为num_rows行 * num_cols列的S形排列二维数组(数组从1开始计数)
'写入模式mode,row按行写入,col按列写入
Dim a, brr, result, rc&, i&, j&, x&, y&
rc = num_rows * num_cols: ReDim brr(1 To rc), result(1 To num_rows, 1 To num_cols)
For Each a In arr '多行多列的,按列从左往右读取,防止arr元素个数超出rc
If x < rc Then x = x + 1: brr(x) = a
Next
If mode = "row" Then
For i = 1 To num_rows
If i Mod 2 = 1 Then
For j = 1 To num_cols '奇数行,从左往右写入
y = y + 1: result(i, j) = brr(y)
Next
Else
For j = num_cols To 1 Step -1 '偶数行,从右往左写入
y = y + 1: result(i, j) = brr(y)
Next
End If
Next
ElseIf mode = "col" Then
For j = 1 To num_cols
If j Mod 2 = 1 Then
For i = 1 To num_rows '奇数列,从上往下写入
y = y + 1: result(i, j) = brr(y)
Next
Else
For i = num_rows To 1 Step -1 '偶数列,从下往上写入
y = y + 1: result(i, j) = brr(y)
Next
End If
Next
End If
S形排列 = result
End Function
- 举例
vbnet
Sub 测试()
Dim arr, brr
arr = [a1].CurrentRegion
brr = S形排列(arr, 5, 4)
[c1].Resize(UBound(brr), UBound(brr, 2)) = brr
brr = S形排列(arr, 4, 5)
[c8].Resize(UBound(brr), UBound(brr, 2)) = brr
End Sub
按行写入再使用Transpose
函数转置后的结果,与直接使用按列写入一致
vbnet
Sub 测试()
Dim arr, brr
arr = [a1].CurrentRegion
brr = WorksheetFunction.Transpose(S形排列(arr, 5, 4))
[c1].Resize(UBound(brr), UBound(brr, 2)) = brr
brr = S形排列(arr, 4, 5, "col")
[c8].Resize(UBound(brr), UBound(brr, 2)) = brr
End Sub