這個屬於矩陣轉換,函式公式可以做。不妨考慮一般性,任意m*n的矩陣轉換為p*q的矩陣,這裡m*n<=p*q,且m,n,p,q都是正整數。很早以前,我寫過一篇文章,是用陣列公式來完成矩陣轉換。現在,不妨換另外一種思路,用VBA來完成矩陣轉換。
一種通用思路,引入中間變數,首先將m*n矩陣轉換為1*mn矩陣,再將1*mn矩陣轉換為p*q矩陣。這裡作一個規定,假設m*n矩陣在sheet1工作表,並且從A2開始存放資料,轉換後的p*q矩陣放入sheet2工作表,也從A2開始存放資料。為了方便寫程式碼,假設m*n矩陣邊緣的資料全部不為空,且轉換後的資料按列從上往下開始存放。如圖,24*7的矩陣轉換為16*11的矩陣:
轉換後的矩陣如圖:
程式碼如下:
Sub Trans()
Sheet1.Activate
Dim arr, temp(), brr, i&, j&, k&, p&, q&, r&, c&
c = Cells(2, Columns.Count).End(xlToLeft).Column
r = Cells(Rows.Count, 1).End(xlUp).Row
arr = Range(Cells(2, 1), Cells(r, c))
For j = 1 To UBound(arr, 2)
For i = 1 To UBound(arr, 1)
k = k + 1
ReDim Preserve temp(1 To k)
temp(k) = arr(i, j)
Next
p = 16: q = 11
ReDim brr(1 To p, 1 To q)
For j = 1 To q
For i = 1 To p
If i + (j - 1) * p <= k Then
brr(i, j) = temp(i + (j - 1) * p)
End If
Sheet2.Activate
[a2].Resize(p, q) = brr
End Sub
我們再來看看矩陣轉換的一些例項。
例1,如圖,按要求轉換資料,假設原始資料在sheet1工作表,轉換後的資料在sheet2工作表。
原始資料:
轉換後的資料:
Sub MyTrans_1()
Dim arr, brr, i%, a&, b&, c&, r&
arr = Range("a2:j" & r)
ReDim brr(1 To 12 * UBound(arr), 1 To 5)
For i = 1 To 12 * UBound(arr)
a = (i - 1) \ 12 + 1
b = (i - 1) \ 4 Mod 3 + 1
c = (i - 1) Mod 4
brr(i, 1) = arr(a, 1)
brr(i, 2) = arr(a, b + 1)
brr(i, 3) = arr(a, c + 5)
brr(i, 4) = arr(a, 9)
brr(i, 5) = arr(a, 10)
[a2].Resize(12 * UBound(arr), 5) = brr
評析:這種矩陣轉換資料比較規則,只需要找相對應的數學關係就好。
例2,按照圖示轉換資料,每戶戶主為原始股東,成員為分股東,假設原始資料在sheet1工作表,轉換後的資料在sheet2·工作表。
Sub MyTrans_2()
Dim arr, brr, temp(), i&, j&, n&, t&, r&
arr = Range("a2:e" & r + 1)
For i = 1 To UBound(arr) - 1
If arr(i, 4) = "戶主" Then
t = t + 1
Do
n = n + 1
Loop Until arr(i + n, 4) = "戶主" Or arr(i + n, 1) = ""
brr = Range(Cells(i + 1, 1), Cells(i + n + 1, "e"))
ReDim Preserve temp(1 To 5 * n)
For j = 0 To 5 * n - 1
temp(j + 1) = brr(j \ 5 + 1, j Mod 5 + 1)
Sheet2.Cells(t + 1, 1).Resize(, 5 * n) = temp
n = 0
評析:這種矩陣轉換依賴於“戶主”位置關係,首先需要獲取每一戶所有成員的資訊,然後進行矩陣轉換。唯一需要注意就是最後一戶的資訊,本例把原始資料擴充了一行,目的是為了找到最後一戶有幾口人。
這個屬於矩陣轉換,函式公式可以做。不妨考慮一般性,任意m*n的矩陣轉換為p*q的矩陣,這裡m*n<=p*q,且m,n,p,q都是正整數。很早以前,我寫過一篇文章,是用陣列公式來完成矩陣轉換。現在,不妨換另外一種思路,用VBA來完成矩陣轉換。
一種通用思路,引入中間變數,首先將m*n矩陣轉換為1*mn矩陣,再將1*mn矩陣轉換為p*q矩陣。這裡作一個規定,假設m*n矩陣在sheet1工作表,並且從A2開始存放資料,轉換後的p*q矩陣放入sheet2工作表,也從A2開始存放資料。為了方便寫程式碼,假設m*n矩陣邊緣的資料全部不為空,且轉換後的資料按列從上往下開始存放。如圖,24*7的矩陣轉換為16*11的矩陣:
轉換後的矩陣如圖:
程式碼如下:
Sub Trans()
Sheet1.Activate
Dim arr, temp(), brr, i&, j&, k&, p&, q&, r&, c&
c = Cells(2, Columns.Count).End(xlToLeft).Column
r = Cells(Rows.Count, 1).End(xlUp).Row
arr = Range(Cells(2, 1), Cells(r, c))
For j = 1 To UBound(arr, 2)
For i = 1 To UBound(arr, 1)
k = k + 1
ReDim Preserve temp(1 To k)
temp(k) = arr(i, j)
Next
Next
p = 16: q = 11
ReDim brr(1 To p, 1 To q)
For j = 1 To q
For i = 1 To p
If i + (j - 1) * p <= k Then
brr(i, j) = temp(i + (j - 1) * p)
End If
Next
Next
Sheet2.Activate
[a2].Resize(p, q) = brr
End Sub
我們再來看看矩陣轉換的一些例項。
例1,如圖,按要求轉換資料,假設原始資料在sheet1工作表,轉換後的資料在sheet2工作表。
原始資料:
轉換後的資料:
程式碼如下:
Sub MyTrans_1()
Sheet1.Activate
Dim arr, brr, i%, a&, b&, c&, r&
r = Cells(Rows.Count, 1).End(xlUp).Row
arr = Range("a2:j" & r)
ReDim brr(1 To 12 * UBound(arr), 1 To 5)
For i = 1 To 12 * UBound(arr)
a = (i - 1) \ 12 + 1
b = (i - 1) \ 4 Mod 3 + 1
c = (i - 1) Mod 4
brr(i, 1) = arr(a, 1)
brr(i, 2) = arr(a, b + 1)
brr(i, 3) = arr(a, c + 5)
brr(i, 4) = arr(a, 9)
brr(i, 5) = arr(a, 10)
Next
Sheet2.Activate
[a2].Resize(12 * UBound(arr), 5) = brr
End Sub
評析:這種矩陣轉換資料比較規則,只需要找相對應的數學關係就好。
例2,按照圖示轉換資料,每戶戶主為原始股東,成員為分股東,假設原始資料在sheet1工作表,轉換後的資料在sheet2·工作表。
原始資料:
轉換後的資料:
程式碼如下:
Sub MyTrans_2()
Sheet1.Activate
Dim arr, brr, temp(), i&, j&, n&, t&, r&
r = Cells(Rows.Count, 1).End(xlUp).Row
arr = Range("a2:e" & r + 1)
For i = 1 To UBound(arr) - 1
If arr(i, 4) = "戶主" Then
t = t + 1
Do
n = n + 1
Loop Until arr(i + n, 4) = "戶主" Or arr(i + n, 1) = ""
brr = Range(Cells(i + 1, 1), Cells(i + n + 1, "e"))
ReDim Preserve temp(1 To 5 * n)
For j = 0 To 5 * n - 1
temp(j + 1) = brr(j \ 5 + 1, j Mod 5 + 1)
Next
Sheet2.Cells(t + 1, 1).Resize(, 5 * n) = temp
n = 0
End If
Next
Sheet2.Activate
End Sub
評析:這種矩陣轉換依賴於“戶主”位置關係,首先需要獲取每一戶所有成員的資訊,然後進行矩陣轉換。唯一需要注意就是最後一戶的資訊,本例把原始資料擴充了一行,目的是為了找到最後一戶有幾口人。