Nhờ giúp đỡ tạo macro xử lí đổi cột thành hàng cho các đối tượng có nhiều giá trị

Liên hệ QC

hs.robby

Thành viên mới
Tham gia
20/1/10
Bài viết
8
Được thích
1
Dear các Pro,
Mình muốn tạo 1 macro để xử lí việc đổi cột thành hàng cho các đối tượng có giá trị tương ứng. Cụ thể như sau:
Từ thong kê dạng cột:
1542616935783.png

Mình muốn đổi thành:
1542617024945.png

Do dữ lieu rất nhiều mình không thể filter từng đối tượng để copy và paste -> transpose được. Chi tiết theo file đính kèm. Xin cảm ơn nhiều!
 

File đính kèm

  • Data_Source.xlsx
    13.3 KB · Đọc: 11
Dear các Pro,
Mình muốn tạo 1 macro để xử lí việc đổi cột thành hàng cho các đối tượng có giá trị tương ứng. Cụ thể như sau:
Từ thong kê dạng cột:
View attachment 207952

Mình muốn đổi thành:
View attachment 207953

Do dữ lieu rất nhiều mình không thể filter từng đối tượng để copy và paste -> transpose được. Chi tiết theo file đính kèm. Xin cảm ơn nhiều!

Có thể dùng công thức, VBA thì chờ Anh/Em khác giúp nha.
 

File đính kèm

  • Data_Source.xlsx
    17.1 KB · Đọc: 13
Dear các Pro,
Mình muốn tạo 1 macro để xử lí việc đổi cột thành hàng cho các đối tượng có giá trị tương ứng. Cụ thể như sau:
Từ thong kê dạng cột:
View attachment 207952

Mình muốn đổi thành:
View attachment 207953

Do dữ lieu rất nhiều mình không thể filter từng đối tượng để copy và paste -> transpose được. Chi tiết theo file đính kèm. Xin cảm ơn nhiều!
đây bạn xem
Mã:
Sub chuyen()
Dim a As Long, b As Long, i As Long, j As Long, k As Long
Dim dk As String
Dim arr, bang
Dim dic As Object
Set dic = CreateObject("scripting.dictionary")
With Sheet1
     arr = .Range("A2:b" & .Range("a" & Rows.Count).End(xlUp).Row).Value
     a = UBound(arr, 1)
     ReDim arr1(1 To a, 1 To a)
     For i = 1 To a
         If dic.exists(arr(i, 1)) = 0 Then
            dic.Add arr(i, 1), "KK"
          End If
     Next i
bang = dic.keys
     For i = 0 To UBound(bang)
         dk = bang(i)
         For j = 1 To a
             If UCase(dk) = UCase(arr(j, 1)) Then
                arr1(i + 1, 1) = bang(i)
                k = k + 1
                arr1(i + 1, k) = arr(j, 2)
             End If
         Next j
         k = 0
     Next i
 End With
 With Sheet2
     .Range("a2").Resize(UBound(arr1, 1), UBound(arr1, 2)).Value = arr1
End With
End Sub
 

File đính kèm

  • Data_Source.xlsm
    24.6 KB · Đọc: 13
Lần chỉnh sửa cuối:
Dear các Pro,
Mình muốn tạo 1 macro để xử lí việc đổi cột thành hàng cho các đối tượng có giá trị tương ứng. Cụ thể như sau:
Từ thong kê dạng cột:
View attachment 207952

Mình muốn đổi thành:
View attachment 207953

Do dữ lieu rất nhiều mình không thể filter từng đối tượng để copy và paste -> transpose được. Chi tiết theo file đính kèm. Xin cảm ơn nhiều!
Thấy code này trên mạng, hi vọng giúp ích. kaka. Nói trước mình không biết sửa code đâu à nha :p
Mã:
: 
Sub transposeunique()
'updateby Extendoffice 20151207
    Dim xLRow As Long
    Dim i As Long
    Dim xCrit As String
    Dim xCol  As New Collection
    Dim xRg As Range
    Dim xOutRg As Range
    Dim xTxt As String
    Dim xCount As Long
    Dim xVRg As Range
    On Error Resume Next
    xTxt = ActiveWindow.RangeSelection.Address
    Set xRg = Application.InputBox("please select data range(only two columns):", "Kutools for Excel", xTxt, , , , , 8)
    Set xRg = Application.Intersect(xRg, xRg.Worksheet.UsedRange)
    If xRg Is Nothing Then Exit Sub
    If (xRg.Columns.Count <> 2) Or _
       (xRg.Areas.Count > 1) Then
        MsgBox "the used range is only one area with two columns ", , "Kutools for Excel"
        Exit Sub
    End If
    Set xOutRg = Application.InputBox("please select output range(specify one cell):", "Kutools for Excel", xTxt, , , , , 8)
    If xOutRg Is Nothing Then Exit Sub
    Set xOutRg = xOutRg.Range(1)
    xLRow = xRg.Rows.Count
    For i = 2 To xLRow
        xCol.Add xRg.Cells(i, 1).Value, xRg.Cells(i, 1).Value
    Next
    Application.ScreenUpdating = False
    For i = 1 To xCol.Count
        xCrit = xCol.Item(i)
        xOutRg.Offset(i, 0) = xCrit
        xRg.AutoFilter Field:=1, Criteria1:=xCrit
        Set xVRg = xRg.Range("B2:B" & xLRow).SpecialCells(xlCellTypeVisible)
        If xVRg.Count > xCount Then xCount = xVRg.Count
        xRg.Range("B2:B" & xLRow).SpecialCells(xlCellTypeVisible).Copy
        xOutRg.Offset(i, 1).PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
        Application.CutCopyMode = False
    Next
    xOutRg = xRg.Cells(1, 1)
    xOutRg.Offset(0, 1).Resize(1, xCount) = xRg.Cells(1, 2)
    xRg.Rows(1).Copy
    xOutRg.Resize(1, xCount + 1).PasteSpecial Paste:=xlPasteFormats
    xRg.AutoFilter
    Application.ScreenUpdating = True
End Sub
 
Bạn thử với con này:
PHP:
Sub ColumnsToRows()
Dim Cls As Range, Rng As Range, sRng As Range
Dim Rws As Long, j As Long, W As Integer
Dim MyAdd As String

Rws = [b1].CurrentRegion.Rows.Count
Set Rng = [A1].Resize(Rws)
For Each Cls In Range([D2], [D2].End(xlDown))
    ReDim Arr(1 To 1, 1 To Rws) As Long
    Set sRng = Rng.Find(Cls.Value, , xlFormulas, xlWhole)
    If Not sRng Is Nothing Then
        MyAdd = sRng.Address
        Do
            W = W + 1:                                        Arr(1, W) = sRng.Offset(, 1).Value
            Set sRng = Rng.FindNext(sRng)
        Loop While sRng.Address <> MyAdd
    End If
    Cls.Offset(13, 1).Resize(, W).Value = Arr():      W = 0
    'Sau Khi Kiêm Tra, Thay Sô 13 => 0      '
Next Cls
End Sub
 
Thấy code này trên mạng, hi vọng giúp ích. kaka. Nói trước mình không biết sửa code đâu à nha :p
Mã:
:
Sub transposeunique()
'updateby Extendoffice 20151207
    Dim xLRow As Long
    Dim i As Long
    Dim xCrit As String
    Dim xCol  As New Collection
    Dim xRg As Range
    Dim xOutRg As Range
    Dim xTxt As String
    Dim xCount As Long
    Dim xVRg As Range
    On Error Resume Next
    xTxt = ActiveWindow.RangeSelection.Address
    Set xRg = Application.InputBox("please select data range(only two columns):", "Kutools for Excel", xTxt, , , , , 8)
    Set xRg = Application.Intersect(xRg, xRg.Worksheet.UsedRange)
    If xRg Is Nothing Then Exit Sub
    If (xRg.Columns.Count <> 2) Or _
       (xRg.Areas.Count > 1) Then
        MsgBox "the used range is only one area with two columns ", , "Kutools for Excel"
        Exit Sub
    End If
    Set xOutRg = Application.InputBox("please select output range(specify one cell):", "Kutools for Excel", xTxt, , , , , 8)
    If xOutRg Is Nothing Then Exit Sub
    Set xOutRg = xOutRg.Range(1)
    xLRow = xRg.Rows.Count
    For i = 2 To xLRow
        xCol.Add xRg.Cells(i, 1).Value, xRg.Cells(i, 1).Value
    Next
    Application.ScreenUpdating = False
    For i = 1 To xCol.Count
        xCrit = xCol.Item(i)
        xOutRg.Offset(i, 0) = xCrit
        xRg.AutoFilter Field:=1, Criteria1:=xCrit
        Set xVRg = xRg.Range("B2:B" & xLRow).SpecialCells(xlCellTypeVisible)
        If xVRg.Count > xCount Then xCount = xVRg.Count
        xRg.Range("B2:B" & xLRow).SpecialCells(xlCellTypeVisible).Copy
        xOutRg.Offset(i, 1).PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
        Application.CutCopyMode = False
    Next
    xOutRg = xRg.Cells(1, 1)
    xOutRg.Offset(0, 1).Resize(1, xCount) = xRg.Cells(1, 2)
    xRg.Rows(1).Copy
    xOutRg.Resize(1, xCount + 1).PasteSpecial Paste:=xlPasteFormats
    xRg.AutoFilter
    Application.ScreenUpdating = True
End Sub

Hihi. Nói trước mình không biết sửa code đâu à nha
 
Bạn thử với con này:
PHP:
Sub ColumnsToRows()
Dim Cls As Range, Rng As Range, sRng As Range
Dim Rws As Long, j As Long, W As Integer
Dim MyAdd As String

Rws = [b1].CurrentRegion.Rows.Count
Set Rng = [A1].Resize(Rws)
For Each Cls In Range([D2], [D2].End(xlDown))
    ReDim Arr(1 To 1, 1 To Rws) As Long
    Set sRng = Rng.Find(Cls.Value, , xlFormulas, xlWhole)
    If Not sRng Is Nothing Then
        MyAdd = sRng.Address
        Do
            W = W + 1:                                        Arr(1, W) = sRng.Offset(, 1).Value
            Set sRng = Rng.FindNext(sRng)
        Loop While sRng.Address <> MyAdd
    End If
    Cls.Offset(13, 1).Resize(, W).Value = Arr():      W = 0
    'Sau Khi Kiêm Tra, Thay Sô 13 => 0      '
Next Cls
End Sub

Many thanks bạn. Mình test với dữ lieu dạng số thì ok, còn dữ lieu mà có định dạng text thì bị báo lỗi ở phần tô đỏ. Có cách nào khắc phục ko bạn ơi?
 
Dear các Pro,
Mình muốn tạo 1 macro để xử lí việc đổi cột thành hàng cho các đối tượng có giá trị tương ứng. Cụ thể như sau:
Từ thong kê dạng cột:
View attachment 207952

Mình muốn đổi thành:
View attachment 207953

Do dữ lieu rất nhiều mình không thể filter từng đối tượng để copy và paste -> transpose được. Chi tiết theo file đính kèm. Xin cảm ơn nhiều!
Gửi bạn tham khảo:
Cột đối tượng:
PHP:
=IFERROR(T(INDEX($A$2:$A$184,MATCH(,INDEX(COUNTIF($D$15:D15,$A$2:$A$184),),0),)),"")
Fill xuống dưới:
Cột giá trị:
PHP:
=IFERROR(OFFSET($B$1,MATCH(COLUMN(A$1),INDEX(COUNTIF(OFFSET($A$2,,,ROW($1:$200)),$D16),),0),),"")
Kéo sang phải và fill xuống dưới.
 

File đính kèm

  • Data_Source.xlsx
    18.4 KB · Đọc: 11
Gửi bạn tham khảo:
Cột đối tượng:
PHP:
=IFERROR(T(INDEX($A$2:$A$184,MATCH(,INDEX(COUNTIF($D$15:D15,$A$2:$A$184),),0),)),"")
Fill xuống dưới:
Cột giá trị:
PHP:
=IFERROR(OFFSET($B$1,MATCH(COLUMN(A$1),INDEX(COUNTIF(OFFSET($A$2,,,ROW($1:$200)),$D16),),0),),"")
Kéo sang phải và fill xuống dưới.

Công thức đối tượng ra cái A11 không bạn ơi
 
Dear các Pro,
Mình muốn tạo 1 macro để xử lí việc đổi cột thành hàng cho các đối tượng có giá trị tương ứng. Cụ thể như sau:
Từ thong kê dạng cột:
View attachment 207952

Mình muốn đổi thành:
View attachment 207953

Do dữ lieu rất nhiều mình không thể filter từng đối tượng để copy và paste -> transpose được. Chi tiết theo file đính kèm. Xin cảm ơn nhiều!
bạn xem code này xem thế nào nhé
Mã:
Sub chuyen()
Dim a As Long, b As Long, i As Long, j As Long, k As Long, c As Long
Dim dk As String
Dim arr, bang
Dim dic As Object
Set dic = CreateObject("scripting.dictionary")
With Sheet1
     arr = .Range("A2:b" & .Range("a" & Rows.Count).End(xlUp).Row).Value
     a = UBound(arr, 1)
     ReDim arr1(1 To a, 1 To a)
     For i = 1 To a
         If dic.exists(arr(i, 1)) = 0 Then
            k = k + 1
            dic.Item(arr(i, 1)) = Array(k, 2)
            arr1(k, 1) = arr(i, 1)
            arr1(k, 2) = arr(i, 2)
         Else
            b = dic.Item(arr(i, 1))(0)
            c = dic.Item(arr(i, 1))(1) + 1
            arr1(b, c) = arr(i, 2)
            dic.Item(arr(i, 1)) = Array(b, c)
          End If
     Next i
     .Range("d15").Resize(UBound(arr1, 1), UBound(arr1, 2)).Value = arr1
 End With
End Sub
 
Công thức đối tượng ra cái A11 không bạn ơi
Bạn gửi cái file bị lỗi lên nó bị sai cái gì

Capture.PNG
Bài đã được tự động gộp:

Công thức đối tượng ra cái A11 không bạn ơi
Bạn để ý chỗ công thức index(countif(vùng(chỗ này đặt công thức) sẽ lấy phía trên chỗ đặt công thức.
 
Lần chỉnh sửa cuối:
Bạn gửi cái file bị lỗi lên nó bị sai cái gì

View attachment 207960
Bài đã được tự động gộp:


Bạn để ý chỗ công thức index(countif(vùng(chỗ này đặt công thức) sẽ lấy phía trên chỗ đặt công thức.

Mình làm công thức mảng nó cũng ra: Ctrl+Shift+Enter
Mã:
D2=IFERROR(INDEX($A$2:$A$184,MATCH(0,COUNTIF($D$1:D1,$A$2:$A$184),0)),"")
hoặc
Mã:
D2=IFERROR(INDEX($A$2:$A$184,MATCH(0,INDEX(COUNTIF($D$1:D1,$A$2:$A$184),0,0),0)),"")
Của bạn thì sửa D15=D1 thì nó mới đúng
Mã:
D2=IFERROR(T(INDEX($A$2:$A$184,MATCH(,INDEX(COUNTIF($D$1:D1,$A$2:$A$184),),0),)),"")
 
Lần chỉnh sửa cuối:
Mình test với dữ lieu dạng số thì ok, còn dữ lieu mà có định dạng text thì bị báo lỗi ở phần tô đỏ. Có cách nào khắc phục ko bạn ơi?
Ngay bài 1 của bạn làm gì có dữ liệu kiểu Text?
Vậy có thể bạn bỏ thử kiểu khai báo dữ liệu mảng Arr() là Variant xem sao>
 
Mình làm công thức mảng nó cũng ra: Ctrl+Shift+Enter
Mã:
D2=IFERROR(INDEX($A$2:$A$184,MATCH(0,COUNTIF($D$1:D1,$A$2:$A$184),0)),"")
hoặc
Mã:
D2=IFERROR(INDEX($A$2:$A$184,MATCH(0,INDEX(COUNTIF($D$1:D1,$A$2:$A$184),0,0),0)),"")
Của bạn thì sửa D15=D1 thì nó mới đúng
Mã:
D2=IFERROR(T(INDEX($A$2:$A$184,MATCH(,INDEX(COUNTIF($D$1:D1,$A$2:$A$184),),0),)),"")
Thì mình cũng nói là công thức đặt chỗ nào thì vùng sẽ lấy phía trên.
 
bạn xem code này xem thế nào nhé
Mã:
Sub chuyen()
Dim a As Long, b As Long, i As Long, j As Long, k As Long, c As Long
Dim dk As String
Dim arr, bang
Dim dic As Object
Set dic = CreateObject("scripting.dictionary")
With Sheet1
     arr = .Range("A2:b" & .Range("a" & Rows.Count).End(xlUp).Row).Value
     a = UBound(arr, 1)
     ReDim arr1(1 To a, 1 To a)
     For i = 1 To a
         If dic.exists(arr(i, 1)) = 0 Then
            k = k + 1
            dic.Item(arr(i, 1)) = Array(k, 2)
            arr1(k, 1) = arr(i, 1)
            arr1(k, 2) = arr(i, 2)
         Else
            b = dic.Item(arr(i, 1))(0)
            c = dic.Item(arr(i, 1))(1) + 1
            arr1(b, c) = arr(i, 2)
            dic.Item(arr(i, 1)) = Array(b, c)
          End If
     Next i
     .Range("d15").Resize(UBound(arr1, 1), UBound(arr1, 2)).Value = arr1
End With
End Sub

Mình run script của bạn bị lỗi bạn ơi!
1542669635336.png
Bài đã được tự động gộp:

Thì mình cũng nói là công thức đặt chỗ nào thì vùng sẽ lấy phía trên.
Công thức của bạn ok. Có điều với dữ liệu lớn thì excel chạy lâu lắm. Dù sao cũng rất cám ơn bạn, mình có thể áp dụng cho dữ liệu nhỏ được.
Bài đã được tự động gộp:

Ngay bài 1 của bạn làm gì có dữ liệu kiểu Text?
Vậy có thể bạn bỏ thử kiểu khai báo dữ liệu mảng Arr() là Variant xem sao>
Cảm ơn bạn rất nhiều, sau khi mình chỉnh lại Variant như bạn nói thì script chay rất OK.
 
Mình run script của bạn bị lỗi bạn ơi!
View attachment 207972
Bài đã được tự động gộp:


Công thức của bạn ok. Có điều với dữ liệu lớn thì excel chạy lâu lắm. Dù sao cũng rất cám ơn bạn, mình có thể áp dụng cho dữ liệu nhỏ được.
Bài đã được tự động gộp:


Cảm ơn bạn rất nhiều, sau khi mình chỉnh lại Variant như bạn nói thì script chay rất OK.
chắc là cái mảng bạn lấy nó bị trống dư liệu nên a nó bằng không nên khai báo bị lỗi bạn xem lại cái dữ liệu đã đúng sheets chưa nhé.
 
Ngay bài 1 của bạn làm gì có dữ liệu kiểu Text?
Vậy có thể bạn bỏ thử kiểu khai báo dữ liệu mảng Arr() là Variant xem sao>

Hi bạn,
Mình muốn các giá trị của đối tượng tương ứng sẽ được fill vào trường đối tượng tương ứng trên 1 sheet khác mà không cần phải Vlookup từng giá trị sau khi run macro có được ko bạn?
 
Web KT
Back
Top Bottom