Chuyển đổi bảng tính Excel bằng VBA

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

moihocvba

Thành viên thường trực
Tham gia
16/8/20
Bài viết
211
Được thích
50
Chào anh chị, em nhờ anh chị diễn đàn GPE viết giúp em 1 đoạn code vba để chuyển đổi bảng A thành bảng B
1677127843348.png

Trong bảng A, cột Tên khách hàng có những dòng chứa nhiều tên khách hàng ngăn cách nhau bởi dấu phẩy, em muốn chuyển sang bảng B để tách mỗi Tên khách hàng đó ra mỗi tên một dòng (Còn dòng nào có 1 tên thì vẫn giữ nguyên)

Dữ liệu của em có khoảng 10 ngàn dòng ạ.
Anh chị giúp em, em cảm ơn rất nhiều ạ!
 

File đính kèm

  • Chuyen Doi Bang.xlsx
    9.9 KB · Đọc: 17
Doanh nghiệp nào mà có hàng chục ngàn thương vụ, quản lý bằng Excel. Lại còn lập record như hạch nữa mới đã.
Không hiểu sao nó còn sống đến giờ này.

Quy trình:
- Text to column
- Cộng số dòng vào mỗi tên, cách nhau bằng dấu |
- Copy Paste transpose.
- Dùng số dòng để copy dữ liệu còn lại.
- Xóa số dòng.
 
Upvote 0
Chào anh chị, em nhờ anh chị diễn đàn GPE viết giúp em 1 đoạn code vba để chuyển đổi bảng A thành bảng B
View attachment 286839

Trong bảng A, cột Tên khách hàng có những dòng chứa nhiều tên khách hàng ngăn cách nhau bởi dấu phẩy, em muốn chuyển sang bảng B để tách mỗi Tên khách hàng đó ra mỗi tên một dòng (Còn dòng nào có 1 tên thì vẫn giữ nguyên)

Dữ liệu của em có khoảng 10 ngàn dòng ạ.
Anh chị giúp em, em cảm ơn rất nhiều ạ!
Trong khi chờ đợi VBA, dùng tạm Power Query xem sao
 

File đính kèm

  • Chuyen Doi Bang.xlsx
    19.2 KB · Đọc: 7
Upvote 0
Doanh nghiệp nào mà có hàng chục ngàn thương vụ, quản lý bằng Excel. Lại còn lập record như hạch nữa mới đã.
Không hiểu sao nó còn sống đến giờ này.

Quy trình:
- Text to column
- Cộng số dòng vào mỗi tên, cách nhau bằng dấu |
- Copy Paste transpose.
- Dùng số dòng để copy dữ liệu còn lại.
- Xóa số dòng.
Cám ơn anh ạ. Trước bước này và sau bước này có 1 loạt lệnh cần chạy VBA nữa, nên em muốn làm code VBA cho tiện ạ, em viết code trước và sau rồi, mỗi đoạn này là bí, làm sao tách được thì em không biết.
 
Upvote 0
Chào anh chị, em nhờ anh chị diễn đàn GPE viết giúp em 1 đoạn code vba để chuyển đổi bảng A thành bảng B
View attachment 286839

Trong bảng A, cột Tên khách hàng có những dòng chứa nhiều tên khách hàng ngăn cách nhau bởi dấu phẩy, em muốn chuyển sang bảng B để tách mỗi Tên khách hàng đó ra mỗi tên một dòng (Còn dòng nào có 1 tên thì vẫn giữ nguyên)

Dữ liệu của em có khoảng 10 ngàn dòng ạ.
Anh chị giúp em, em cảm ơn rất nhiều ạ!
1. Chạy vòng lặp từ đầu đến cuối bảng A.
2. Dùng hàm Instr để kiểm tra dấu phẩy có tồn tại trong cột C hay không.
3. Nếu không có: cho 1 biến đếm dòng rw tăng thêm 1, ghi thông tin dòng đó vào mảng kết quả.
4. Nếu có: dùng hàm split cắt các giá trị cột C ra thành mảng Temp. Chạy vòng lặp từ đầu đến cuối mảng Temp. Cứ mỗi giá trị Temp(i) thì tăng biến đếm rw lên 1 đơn vị. ghi thông tin từng dòng rw đó vào mảng kết quả.
5. Hết việc dán mảng kết quả xuống sheet tại bảng B.

P/S: thay cho chạy trên sheet, nên ghi bảng A vào 1 mảng rồi chạy vòng lặp trên mảng cho nhanh
 
Upvote 0
Chào anh chị, em nhờ anh chị diễn đàn GPE viết giúp em 1 đoạn code vba để chuyển đổi bảng A thành bảng B
View attachment 286839

Trong bảng A, cột Tên khách hàng có những dòng chứa nhiều tên khách hàng ngăn cách nhau bởi dấu phẩy, em muốn chuyển sang bảng B để tách mỗi Tên khách hàng đó ra mỗi tên một dòng (Còn dòng nào có 1 tên thì vẫn giữ nguyên)

Dữ liệu của em có khoảng 10 ngàn dòng ạ.
Anh chị giúp em, em cảm ơn rất nhiều ạ!
Thử xem nhé bạn!
Mã:
Public Sub BangB()
Dim sArr(), dArr(), Tmp, I As Long, J As Long, K As Long,  Rws As Long
    If Sheets("Bang A").Range("A4") <> Empty Then
        sArr = Sheets("Bang A").Range("A4", Sheets("Bang A").Range("A10000").End(xlUp)).Resize(, 3).Value
        Rws = UBound(sArr)
        ReDim dArr(1 To Rws * 100, 1 To 3)
        For I = 1 To Rws
            Tmp = Split(sArr(I, 3), ",")
            For J = 0 To UBound(Tmp)
                K = K + 1
                dArr(K, 1) = sArr(I, 1)
                dArr(K, 2) = sArr(I, 2)
                dArr(K, 3) = Trim(Tmp(J))
            Next J
        Next I
        With Sheets("Bang A")
            [E4:G100000].ClearContents
            [E4:G100000].Resize(K, 3) = dArr
        End With
    End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
1. Chạy vòng lặp từ đầu đến cuối bảng A.
2. Dùng hàm Instr để kiểm tra dấu phẩy có tồn tại trong cột C hay không.
3. Nếu không có: cho 1 biến đếm dòng rw tăng thêm 1, ghi thông tin dòng đó vào mảng kết quả.
4. Nếu có: dùng hàm split cắt các giá trị cột C ra thành mảng Temp. Chạy vòng lặp từ đầu đến cuối mảng Temp. Cứ mỗi giá trị Temp(i) thì tăng biến đếm rw lên 1 đơn vị. ghi thông tin từng dòng rw đó vào mảng kết quả.
5. Hết việc dán mảng kết quả xuống sheet tại bảng B.

P/S: thay cho chạy trên sheet, nên ghi bảng A vào 1 mảng rồi chạy vòng lặp trên mảng cho nhanh
Tại sao cần bước 2 và 3 cứ dùng hàm Split bình thường có sao đâu nhỉ.
 
Upvote 0
Thử xem nhé bạn!
Mã:
Public Sub BangB()
Dim sArr(), dArr(), Tmp, I As Long, J As Long, K As Long,  Rws As Long
    If Sheets("Bang A").Range("A4") <> Empty Then
        sArr = Sheets("Bang A").Range("A10000", Sheets("Bang A").Range("A10000").End(xlUp)).Resize(, 3).Value
        Rws = UBound(sArr)
        ReDim dArr(1 To Rws * 100, 1 To 3)
        For I = 1 To Rws
            Tmp = Split(sArr(I, 3), ",")
            For J = 0 To UBound(Tmp)
                K = K + 1
                dArr(K, 1) = sArr(I, 1)
                dArr(K, 2) = sArr(I, 2)
                dArr(K, 3) = Trim(Split(Tmp(J), "")(0))
            Next J
        Next I
        With Sheets("Bang A")
            [E4:G100000].ClearContents
            [E4:G100000].Resize(K, 3) = dArr
        End With
    End If
End Sub
code này chạy không ra đúng kết quả của chủ thớt đó anh. Em chạy thử không ra KQ đúng, không biết bị sao nhỉ.
Bài đã được tự động gộp:

Bài này em chờ anh chị nào viết để em xem và học hỏi nhưng lại không thấy anh chị nào viết tiếp.
Thôi bạn xài code chấp và của mình nhé. Mình thấy hơi chấp vá. Nhưng sử dụng được nhé bạn
Mã:
Sub chuyen_doi_bang()
On Error Resume Next

'tao bang phu
Dim dong_cuoi As Long
dong_cuoi = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
Sheet1.Range("H4").Formula = "=LEN(C4)-LEN(SUBSTITUTE(C4,"","",""""))+1"
Sheet1.Range("H4").Select
Selection.AutoFill Destination:=Range("H4:H" & dong_cuoi), Type:=xlFillDefault
Sheet1.Range("H4:H" & dong_cuoi) = Sheet1.Range("H4:H" & dong_cuoi).Value

Sheet1.Range("I4:I" & dong_cuoi) = Sheet1.Range("C4:C" & dong_cuoi).Value
Sheet1.Range("I4:I" & dong_cuoi).Replace What:=",*", Replacement:=""

'dung mang cho cot E
Dim shData As Worksheet
Dim arrData, arrSoLuong, arrKetQua
Dim e As Long, h As Long, n As Long, r As Long, s As Long
Set shData = Sheet1
e = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
arrData = shData.Range("A4:A" & e).Value
arrSoLuong = shData.Range("H4:H" & e).Value
s = WorksheetFunction.Sum(arrSoLuong)
ReDim arrKetQua(1 To s, 1 To 1)
For r = 1 To UBound(arrData)
For h = 1 To arrSoLuong(r, 1)
n = n + 1
arrKetQua(n, 1) = arrData(r, 1)
Next
Next
shData.Range("E4").Resize(s).Value = arrKetQua
'dung mang cho cot F
Dim arrDataB, arrSoLuongB, arrKetQuaB
Dim eB As Long, hB As Long, nB As Long, rB As Long, sB As Long
eB = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
arrDataB = shData.Range("B4:B" & eB).Value
arrSoLuongB = shData.Range("H4:H" & eB).Value
sB = WorksheetFunction.Sum(arrSoLuongB)
ReDim arrKetQuaB(1 To sB, 1 To 1)
For rB = 1 To UBound(arrDataB)
For hB = 1 To arrSoLuongB(rB, 1)
nB = nB + 1
arrKetQuaB(nB, 1) = arrDataB(rB, 1)
Next
Next
shData.Range("F4").Resize(sB).Value = arrKetQuaB
'dung mang cho cot G
Dim arrDataC, arrSoLuongC, arrKetQuaC
Dim eC As Long, hC As Long, nC As Long, rC As Long, sC As Long
eC = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
arrDataC = shData.Range("I4:I" & eC).Value
arrSoLuongC = shData.Range("H4:H" & eC).Value
sC = WorksheetFunction.Sum(arrSoLuongC)
ReDim arrKetQuaC(1 To sC, 1 To 1)
For rC = 1 To UBound(arrDataC)
For hC = 1 To arrSoLuongC(rC, 1)
nC = nC + 1
arrKetQuaC(nC, 1) = arrDataC(rC, 1)
Next
Next
shData.Range("G4").Resize(sC).Value = arrKetQuaC

'xoa cot H va cot I
Sheet1.Range("H4:I" & dong_cuoi).ClearContents
End Sub
 
Upvote 0
Công thức sử dụng E365
Mã:
=LET(a,A4:A7,b,B4:B7,d,C4:C7,n,LEN(d)-LEN(SUBSTITUTE(d,",",""))+1,e,LAMBDA(x,TEXTSPLIT(CONCAT(x&","),,",",1)),TRIM(HSTACK(e(REPT(a&",",n)),e(REPT(b&",",n)),e(d))))
 
Upvote 1
code này chạy không ra đúng kết quả của chủ thớt đó anh. Em chạy thử không ra KQ đúng, không biết bị sao nhỉ.
Bài đã được tự động gộp:

Bài này em chờ anh chị nào viết để em xem và học hỏi nhưng lại không thấy anh chị nào viết tiếp.
Thôi bạn xài code chấp và của mình nhé. Mình thấy hơi chấp vá. Nhưng sử dụng được nhé bạn
Mã:
Sub chuyen_doi_bang()
On Error Resume Next

'tao bang phu
Dim dong_cuoi As Long
dong_cuoi = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
Sheet1.Range("H4").Formula = "=LEN(C4)-LEN(SUBSTITUTE(C4,"","",""""))+1"
Sheet1.Range("H4").Select
Selection.AutoFill Destination:=Range("H4:H" & dong_cuoi), Type:=xlFillDefault
Sheet1.Range("H4:H" & dong_cuoi) = Sheet1.Range("H4:H" & dong_cuoi).Value

Sheet1.Range("I4:I" & dong_cuoi) = Sheet1.Range("C4:C" & dong_cuoi).Value
Sheet1.Range("I4:I" & dong_cuoi).Replace What:=",*", Replacement:=""

'dung mang cho cot E
Dim shData As Worksheet
Dim arrData, arrSoLuong, arrKetQua
Dim e As Long, h As Long, n As Long, r As Long, s As Long
Set shData = Sheet1
e = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
arrData = shData.Range("A4:A" & e).Value
arrSoLuong = shData.Range("H4:H" & e).Value
s = WorksheetFunction.Sum(arrSoLuong)
ReDim arrKetQua(1 To s, 1 To 1)
For r = 1 To UBound(arrData)
For h = 1 To arrSoLuong(r, 1)
n = n + 1
arrKetQua(n, 1) = arrData(r, 1)
Next
Next
shData.Range("E4").Resize(s).Value = arrKetQua
'dung mang cho cot F
Dim arrDataB, arrSoLuongB, arrKetQuaB
Dim eB As Long, hB As Long, nB As Long, rB As Long, sB As Long
eB = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
arrDataB = shData.Range("B4:B" & eB).Value
arrSoLuongB = shData.Range("H4:H" & eB).Value
sB = WorksheetFunction.Sum(arrSoLuongB)
ReDim arrKetQuaB(1 To sB, 1 To 1)
For rB = 1 To UBound(arrDataB)
For hB = 1 To arrSoLuongB(rB, 1)
nB = nB + 1
arrKetQuaB(nB, 1) = arrDataB(rB, 1)
Next
Next
shData.Range("F4").Resize(sB).Value = arrKetQuaB
'dung mang cho cot G
Dim arrDataC, arrSoLuongC, arrKetQuaC
Dim eC As Long, hC As Long, nC As Long, rC As Long, sC As Long
eC = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
arrDataC = shData.Range("I4:I" & eC).Value
arrSoLuongC = shData.Range("H4:H" & eC).Value
sC = WorksheetFunction.Sum(arrSoLuongC)
ReDim arrKetQuaC(1 To sC, 1 To 1)
For rC = 1 To UBound(arrDataC)
For hC = 1 To arrSoLuongC(rC, 1)
nC = nC + 1
arrKetQuaC(nC, 1) = arrDataC(rC, 1)
Next
Next
shData.Range("G4").Resize(sC).Value = arrKetQuaC

'xoa cot H va cot I
Sheet1.Range("H4:I" & dong_cuoi).ClearContents
End Sub
Mình sửa lại ở #6 rồi bạn. Nhờ bạn test giúp mình!
 
Upvote 0
Thử xem nhé bạn!
Mã:
Public Sub BangB()
Dim sArr(), dArr(), Tmp, I As Long, J As Long, K As Long,  Rws As Long
    If Sheets("Bang A").Range("A4") <> Empty Then
        sArr = Sheets("Bang A").Range("A4", Sheets("Bang A").Range("A10000").End(xlUp)).Resize(, 3).Value
        Rws = UBound(sArr)
        ReDim dArr(1 To Rws * 100, 1 To 3)
        For I = 1 To Rws
            Tmp = Split(sArr(I, 3), ",")
            For J = 0 To UBound(Tmp)
                K = K + 1
                dArr(K, 1) = sArr(I, 1)
                dArr(K, 2) = sArr(I, 2)
                dArr(K, 3) = Trim(Split(Tmp(J), "")(0))
            Next J
        Next I
        With Sheets("Bang A")
            [E4:G100000].ClearContents
            [E4:G100000].Resize(K, 3) = dArr
        End With
    End If
End Sub
Sao lại tách 2 lần làm gì vậy.
 
Upvote 0
dArr(K, 3) = Trim(Split(Tmp(J), "")(0))
Cái đoạn này đâu cần split nữa vậy
Chủ thớt có thể tham khảo thêm cách khác
Mã:
Option Explicit

Sub Tach()
    Dim sArr(), Res(), i&, j&, S, n&
    With Sheets("Bang A")
        sArr = .Range("A4:C" & .Range("A" & Rows.Count).End(3).Row).Value
        ReDim Res(1 To 10000, 1 To 3)
        For i = 1 To UBound(sArr)
            S = Split(sArr(i, 3), ",")
            For j = 0 To UBound(S)
                n = n + 1
                Res(n, 1) = sArr(i, 1)
                Res(n, 2) = sArr(i, 2)
                Res(n, 3) = Trim(S(j))
            Next
        Next
        If n Then
            .Range("E4").Resize(10000, 3).ClearContents
            .Range("E4").Resize(n, 3).Value = Res
        End If
    End With
    MsgBox "Done"
End Sub
 
Upvote 0
Cái đoạn này đâu cần split nữa vậy
Chủ thớt có thể tham khảo thêm cách khác
Mã:
Option Explicit

Sub Tach()
    Dim sArr(), Res(), i&, j&, S, n&
    With Sheets("Bang A")
        sArr = .Range("A4:C" & .Range("A" & Rows.Count).End(3).Row).Value
        ReDim Res(1 To 10000, 1 To 3)
        For i = 1 To UBound(sArr)
            S = Split(sArr(i, 3), ",")
            For j = 0 To UBound(S)
                n = n + 1
                Res(n, 1) = sArr(i, 1)
                Res(n, 2) = sArr(i, 2)
                Res(n, 3) = Trim(S(j))
            Next
        Next
        If n Then
            .Range("E4").Resize(10000, 3).ClearContents
            .Range("E4").Resize(n, 3).Value = Res
        End If
    End With
    MsgBox "Done"
End Sub
vâng cám ơn mọi người đã hỗ trợ em. Em áp dụng code này đã thành công rồi ạ!
 
Upvote 0
GPE này có tật, người đi trước làm cái gì rồi thì các người đi sau cứ theo kiểu ấy.

Ở đây, chuỗi chỉ cần tách ra rồi lấy từng phần tử. Và chỉ lấy một lần. Như vậy biến tạm không cần thiết phải lấy cả mảng, chỉ cần lấy từng phần tử thôi.

Tmp = Split(sArr(I, 3), ",")
For Each tmp in Split(Replace(sArr(I, 3), ", ", ","), ",")
K = K + 1
dArr(K, 1) = sArr(I, 1)
dArr(K, 2) = sArr(I, 2)
dArr(K, 3) = tmp
Next tmp

Chú thích:
Viết code tránh đặt tên biến là i viết hoa, I. Lý do: khó phân biệt với l, khi gặp các phông sans serif. Nếu trình duyệt của bạn dùng phông Arial, bạn hiểu tôi nói gì ngay.
i chỉ nên viết thường.
 
Upvote 0
Một cách khác chậm hơn:
Mã:
Option Explicit

Sub BonChen()

    Dim sArr() As Variant, Res() As Variant, Tmp() As String, Value As String
    Dim i As Long, j As Long, n As Long, r As Long
    
    With ThisWorkbook.Worksheets("Bang A")
        r = .Cells(.Rows.Count, "A").End(xlUp).Row
        sArr = .Range("A4:C" & r).Value
    End With
    
    ReDim TempArray(1 To UBound(sArr) * 100, 1 To 3)
    For i = 1 To UBound(sArr)
        Tmp = Split(sArr(i, 3), ",")
        For j = LBound(Tmp) To UBound(Tmp)
            n = n + 1
            Value = Trim$(Tmp(j))
            TempArray(n, 1) = sArr(i, 1)
            TempArray(n, 2) = sArr(i, 2)
            TempArray(n, 3) = Value
        Next j
    Next i
    
    ReDim Res(1 To n, 1 To 3)
    For i = 1 To n
        Res(i, 1) = TempArray(i, 1)
        Res(i, 2) = TempArray(i, 2)
        Res(i, 3) = TempArray(i, 3)
    Next i
    
    If n > 0 Then
        With ThisWorkbook.Worksheets("Bang A")
            r = .Cells(.Rows.Count, "E").End(xlUp).Row
            .Range("E4").Resize(r, 3).ClearContents
            .Range("E4").Resize(n, 3).Value = Res
        End With
    End If

    MsgBox "Done"

End Sub
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom