diepminhhong
Thành viên mới

- Tham gia
- 4/8/09
- Bài viết
- 46
- Được thích
- 8
Sub Doc2Ngang()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim lr As Long, rw As Long, i As Long, m As Long, rc As Long, CV As Long, ii As Long, j As Long
Dim arr, drr(), tmp, cel1 As Range, cel2 As Range
Set cel1 = Sheet1.Range("A1")
Set cel2 = Sheet1.Range("AA9") 'Sua lai thành = Sheet1.Range("AA1")
lr = cel1.End(xlDown).Row
arr = UniqueArray(Sheet1.Range("A2:A" & lr))
For i = 1 To UBound(arr)
If arr(i, 1) <> "" Then
rw = rw + 1
cel2.Offset(1, 0).Offset(rw - 1).Value = arr(i, 1)
End If
Next i
ReDim drr(1 To rw)
For i = 1 To rw
drr(i) = WorksheetFunction.CountIf(Sheet1.Range("A2:A" & lr), arr(i, 1))
Next i
m = WorksheetFunction.Max(drr)
cel2.Value = cel1.Value
For i = 1 To 5
For j = 1 To m
rc = rc + 1
If j = 1 Then cel2.Offset(0, rc) = cel1.Offset(0, i)
If j > 1 Then cel2.Offset(0, rc) = cel1.Offset(0, i) & j - 1
Next j
Next i
cel2.Offset(0, 5 * m + 1).Resize(1, 16).Value = _
cel1.Offset(0, 6).Resize(1, 16).Value
tmp = cel2.Offset(1).Resize(rw, 1).Value
For i = 1 To UBound(tmp)
CV = WorksheetFunction.Match(tmp(i, 1), Sheets(1).Range("A1:A" & lr), 0)
j = 1
For ii = 1 To (5 * m) Step m
cel2.Offset(i, ii).Resize(1, drr(i)).Value = _
Application.Transpose(cel1.Offset(CV - 1, j).Resize(drr(i)))
j = j + 1
Next ii
cel2.Offset(i, 5 * m + 1).Resize(1, 16).Value = _
cel1.Offset(CV - 1, 6).Resize(1, 16).Value
Next i
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Function UniqueArray(SrcRng As Range) 'ndu96081631 -GPE
Dim Src, tmp As String, arr()
Dim i As Long, j As Long, n As Long
Src = SrcRng.Value
ReDim arr(1 To UBound(Src, 1), 1 To UBound(Src, 2))
With CreateObject("Scripting.Dictionary")
For i = LBound(Src, 1) To UBound(Src, 1)
tmp = ""
For j = LBound(Src, 2) To UBound(Src, 2)
tmp = tmp & Src(i, j)
Next
If tmp <> "" Then
If Not .Exists(tmp) Then
n = n + 1
.Add tmp, ""
For j = LBound(Src, 2) To UBound(Src, 2)
arr(n, j) = Src(i, j)
Next
End If
End If
Next
End With
If j <> 0 Then
UniqueArray = arr
End If
End Function
chạy thử code nầyAnh chị có thể giúp mình viết code copy chuyển cột dọc thành hàng ngang như trong file giúp em với được k ạ? E cảm ơn mọi người.
Sub CopyDoc_Ngang()
Dim Darr, arr(), i As Long, j As Integer, n As Integer, k As Integer
Darr = Range("a2:v" & Range("a2").End(xlDown).Row)
ReDim arr(1 To UBound(Darr), 1 To 97)
Application.ScreenUpdating = False
For i = 1 To UBound(Darr)
k = k + 1
arr(k, 1) = Darr(i, 1)
For j = 82 To 97
arr(k, j) = Darr(i, j - 75)
Next j
cot = 0
For n = i To UBound(Darr)
If Darr(n, 1) = Darr(i, 1) Then
cot = cot + 1
arr(k, cot + 1) = Darr(n, 2)
arr(k, cot + 17) = Darr(n, 3)
arr(k, cot + 33) = Darr(n, 4)
arr(k, cot + 49) = Darr(n, 5)
arr(k, cot + 65) = Darr(n, 6)
If n = UBound(Darr) Then GoTo thoat
Else
i = n - 1
GoTo tiep
End If
Next n
tiep:
Next i
thoat:
Range("aa2:ds" & Range("aa2").End(xlDown).Row).ClearContents
Range("aa2").Resize(k, 97) = arr
Application.ScreenUpdating = True
End Sub
Sub CopyDoc_Ngang1()
Dim Darr, arr(), i As Long, j As Integer, n As Integer, k As Integer, max As Integer
Darr = Range("a1:v" & Range("a2").End(xlDown).Row)
Application.ScreenUpdating = False
tmp = "": max = 0
For i = 2 To UBound(Darr)
If Darr(i, 1) = tmp Then
j = j + 1
Else
j = 1: tmp = Darr(i, 1)
End If
If j > max Then max = j
Next i
ReDim arr(1 To UBound(Darr), 1 To 17 + max * 5)
For j = 1 To 5 * max + 17
Select Case j
Case 1 To 2
arr(1, j) = Darr(1, j)
Case 3 To max + 1
arr(1, j) = Darr(1, 2) & (j - 2)
Case max + 2
arr(1, j) = Darr(1, 3)
Case max + 3 To 2 * max + 1
arr(1, j) = Darr(1, 3) & (j - max - 2)
Case 2 * max + 2
arr(1, j) = Darr(1, 4)
Case 2 * max + 3 To 3 * max + 1
arr(1, j) = Darr(1, 4) & (j - 2 * max - 2)
Case 3 * max + 2
arr(1, j) = Darr(1, 5)
Case 3 * max + 3 To 4 * max + 1
arr(1, j) = Darr(1, 5) & (j - 3 * max - 2)
Case 4 * max + 2
arr(1, j) = Darr(1, 6)
Case 4 * max + 3 To 5 * max + 1
arr(1, j) = Darr(1, 6) & (j - 4 * max - 2)
Case 5 * max + 2 To 5 * max + 17
arr(1, j) = Darr(1, j - 5 * max + 5)
End Select
Next j
k = 1
For i = 2 To UBound(Darr)
k = k + 1
arr(k, 1) = Darr(i, 1)
For j = 5 * max + 2 To 5 * max + 17
arr(k, j) = Darr(i, j - 5 * max + 5)
Next j
cot = 0
For n = i To UBound(Darr)
If Darr(n, 1) = Darr(i, 1) Then
cot = cot + 1
arr(k, cot + 1) = Darr(n, 2)
arr(k, cot + 1 + max) = Darr(n, 3)
arr(k, cot + 1 + 2 * max) = Darr(n, 4)
arr(k, cot + 1 + 3 * max) = Darr(n, 5)
arr(k, cot + 1 + 4 * max) = Darr(n, 6)
If n = UBound(Darr) Then GoTo thoat
Else
i = n - 1
GoTo tiep
End If
Next n
tiep:
Next i
thoat:
Range("aa1").CurrentRegion.ClearContents
Range("aa1").Resize(k, 5 * max + 17) = arr
Application.ScreenUpdating = True
End Sub
Ối anh ơi! Anh cứu em với. Em chạy code của anh xong mất hết dữ liệu ban đầu. Em nhờ các anh copy giúp em, chứ dữ liệu ban đầu thì giữ nguyên ạ.Mã:Sub CopyDoc_Ngang1() ... Range("aa1").CurrentRegion.ClearContents Range("aa1").Resize(k, 5 * max + 17) = arr Application.ScreenUpdating = True End Sub
mình chạy thử vẫn bình thường, chắc ăn bạn sửa chổ màu đỏ lại theo đoạn code dướiỐi anh ơi! Anh cứu em với. Em chạy code của anh xong mất hết dữ liệu ban đầu. Em nhờ các anh copy giúp em, chứ dữ liệu ban đầu thì giữ nguyên ạ.
...
Next i
thoat:
[COLOR=#ff0000]Range("aa1:dsC" & Range("aa65000").End(xlUp).Row).ClearContents[/COLOR]
Range("aa1").Resize(k, 5 * max + 17) = arr
Application.ScreenUpdating = True
End Sub
mình chạy thử vẫn bình thường, chắc ăn bạn sửa chổ màu đỏ lại theo đoạn code dưới
Sub CopyDoc_Ngang1()
...
Range("aa1").CurrentRegion.ClearContents
Range("aa1").Resize(k, 5 * max + 17) = arr
Application.ScreenUpdating = True
End Sub
Mã:... Next i thoat: [COLOR=#ff0000]Range("aa1:dsC" & Range("aa65000").End(xlUp).Row).ClearContents[/COLOR] Range("aa1").Resize(k, 5 * max + 17) = arr Application.ScreenUpdating = True End Sub
...
ReDim arr(1 To UBound(Darr), 1 To 17 + max * 5)
For j = 1 To 5 * max + 17
Select Case j
Case 1 To 2
arr(1, j) = Darr(1, j)
Case 3 To max + 1
arr(1, j) = Darr(1, 2) & (j - 2)
Case max + 2
arr(1, j) = Darr(1, 3)
Case max + 3 To 2 * max + 1
arr(1, j) = Darr(1, 3) & (j - max - 2)
Case 2 * max + 2
arr(1, j) = Darr(1, 4)
Case 2 * max + 3 To 3 * max + 1
arr(1, j) = Darr(1, 4) & (j - 2 * max - 2)
Case 3 * max + 2
arr(1, j) = Darr(1, 5)
Case 3 * max + 3 To 4 * max + 1
arr(1, j) = Darr(1, 5) & (j - 3 * max - 2)
Case 4 * max + 2
arr(1, j) = Darr(1, 6)
Case 4 * max + 3 To 5 * max + 1
arr(1, j) = Darr(1, 6) & (j - 4 * max - 2)
Case 5 * max + 2 To 5 * max + 17
arr(1, j) = Darr(1, j - 5 * max + 5)
End Select
Next j
...
ReDim arr(1 To UBound(Darr), 1 To 17 + max * 5)
For j = 1 To 5 * max + 17
If j = 1 Then
arr(1, j) = Darr(1, j)
ElseIf j >= 5 * max + 2 Then
arr(1, j) = Darr(1, j - 5 * max + 5)
ElseIf j Mod max = 2 Then
arr(1, j) = Darr(1, Int(j / max) + 2)
Else
arr(1, j) = Darr(1, Int((j - 2) / max) + 2) & ((j - 2) Mod max)
End If
Next j
dùng code dưới thay thế đoạn code trên cho gọn hơnMã:... ReDim arr(1 To UBound(Darr), 1 To 17 + max * 5) For j = 1 To 5 * max + 17 Select Case j Case 1 To 2 arr(1, j) = Darr(1, j) Case 3 To max + 1 arr(1, j) = Darr(1, 2) & (j - 2) Case max + 2 arr(1, j) = Darr(1, 3) Case max + 3 To 2 * max + 1 arr(1, j) = Darr(1, 3) & (j - max - 2) Case 2 * max + 2 arr(1, j) = Darr(1, 4) Case 2 * max + 3 To 3 * max + 1 arr(1, j) = Darr(1, 4) & (j - 2 * max - 2) Case 3 * max + 2 arr(1, j) = Darr(1, 5) Case 3 * max + 3 To 4 * max + 1 arr(1, j) = Darr(1, 5) & (j - 3 * max - 2) Case 4 * max + 2 arr(1, j) = Darr(1, 6) Case 4 * max + 3 To 5 * max + 1 arr(1, j) = Darr(1, 6) & (j - 4 * max - 2) Case 5 * max + 2 To 5 * max + 17 arr(1, j) = Darr(1, j - 5 * max + 5) End Select Next j ...
Mã:ReDim arr(1 To UBound(Darr), 1 To 17 + max * 5) For j = 1 To 5 * max + 17 If j = 1 Then arr(1, j) = Darr(1, j) ElseIf j >= 5 * max + 2 Then arr(1, j) = Darr(1, j - 5 * max + 5) ElseIf j Mod max = 2 Then arr(1, j) = Darr(1, Int(j / max) + 2) Else arr(1, j) = Darr(1, Int((j - 2) / max) + 2) & ((j - 2) Mod max) End If Next j
nhìn file của bạn, mình hơi hoảng, từ từ mình nghiên cứu và gởi code sauAnh HieuCD ơi, Anh có thể giúp e xử lý file này (file đính kèm) với được không ạ? Vẫn là file hôm trước anh làm giúp e nhưng e có thay đổi 1 chút đi. E cảm ơn anh nhiều, Chúc anh sức khỏe và thành công.
Sub CopyDoc_Ngang1()
Dim Dic2 As Object, Dic3 As Object, Darr, arr()
Dim i As Long, j As Integer, n As Integer, m As Integer, k As Integer
Dim max1 As Integer, max2 As Integer, max3 As Integer, k2 As Integer, k3 As Integer
Set Dic2 = CreateObject("Scripting.Dictionary")
Set Dic3 = CreateObject("Scripting.Dictionary")
Darr = Range("a1:aa" & Range("a2").End(xlDown).Row)
Application.ScreenUpdating = False
Tmp = Darr(2, 1): max1 = 0
max2 = 0: max3 = 0
For i = 2 To UBound(Darr)
If Darr(i, 1) = Tmp Then
k1 = k1 + 1
For j = 22 To 24
If Not Dic2.Exists(Darr(i, j)) Then
k2 = k2 + 1: Dic2.Add Darr(i, j), ""
If k2 > max2 Then max2 = k2
End If
Next j
For n = 25 To 27
If Not Dic3.Exists(Darr(i, n)) Then
k3 = k3 + 1: Dic3.Add Darr(i, n), ""
If k3 > max3 Then max3 = k3
End If
Next n
Else
k1 = 1: Tmp = Darr(i, 1)
k2 = 0: k3 = 0
End If
If k1 > max1 Then max1 = k1
Next i
ReDim arr(1 To UBound(Darr), 1 To 16 + max1 * 5 + max2 + max3)
For j = 1 To 16 + max1 * 5
If j <= 2 Then
arr(1, j) = Darr(1, j)
ElseIf j >= 5 * max1 + 3 Then
arr(1, j) = Darr(1, j - 5 * max1 + 5)
ElseIf j Mod max1 = 3 Then
arr(1, j) = Darr(1, Int(j / max1) + 3)
Else
arr(1, j) = Darr(1, Int((j - 3) / max1) + 3) & ((j - 3) Mod max1)
End If
Next j
For j = 1 To max2
arr(1, j + 16 + max1 * 5) = "TC" & j
Next j
For j = 1 To max3
arr(1, j + 16 + max1 * 5 + max2) = "NDTC" & j
Next j
k = 1
For i = 2 To UBound(Darr)
k = k + 1
arr(k, 1) = Darr(i, 1): arr(k, 2) = Darr(i, 2)
For j = 5 * max1 + 3 To 5 * max1 + 16
arr(k, j) = Darr(i, j - 5 * max1 + 5)
Next j
cot = 1
For n = i To UBound(Darr)
If Darr(n, 1) = Darr(i, 1) Then
cot = cot + 1
arr(k, cot + 1) = Darr(n, 3)
arr(k, cot + 1 + max1) = Darr(n, 4)
arr(k, cot + 1 + 2 * max1) = Darr(n, 5)
arr(k, cot + 1 + 3 * max1) = Darr(n, 6)
arr(k, cot + 1 + 4 * max1) = Darr(n, 7)
If n = UBound(Darr) Then GoTo thoat
Else
i = n - 1
GoTo tiep
End If
Next n
tiep:
Next i
thoat:
For n = 2 To k
k2 = 5 * max1 + 16: k3 = 5 * max1 + 16 + max2
Dic2.RemoveAll: Dic3.RemoveAll
For j = 22 To 27
For m = 2 To UBound(Darr)
If arr(n, 1) = Darr(m, 1) Then
If j <= 24 Then
If Not Dic2.Exists(Darr(m, j)) Then
Dic2.Add Darr(m, j), ""
k2 = k2 + 1
arr(n, k2) = Darr(m, j)
End If
Else
If Not Dic3.Exists(Darr(m, j)) Then
Dic3.Add Darr(m, j), ""
k3 = k3 + 1
arr(n, k3) = Darr(m, j)
End If
End If
End If
Next m
Next j
Next n
Set Dic2 = Nothing: Set Dic3 = Nothing
Range("af1:dsC" & Range("af65000").End(xlUp).Row).ClearContents
Range("af1").Resize(k, 16 + max1 * 5 + max2 + max3) = arr
Application.ScreenUpdating = True
End Sub
Anh HieuCD ơi, Anh có thể giúp e xử lý file này (file đính kèm) với được không ạ? Vẫn là file hôm trước anh làm giúp e nhưng e có thay đổi 1 chút đi. E cảm ơn anh nhiều, Chúc anh sức khỏe và thành công.
Sub Doc2Ngang()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Sheet1.Range("AF9:ZZ6500").ClearContents
Dim lr As Long, rw As Long, i As Long, m As Long, rc As Long, CV As Long, ii As Long, j As Long
Dim arr, drr(), tmp, cel1 As Range, cel2 As Range
Set cel1 = Sheet1.Range("A1")
Set cel2 = Sheet1.Range("AF1")
lr = cel1.End(xlDown).Row
arr = UniqueArray(Sheet1.Range("A2:A" & lr))
For i = 1 To UBound(arr)
If arr(i, 1) <> "" Then
rw = rw + 1
cel2.Offset(1, 0).Offset(rw - 1).Value = arr(i, 1)
End If
Next i
ReDim drr(1 To rw)
For i = 1 To rw
drr(i) = WorksheetFunction.CountIf(Sheet1.Range("A2:A" & lr), arr(i, 1))
Next i
m = Application.Max(drr)
cel2.Value = cel1.Value '// BBS
cel2.Offset(0, 1).Value = cel1.Offset(0, 1).Value '// HM
cel2.Offset(1, 1).Resize(rw, 1) = cel1.Offset(1, 1).Value
'// Tieu de CV->KLNT
For i = 1 To 5
For j = 1 To m
rc = rc + 1
If j = 1 Then cel2.Offset(0, 1).Offset(0, rc) = cel1.Offset(0, 1).Offset(0, i)
If j > 1 Then cel2.Offset(0, 1).Offset(0, rc) = cel1.Offset(0, 1).Offset(0, i) & j - 1
Next j
Next i
'// Tieu de GBD->NDTC3
cel2.Offset(0, 5 * m + 2).Resize(1, 20).Value = _
cel1.Offset(0, 7).Resize(1, 20).Value
'// Ghi gia tri:
tmp = cel2.Offset(1).Resize(rw, 1).Value
For i = 1 To UBound(tmp)
CV = WorksheetFunction.Match(tmp(i, 1), Sheets(1).Range("A1:A" & lr), 0)
j = 1
For ii = 1 To (5 * m) Step m
cel2.Offset(0, 1).Offset(i, ii).Resize(1, drr(i)).Value = _
Application.Transpose(cel1.Offset(0, 1).Offset(CV - 1, j).Resize(drr(i)))
j = j + 1
Next ii
cel2.Offset(i, 5 * m + 2).Resize(1, 20).Value = _
cel1.Offset(CV - 1, 7).Resize(1, 20).Value
Next i
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
dùng 2 Dic để giảm bớt vòng lặp và tăng tốc xử lýbạn HieuCD chơi sang dùng tận 2 Dic liền.
p/s: Có 6 cột cuối thì không hiểu quy luật so với kết quả của bạn: TC1->TC3 mà kết quả cần TC1->TC10
Đã xem lại và rõ quy luật của 2 nhóm TC và NDTC. Cảm ơn HieuCD.dùng 2 Dic để giảm bớt vòng lặp và tăng tốc xử lý
6 cột cuối mới khó xơi, qui luật chia cột tương tự như 5 cột trước không biết trước số cột, nhưng lấy các dòng của nhóm 3 cột và không trùng, và xếp thứ tự từ nhỏ đến lớn. mình không viết lệnh xếp thứ tự mà theo thứ tự có trước
Vâng, em cảm ơn anh nhiều ạ. E chúc anh sức khỏe và thành công ạ!bạn kiể tra lại code
Mã:Sub CopyDoc_Ngang1() Dim Dic2 As Object, Dic3 As Object, Darr, arr() Dim i As Long, j As Integer, n As Integer, m As Integer, k As Integer Dim max1 As Integer, max2 As Integer, max3 As Integer, k2 As Integer, k3 As Integer Set Dic2 = CreateObject("Scripting.Dictionary") Set Dic3 = CreateObject("Scripting.Dictionary") Darr = Range("a1:aa" & Range("a2").End(xlDown).Row) Application.ScreenUpdating = False Tmp = Darr(2, 1): max1 = 0 max2 = 0: max3 = 0 For i = 2 To UBound(Darr) If Darr(i, 1) = Tmp Then k1 = k1 + 1 For j = 22 To 24 If Not Dic2.Exists(Darr(i, j)) Then k2 = k2 + 1: Dic2.Add Darr(i, j), "" If k2 > max2 Then max2 = k2 End If Next j For n = 25 To 27 If Not Dic3.Exists(Darr(i, n)) Then k3 = k3 + 1: Dic3.Add Darr(i, n), "" If k3 > max3 Then max3 = k3 End If Next n Else k1 = 1: Tmp = Darr(i, 1) k2 = 0: k3 = 0 End If If k1 > max1 Then max1 = k1 Next i ReDim arr(1 To UBound(Darr), 1 To 16 + max1 * 5 + max2 + max3) For j = 1 To 16 + max1 * 5 If j <= 2 Then arr(1, j) = Darr(1, j) ElseIf j >= 5 * max1 + 3 Then arr(1, j) = Darr(1, j - 5 * max1 + 5) ElseIf j Mod max1 = 3 Then arr(1, j) = Darr(1, Int(j / max1) + 3) Else arr(1, j) = Darr(1, Int((j - 3) / max1) + 3) & ((j - 3) Mod max1) End If Next j For j = 1 To max2 arr(1, j + 16 + max1 * 5) = "TC" & j Next j For j = 1 To max3 arr(1, j + 16 + max1 * 5 + max2) = "NDTC" & j Next j k = 1 For i = 2 To UBound(Darr) k = k + 1 arr(k, 1) = Darr(i, 1): arr(k, 2) = Darr(i, 2) For j = 5 * max1 + 3 To 5 * max1 + 16 arr(k, j) = Darr(i, j - 5 * max1 + 5) Next j cot = 1 For n = i To UBound(Darr) If Darr(n, 1) = Darr(i, 1) Then cot = cot + 1 arr(k, cot + 1) = Darr(n, 3) arr(k, cot + 1 + max1) = Darr(n, 4) arr(k, cot + 1 + 2 * max1) = Darr(n, 5) arr(k, cot + 1 + 3 * max1) = Darr(n, 6) arr(k, cot + 1 + 4 * max1) = Darr(n, 7) If n = UBound(Darr) Then GoTo thoat Else i = n - 1 GoTo tiep End If Next n tiep: Next i thoat: For n = 2 To k k2 = 5 * max1 + 16: k3 = 5 * max1 + 16 + max2 Dic2.RemoveAll: Dic3.RemoveAll For j = 22 To 27 For m = 2 To UBound(Darr) If arr(n, 1) = Darr(m, 1) Then If j <= 24 Then If Not Dic2.Exists(Darr(m, j)) Then Dic2.Add Darr(m, j), "" k2 = k2 + 1 arr(n, k2) = Darr(m, j) End If Else If Not Dic3.Exists(Darr(m, j)) Then Dic3.Add Darr(m, j), "" k3 = k3 + 1 arr(n, k3) = Darr(m, j) End If End If End If Next m Next j Next n Set Dic2 = Nothing: Set Dic3 = Nothing Range("af1:dsC" & Range("af65000").End(xlUp).Row).ClearContents Range("af1").Resize(k, 16 + max1 * 5 + max2 + max3) = arr Application.ScreenUpdating = True End Sub
Chào diepminhhong,
Ôi ghen tị quá đi
Hổng biết bạn có thử code ở bài #2 chưa? (mình trả lời đầu tiên mà vẫn bị cho ra rìa. hức)
Code mình thì kiểu cùi bắp thôi (bạn HieuCD chơi sang dùng tận 2 Dic liền). Bạn thử xem nhé.
(p/s: Có 6 cột cuối thì không hiểu quy luật so với kết quả của bạn: TC1->TC3 mà kết quả cần TC1->TC10)
Sub chính:
Còn Function UniqueArray(), bạn chép lại ở bài #2 nhé.PHP:Sub Doc2Ngang() Application.DisplayAlerts = False Application.ScreenUpdating = False Sheet1.Range("AF9:ZZ6500").ClearContents Dim lr As Long, rw As Long, i As Long, m As Long, rc As Long, CV As Long, ii As Long, j As Long Dim arr, drr(), tmp, cel1 As Range, cel2 As Range Set cel1 = Sheet1.Range("A1") Set cel2 = Sheet1.Range("AF1") lr = cel1.End(xlDown).Row arr = UniqueArray(Sheet1.Range("A2:A" & lr)) For i = 1 To UBound(arr) If arr(i, 1) <> "" Then rw = rw + 1 cel2.Offset(1, 0).Offset(rw - 1).Value = arr(i, 1) End If Next i ReDim drr(1 To rw) For i = 1 To rw drr(i) = WorksheetFunction.CountIf(Sheet1.Range("A2:A" & lr), arr(i, 1)) Next i m = Application.Max(drr) cel2.Value = cel1.Value '// BBS cel2.Offset(0, 1).Value = cel1.Offset(0, 1).Value '// HM cel2.Offset(1, 1).Resize(rw, 1) = cel1.Offset(1, 1).Value '// Tieu de CV->KLNT For i = 1 To 5 For j = 1 To m rc = rc + 1 If j = 1 Then cel2.Offset(0, 1).Offset(0, rc) = cel1.Offset(0, 1).Offset(0, i) If j > 1 Then cel2.Offset(0, 1).Offset(0, rc) = cel1.Offset(0, 1).Offset(0, i) & j - 1 Next j Next i '// Tieu de GBD->NDTC3 cel2.Offset(0, 5 * m + 2).Resize(1, 20).Value = _ cel1.Offset(0, 7).Resize(1, 20).Value '// Ghi gia tri: tmp = cel2.Offset(1).Resize(rw, 1).Value For i = 1 To UBound(tmp) CV = WorksheetFunction.Match(tmp(i, 1), Sheets(1).Range("A1:A" & lr), 0) j = 1 For ii = 1 To (5 * m) Step m cel2.Offset(0, 1).Offset(i, ii).Resize(1, drr(i)).Value = _ Application.Transpose(cel1.Offset(0, 1).Offset(CV - 1, j).Resize(drr(i))) j = j + 1 Next ii cel2.Offset(i, 5 * m + 2).Resize(1, 20).Value = _ cel1.Offset(CV - 1, 7).Resize(1, 20).Value Next i Application.DisplayAlerts = True Application.ScreenUpdating = True End Sub
TC1, TC2, TC3 của em bên cột dọc ứng với mỗi công việc có thể giống nhau, có thể khác nhau. Mỗi TC thì ứng với 1 nội dung. Khi copy chuyển sang ngang thì e cũng muốn chuyển các TC sang hàng ngang và ứng với nó là các NDTC Nhưng các công việc mà có TC giống nhau thì khi copy sang hàng ngang thì mình loại bỏ cái TC giống nhau đi(giả sử có 3 TC giống nhau thì chỉ lấy 1 TC thôi còn 2 cái giống còn lại thì bỏ đi. NDTC cũng vậy anh ạ).Đã xem lại và rõ quy luật của 2 nhóm TC và NDTC. Cảm ơn HieuCD.
Số lượng phần tử TC = max (số giá trị không lặp lại của nhóm TC ứng với mỗi BBS) và tương tự với nhóm NDTC.
Theo kết quả đã cho thì quy luật xếp giá trị vào tương ứng với các phần tử của nhóm (ứng với mỗi BBS) lấy theo cột (đã loại trùng) từ trái sang phải rồi xoay thành hàng.
bạn kiể tra lại code
Mã:Sub CopyDoc_Ngang1() Dim Dic2 As Object, Dic3 As Object, Darr, arr() Dim i As Long, j As Integer, n As Integer, m As Integer, k As Integer Dim max1 As Integer, max2 As Integer, max3 As Integer, k2 As Integer, k3 As Integer Set Dic2 = CreateObject("Scripting.Dictionary") Set Dic3 = CreateObject("Scripting.Dictionary") Darr = Range("a1:aa" & Range("a2").End(xlDown).Row) Application.ScreenUpdating = False Tmp = Darr(2, 1): max1 = 0 max2 = 0: max3 = 0 For i = 2 To UBound(Darr) If Darr(i, 1) = Tmp Then k1 = k1 + 1 For j = 22 To 24 If Not Dic2.Exists(Darr(i, j)) Then k2 = k2 + 1: Dic2.Add Darr(i, j), "" If k2 > max2 Then max2 = k2 End If Next j For n = 25 To 27 If Not Dic3.Exists(Darr(i, n)) Then k3 = k3 + 1: Dic3.Add Darr(i, n), "" If k3 > max3 Then max3 = k3 End If Next n Else k1 = 1: Tmp = Darr(i, 1) k2 = 0: k3 = 0 End If If k1 > max1 Then max1 = k1 Next i ReDim arr(1 To UBound(Darr), 1 To 16 + max1 * 5 + max2 + max3) For j = 1 To 16 + max1 * 5 If j <= 2 Then arr(1, j) = Darr(1, j) ElseIf j >= 5 * max1 + 3 Then arr(1, j) = Darr(1, j - 5 * max1 + 5) ElseIf j Mod max1 = 3 Then arr(1, j) = Darr(1, Int(j / max1) + 3) Else arr(1, j) = Darr(1, Int((j - 3) / max1) + 3) & ((j - 3) Mod max1) End If Next j For j = 1 To max2 arr(1, j + 16 + max1 * 5) = "TC" & j Next j For j = 1 To max3 arr(1, j + 16 + max1 * 5 + max2) = "NDTC" & j Next j k = 1 For i = 2 To UBound(Darr) k = k + 1 arr(k, 1) = Darr(i, 1): arr(k, 2) = Darr(i, 2) For j = 5 * max1 + 3 To 5 * max1 + 16 arr(k, j) = Darr(i, j - 5 * max1 + 5) Next j cot = 1 For n = i To UBound(Darr) If Darr(n, 1) = Darr(i, 1) Then cot = cot + 1 arr(k, cot + 1) = Darr(n, 3) arr(k, cot + 1 + max1) = Darr(n, 4) arr(k, cot + 1 + 2 * max1) = Darr(n, 5) arr(k, cot + 1 + 3 * max1) = Darr(n, 6) arr(k, cot + 1 + 4 * max1) = Darr(n, 7) If n = UBound(Darr) Then GoTo thoat Else i = n - 1 GoTo tiep End If Next n tiep: Next i thoat: For n = 2 To k k2 = 5 * max1 + 16: k3 = 5 * max1 + 16 + max2 Dic2.RemoveAll: Dic3.RemoveAll For j = 22 To 27 For m = 2 To UBound(Darr) If arr(n, 1) = Darr(m, 1) Then If j <= 24 Then If Not Dic2.Exists(Darr(m, j)) Then Dic2.Add Darr(m, j), "" k2 = k2 + 1 arr(n, k2) = Darr(m, j) End If Else If Not Dic3.Exists(Darr(m, j)) Then Dic3.Add Darr(m, j), "" k3 = k3 + 1 arr(n, k3) = Darr(m, j) End If End If End If Next m Next j Next n Set Dic2 = Nothing: Set Dic3 = Nothing Range("af1:dsC" & Range("af65000").End(xlUp).Row).ClearContents Range("af1").Resize(k, 16 + max1 * 5 + max2 + max3) = arr Application.ScreenUpdating = True End Sub