Cột khoảng 3 đến 4 cột thôi, nhưng hàng chắc sẽ nhiều và quan trọng là sẽ thay đổi liên tục.Cái này bạn có tổng cộng là bao nhiêu cột? đại khái thôi
làm cơ bản cho bạn cái đã, thắc mắc gì từ từ tính tiếpCột khoảng 3 đến 4 cột thôi, nhưng hàng chắc sẽ nhiều và quan trọng là sẽ thay đổi liên tục.
À, chỉ lấy theo thứ tự từ cột đầu đến cột cuối, chứ không lấy bắt đầu từ cột 2,3,... mình có ví dụ làm bằng tay tại file rồi mà?Bài này nếu xác định số cột thì viết code dễ dàng. Nếu không xác định được số cột thì phải viết code đệ quy để đi ruồng hết tất cả các cột, rắc rối lắm.
Vả lại cách tạo mã như trên chả theo một tiêu chuẩn nào cả. Dùng cho 3 cột thì được, nhưng trên 3 cột thì bố ai biết nó sẽ ra sao?
Ta có thể đoán rằng mã chỉ gồm 8 ký tự, 2 ký tự đầu là cột 1, 3 ký tự kế là cột 2, 3 ký tự kế là cột 3 ?
...
Ta có thể đoán rằng mã chỉ gồm 8 ký tự, 2 ký tự đầu là cột 1, 3 ký tự kế là cột 2, 3 ký tự kế là cột 3 ?
À, chỉ lấy theo thứ tự từ cột đầu đến cột cuối, chứ không lấy bắt đầu từ cột 2,3,... mình có ví dụ làm bằng tay tại file rồi mà?
Sub t()
Dim a As Variant, b As Variant ' input and output arrays
Dim r As Integer, s As String, i As Integer
a = Range("d4:f8").Value ' input matrix
ReDim b(1 To UBound(a) ^ UBound(a, 2)) ' output array
r = 0
' I am too lazy to write a full recursive routine
' thus I will let the main program go thru each line of the first column
' and the called routine automatically recurses over the rest
For i = 1 To UBound(a) ' go thru the first column
Call Combi(b, r, "", a, i, 1) ' combi is a recursive routine, it will go thru all other columns
Next i
For i = 1 To UBound(b) ' output
Range("G11").Offset(i - 1).Value = b(i)
Next i
End Sub
Sub Combi(ByRef oarr As Variant, ByRef oRow As Integer, ByVal oStr As String, _
ByVal iarr As Variant, ByVal iRow As Integer, ByVal iCol As Integer)
' parameters: output array, current output row, output string,
' input array, input array current row, input array current column
Dim i As Integer, s As String
s = iarr(iRow, iCol)
If iCol > 1 And Len(s) < 3 Then s = Right("000" & s, 3) ' patch the length with 0's
oStr = oStr & s
If iCol >= UBound(iarr, 2) Then ' last column, no need to go any further
oRow = oRow + 1
oarr(oRow) = oStr
Exit Sub
End If
For i = 1 To UBound(iarr) ' continue to go thru every line of the next level
Combi oarr, oRow, oStr, iarr, i, iCol + 1
Next i
End Sub
dạ em biết cái này nhưng sợ khi mình viết xong người hỏi lại yêu cầu thêm khác nữa nên chưa có viết tổng quát được. viết tạm cái đã rồi tính sau@phihndhsp: cocde thì dễ rồi. Nhưng code làm thế nào để không bị lệ thuộc vào số cột số dòng?
Theo toán thì bắt buộc phải dùng kỹ thuật vét cạn. Kỹ thuật vét cạn đơn giản nhất là hàm đệ quy.
Bạn thử code này, thay arr=range("D4:F8").value thành range khác hoặc đặt name hoặc Selection.Em đang vướng việc tạo mã chạy kiểu giai thừa trong một ma trận không vuông cho trước. Em có gửi file đính kèm, nhờ các bác giúp em với.
Thực tế ma trận của em rộng hơn và không vuông, nhưng em chỉ cần cách tính thôi. Cảm ơn các bác trước!
Sub abc()
Dim arr(), m&, n&, mn&, i&, j&, brr(), kq()
arr = Range("D4:F8").Value2
m = UBound(arr, 1)
n = UBound(arr, 2)
ReDim brr(1 To n)
mn = 1
For i = 1 To n
brr(i) = 1
mn = mn * m
Next
ReDim kq(1 To mn, 1 To 1)
For j = 1 To mn
For i = 1 To n
kq(j, 1) = kq(j, 1) & arr(brr(i), i)
Next
For i = n To 1 Step -1
brr(i) = brr(i) + 1
If brr(i) <= m Then Exit For
brr(i) = 1
Next
Next
Range("B11").Resize(mn) = kq
End Sub
Bạn thử code này, thay arr=range("D4:F8").value thành range khác hoặc đặt name hoặc Selection.
Mã:Sub abc() Dim arr(), m&, n&, mn&, i&, j&, [COLOR=#ff0000]brr()[/COLOR], kq() arr = Range("D4:F8").Value2 m = UBound(arr, 1) n = UBound(arr, 2) ReDim brr(1 To n) mn = 1 For i = 1 To n brr(i) = 1 mn = mn * m Next ReDim kq(1 To mn, 1 To 1) For j = 1 To mn For i = 1 To n kq(j, 1) = kq(j, 1) & arr(brr(i), i) Next For i = n To 1 Step -1 brr(i) = brr(i) + 1 If brr(i) <= m Then Exit For brr(i) = 1 Next Next Range("B11").Resize(mn) = kq End Sub
Cám ơn bác VetMini và các bác khác. Thực ra giải pháp các bác đều xử lý được vấn đề của em. Tuy nhiên để xử lý được mọi tình huống có thể xảy ra thì em đang cân nhắc các giải pháp đặc biệt là cách của bác VetMini.@phihndhsp: cocde thì dễ rồi. Nhưng code làm thế nào để không bị lệ thuộc vào số cột số dòng?
Theo toán thì bắt buộc phải dùng kỹ thuật vét cạn. Kỹ thuật vét cạn đơn giản nhất là hàm đệ quy.
Mã:Sub t() Dim a As Variant, b As Variant ' input and output arrays Dim r As Integer, s As String, i As Integer a = Range("d4:f8").Value ' input matrix ReDim b(1 To UBound(a) ^ UBound(a, 2)) ' output array r = 0 ' I am too lazy to write a full recursive routine ' thus I will let the main program go thru each line of the first column ' and the called routine automatically recurses over the rest For i = 1 To UBound(a) ' go thru the first column Call Combi(b, r, "", a, i, 1) ' combi is a recursive routine, it will go thru all other columns Next i For i = 1 To UBound(b) ' output Range("G11").Offset(i - 1).Value = b(i) Next i End Sub Sub Combi(ByRef oarr As Variant, ByRef oRow As Integer, ByVal oStr As String, _ ByVal iarr As Variant, ByVal iRow As Integer, ByVal iCol As Integer) ' parameters: output array, current output row, output string, ' input array, input array current row, input array current column Dim i As Integer, s As String s = iarr(iRow, iCol) If iCol > 1 And Len(s) < 3 Then s = Right("000" & s, 3) ' patch the length with 0's oStr = oStr & s If iCol >= UBound(iarr, 2) Then ' last column, no need to go any further oRow = oRow + 1 oarr(oRow) = oStr Exit Sub End If For i = 1 To UBound(iarr) ' continue to go thru every line of the next level Combi oarr, oRow, oStr, iarr, i, iCol + 1 Next i End Sub