tranphuson
Thành viên thường trực




- Tham gia
- 14/8/09
- Bài viết
- 268
- Được thích
- 10
- Giới tính
- Nam
Bài này của bạn đâu phải dùng sumif nhỉ.Vui lòng hỗ trợ hàm Sumif bằng VBA file đính kèm.
Trong đây có 2 Sheet: Sheet 1 "Dữ liệu" và Sheet 2 "KQ": ở Sheet "KQ" thì dò tìm phòng ban và mã hàng theo Sheet "Dữ liệu" từ cột C đến cột G
Xin cảm ơn
Vậy bạn thử tính kết quả bằng tay vào file xem sao nhé.Tính tổng dựa theo phòng ban và mã hàng
Bạn thử code siêu dở này xem:Vui lòng hỗ trợ hàm Sumif bằng VBA file đính kèm.
Trong đây có 2 Sheet: Sheet 1 "Dữ liệu" và Sheet 2 "KQ": ở Sheet "KQ" thì dò tìm phòng ban và mã hàng theo Sheet "Dữ liệu" từ cột C đến cột G
Xin cảm ơn
Option Explicit
Sub Dung_Tin_Vao_Code_Cua_OT()
Dim aMaHang() As Variant, aDulieu() As Variant
Dim R As Long, I As Long, J As Long, Lr As Long
With ThisWorkbook.Worksheets("Du lieu")
Lr = .Cells(.Rows.Count, "B").End(xlUp).Row
If Lr < 4 Then
MsgBox "Khong co du lieu dau vao": Exit Sub
End If
aDulieu = .Range("B3:G" & Lr).Value2
End With
With ThisWorkbook.Worksheets("KQ")
Lr = .Cells(.Rows.Count, "C").End(xlUp).Row
If Lr < 4 Then
MsgBox "Khong co du lieu can tim": Exit Sub
End If
aMaHang = .Range("C4:E" & Lr).Value2
For R = 1 To UBound(aMaHang, 1)
For I = 1 To UBound(aDulieu, 1)
For J = 1 To UBound(aDulieu, 2)
If aMaHang(R, 1) = aDulieu(I, 1) Then
If aMaHang(R, 2) = aDulieu(1, J) Then
aMaHang(R, 3) = aDulieu(I, J)
End If
End If
Next J
Next I
Next R
With .Range("G4").Resize(UBound(aMaHang, 1), UBound(aMaHang, 2))
.ClearContents
.Value = aMaHang
End With
End With
End Sub
Cảm ơn Chị, nhưng khi chạy VBA thì dữ liệu (double: nhân đôi) thêm từ Cột G đến Cột I. Nếu được thì mình cần anh hỗ trợ lấy dữ liệu như vậy nhưng không cần dữ liệu có sẵn cột B, C, DBạn thử code siêu dở này xem:
Mã:Option Explicit Sub Dung_Tin_Vao_Code_Cua_OT() Dim aMaHang() As Variant, aDulieu() As Variant Dim R As Long, I As Long, J As Long, Lr As Long With ThisWorkbook.Worksheets("Du lieu") Lr = .Cells(.Rows.Count, "B").End(xlUp).Row If Lr < 4 Then MsgBox "Khong co du lieu dau vao": Exit Sub End If aDulieu = .Range("B3:G" & Lr).Value2 End With With ThisWorkbook.Worksheets("KQ") Lr = .Cells(.Rows.Count, "C").End(xlUp).Row If Lr < 4 Then MsgBox "Khong co du lieu can tim": Exit Sub End If aMaHang = .Range("C4:E" & Lr).Value2 For R = 1 To UBound(aMaHang, 1) For I = 1 To UBound(aDulieu, 1) For J = 1 To UBound(aDulieu, 2) If aMaHang(R, 1) = aDulieu(I, 1) Then If aMaHang(R, 2) = aDulieu(1, J) Then aMaHang(R, 3) = aDulieu(I, J) End If End If Next J Next I Next R With .Range("G4").Resize(UBound(aMaHang, 1), UBound(aMaHang, 2)) .ClearContents .Value = aMaHang End With End With End Sub
Cô quân nhân code hay vậy mà bài của mình không quá khó mà lại không code được, kỳ à nhaBạn thử code siêu dở này xem:
Mã:Option Explicit Sub Dung_Tin_Vao_Code_Cua_OT() Dim aMaHang() As Variant, aDulieu() As Variant Dim R As Long, I As Long, J As Long, Lr As Long With ThisWorkbook.Worksheets("Du lieu") Lr = .Cells(.Rows.Count, "B").End(xlUp).Row If Lr < 4 Then MsgBox "Khong co du lieu dau vao": Exit Sub End If aDulieu = .Range("B3:G" & Lr).Value2 End With With ThisWorkbook.Worksheets("KQ") Lr = .Cells(.Rows.Count, "C").End(xlUp).Row If Lr < 4 Then MsgBox "Khong co du lieu can tim": Exit Sub End If aMaHang = .Range("C4:E" & Lr).Value2 For R = 1 To UBound(aMaHang, 1) For I = 1 To UBound(aDulieu, 1) For J = 1 To UBound(aDulieu, 2) If aMaHang(R, 1) = aDulieu(I, 1) Then If aMaHang(R, 2) = aDulieu(1, J) Then aMaHang(R, 3) = aDulieu(I, J) End If End If Next J Next I Next R With .Range("G4").Resize(UBound(aMaHang, 1), UBound(aMaHang, 2)) .ClearContents .Value = aMaHang End With End With End Sub
Cảm ơn Chị, nhưng khi chạy VBA thì dữ liệu (double: nhân đôi) thêm từ Cột G đến Cột I. Nếu được thì mình cần anh hỗ trợ lấy dữ liệu như vậy nhưng không cần dữ liệu có sẵn cột B, C, D
View attachment 252411
Còn nếu xóa dữ liệu từ Cột B tới E thì báo
View attachment 252412
Option Explicit
Sub Dung_Tin_Vao_Code_Cua_OT()
Dim aDULIEU() As Variant, aKETQUA() As Variant
Dim iMa As Long, jPhong As Long, r As Long
Dim DongCuoi As Long, CotCuoi As Long
Const B_D_C_E As Integer = 4
With ThisWorkbook.Worksheets("Du lieu")
DongCuoi = .Cells(.Rows.Count, "B").End(xlUp).Row
CotCuoi = .Cells(3, .Columns.Count).End(xlToLeft).Column
If DongCuoi < 4 Or CotCuoi < 3 Then
MsgBox "Khong co du lieu dau vao": Exit Sub
End If
DongCuoi = DongCuoi - 2: CotCuoi = CotCuoi - 1
aDULIEU = .Range("B3").Resize(DongCuoi, CotCuoi).Value2
ReDim aKETQUA(1 To DongCuoi * CotCuoi, 1 To B_D_C_E)
End With
With ThisWorkbook.Worksheets("KQ")
For jPhong = 2 To UBound(aDULIEU, 2)
For iMa = 2 To UBound(aDULIEU, 1)
r = r + 1
aKETQUA(r, 1) = r
aKETQUA(r, 2) = aDULIEU(iMa, 1)
aKETQUA(r, 3) = aDULIEU(1, jPhong)
aKETQUA(r, 4) = aDULIEU(iMa, jPhong)
Next iMa
Next jPhong
DongCuoi = .Cells(.Rows.Count, "B").End(xlUp).Row
If DongCuoi > 3 Then
DongCuoi = DongCuoi - 3
.Range("B4").Resize(DongCuoi, B_D_C_E).ClearContents
End If
.Range("B4").Resize(r, B_D_C_E) = aKETQUA
End With
End Sub
Cô quân nhân code hay vậy mà bài của mình không quá khó mà lại không code được, kỳ à nha![]()
Rất tốt cảm ơn bạn. Nhân tiện làm phiền bạn giúp thêm nếu Sheet "KQ" thêm 1 số dòng để nhập dữ liệu bằng tay. Do vậy Cột "Phòng ban và số lượng" sẽ dời qua Cột S và T. Cảm ơnBấm mặt cười bạn nhé:
Mã:Option Explicit Sub Dung_Tin_Vao_Code_Cua_OT() Dim aDULIEU() As Variant, aKETQUA() As Variant Dim iMa As Long, jPhong As Long, r As Long Dim DongCuoi As Long, CotCuoi As Long Const B_D_C_E As Integer = 4 With ThisWorkbook.Worksheets("Du lieu") DongCuoi = .Cells(.Rows.Count, "B").End(xlUp).Row CotCuoi = .Cells(3, .Columns.Count).End(xlToLeft).Column If DongCuoi < 4 Or CotCuoi < 3 Then MsgBox "Khong co du lieu dau vao": Exit Sub End If DongCuoi = DongCuoi - 2: CotCuoi = CotCuoi - 1 aDULIEU = .Range("B3").Resize(DongCuoi, CotCuoi).Value2 ReDim aKETQUA(1 To DongCuoi * CotCuoi, 1 To B_D_C_E) End With With ThisWorkbook.Worksheets("KQ") For jPhong = 2 To UBound(aDULIEU, 2) For iMa = 2 To UBound(aDULIEU, 1) r = r + 1 aKETQUA(r, 1) = r aKETQUA(r, 2) = aDULIEU(iMa, 1) aKETQUA(r, 3) = aDULIEU(1, jPhong) aKETQUA(r, 4) = aDULIEU(iMa, jPhong) Next iMa Next jPhong DongCuoi = .Cells(.Rows.Count, "B").End(xlUp).Row If DongCuoi > 3 Then DongCuoi = DongCuoi - 3 .Range("B4").Resize(DongCuoi, B_D_C_E).ClearContents End If .Range("B4").Resize(r, B_D_C_E) = aKETQUA End With End Sub
Uầy hay thật á Bạn, Hic...OT cũng không hiểu có thể do yêu cầu của Sếp khiến cho OT mất hết tự tin ạ.
Nên dùng Pivot Table đi, dời cột, chỉnh bảng không vất vả như VBA phụ thuộcRất tốt cảm ơn bạn. Nhân tiện làm phiền bạn giúp thêm nếu Sheet "KQ" thêm 1 số dòng để nhập dữ liệu bằng tay. Do vậy Cột "Phòng ban và số lượng" sẽ dời qua Cột S và T. Cảm ơn
View attachment 252437
Quan trọng là học hỏi VBA thoi anh oi.Nên dùng Pivot Table đi, dời cột, chỉnh bảng không vất vả như VBA phụ thuộc
Vậy thì cứ học thôi, học thì nên học sao cho kỹ: thử làm, thử sai, chạy thử trước khi hỏi. Sao cho dời cột vẫn áp dụng đượcQuan trọng là học hỏi VBA thoi anh oi.
Còn làm thì thiếu gì cách?
Bạn kiểm tra nhé:Rất tốt cảm ơn bạn. Nhân tiện làm phiền bạn giúp thêm nếu Sheet "KQ" thêm 1 số dòng để nhập dữ liệu bằng tay. Do vậy Cột "Phòng ban và số lượng" sẽ dời qua Cột S và T. Cảm ơn
View attachment 252437
Sub Khong_Tot_Lam()
Dim aDULIEU() As Variant, aSaoLaiMaHang() As Variant, aKETQUA() As Variant
Dim iMa As Long, jPhong As Long, r As Long, SoDong As Long, SoCot As Long, Wb As Workbook
Const O_Nhap_Lieu_Dau_Tien As String = "B4" 'Chỉnh sửa ô đầu tiên điền dữ liệu ở đây
Const SoCotThemVao As Long = 15 'điền số cột thêm vào ở đây,ví dụ bạn thêm mới 15 cột (tính từ cột D đến cột R) thì điền 15
Set Wb = ThisWorkbook
With Wb.Worksheets("Du lieu")
SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row
SoCot = .Cells(3, .Columns.Count).End(xlToLeft).Column
If SoDong < 4 Or SoCot < 3 Then
MsgBox "Khong co du lieu dau vao": Exit Sub
End If
SoDong = SoDong - 2: SoCot = SoCot - 1
aDULIEU = .Range("B3").Resize(SoDong, SoCot).Value2
ReDim aSaoLaiMaHang(1 To SoDong * SoCot, 1 To 2)
ReDim aKETQUA(1 To SoDong * SoCot, 1 To 2)
End With
With Wb.Worksheets("KQ")
For jPhong = 2 To UBound(aDULIEU, 2)
For iMa = 2 To UBound(aDULIEU, 1)
r = r + 1
aSaoLaiMaHang(r, 1) = r
aSaoLaiMaHang(r, 2) = aDULIEU(iMa, 1)
aKETQUA(r, 1) = aDULIEU(1, jPhong)
aKETQUA(r, 2) = aDULIEU(iMa, jPhong)
Next iMa
Next jPhong
SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row
If SoDong > 3 Then
SoDong = SoDong - 3
.Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents
End If
With .Range(O_Nhap_Lieu_Dau_Tien)
.Resize(r, 2) = aSaoLaiMaHang
.Offset(, SoCotThemVao + 2).Resize(r, 2) = aKETQUA
End With
End With
End Sub
Nếu nghĩ xa về tương lai thì học Pivot quan trọng hơn học code.Quan trọng là học hỏi VBA thoi anh oi.
Còn làm thì thiếu gì cách?
Vâng ạ, cháu cảm ơn Bác!Nếu nghĩ xa về tương lai thì học Pivot quan trọng hơn học code.
Pivot là công cụ của quản lý. Code là công cụ của cấp dưới hoặc của người muốn dùng VBA làm thú tiêu khiển.
Quá tuyệt, nhưng lần cuối làm phiền bạn là bên kế toán cần bổ sung thêm cột ở Sheet "Du lieu" thì chỉnh sửa như thế nào.Bạn kiểm tra nhé:
Code thêm một mảng 'aSaoLaiMaHang' (Phòng ban thường đi với mã nhân viên)
Bạn chú ý thêm câu lệnh này sẽ xóa cả dữ liệu nhập tay của bạn và dữ liệu do code thêm vào:
.Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents
Nếu bạn muốn chỉ xóa dữ liệu do code thêm vào thì chỉnh lại dòng đó bạn nhé.
Mã:Sub Khong_Tot_Lam() Dim aDULIEU() As Variant, aSaoLaiMaHang() As Variant, aKETQUA() As Variant Dim iMa As Long, jPhong As Long, r As Long, SoDong As Long, SoCot As Long, Wb As Workbook Const O_Nhap_Lieu_Dau_Tien As String = "B4" 'Chỉnh sửa ô đầu tiên điền dữ liệu ở đây Const SoCotThemVao As Long = 15 'điền số cột thêm vào ở đây,ví dụ bạn thêm mới 15 cột (tính từ cột D đến cột R) thì điền 15 Set Wb = ThisWorkbook With Wb.Worksheets("Du lieu") SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row SoCot = .Cells(3, .Columns.Count).End(xlToLeft).Column If SoDong < 4 Or SoCot < 3 Then MsgBox "Khong co du lieu dau vao": Exit Sub End If SoDong = SoDong - 2: SoCot = SoCot - 1 aDULIEU = .Range("B3").Resize(SoDong, SoCot).Value2 ReDim aSaoLaiMaHang(1 To SoDong * SoCot, 1 To 2) ReDim aKETQUA(1 To SoDong * SoCot, 1 To 2) End With With Wb.Worksheets("KQ") For jPhong = 2 To UBound(aDULIEU, 2) For iMa = 2 To UBound(aDULIEU, 1) r = r + 1 aSaoLaiMaHang(r, 1) = r aSaoLaiMaHang(r, 2) = aDULIEU(iMa, 1) aKETQUA(r, 1) = aDULIEU(1, jPhong) aKETQUA(r, 2) = aDULIEU(iMa, jPhong) Next iMa Next jPhong SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row If SoDong > 3 Then SoDong = SoDong - 3 .Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents End If With .Range(O_Nhap_Lieu_Dau_Tien) .Resize(r, 2) = aSaoLaiMaHang .Offset(, SoCotThemVao + 2).Resize(r, 2) = aKETQUA End With End With End Sub
Quá tuyệt, nhưng lần cuối làm phiền bạn là bên kế toán cần bổ sung thêm cột ở Sheet "Du lieu" thì chỉnh sửa như thế nào.
Xin lỗi đã làm phiền bạn chỉnh sửa nhiều lần. Cảm ơn sự hỗ trợ rất nhiệt tình này
View attachment 252459
Option Explicit
Sub Khong_Tot_Lam()
Dim aDULIEU() As Variant, aSaoLaiMaHang() As Variant, aKETQUA() As Variant
Dim iMa As Long, jPhong As Long, r As Long, SoDong As Long, SoCot As Long, Wb As Workbook
Const O_Nhap_Lieu_Dau_Tien As String = "B4"
Const SoCotThemVao As Long = 15'Số cột thêm sheet KQ
Const CotDuLieuThem As Long = 8 'Số cột thêm sheet Dữ liệu
Set Wb = ThisWorkbook
With Wb.Worksheets("Du lieu")
SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row
SoCot = .Cells(3, .Columns.Count).End(xlToLeft).Column
If SoDong < 4 Or SoCot < 3 + CotDuLieuThem Then
MsgBox "Khong co du lieu dau vao": Exit Sub
End If
SoDong = SoDong - 2: SoCot = SoCot - 1
aDULIEU = .Range("B3").Resize(SoDong, SoCot).Value2
SoCot = SoCot - (1 + CotDuLieuThem)
SoDong = SoDong - 1
ReDim aSaoLaiMaHang(1 To SoDong * SoCot, 1 To 2)
ReDim aKETQUA(1 To SoDong * SoCot, 1 To 2)
End With
With Wb.Worksheets("KQ")
SoCot = 2 + CotDuLieuThem
For jPhong = SoCot To UBound(aDULIEU, 2)
For iMa = 2 To UBound(aDULIEU, 1)
r = r + 1
aSaoLaiMaHang(r, 1) = r
aSaoLaiMaHang(r, 2) = aDULIEU(iMa, 1)
aKETQUA(r, 1) = aDULIEU(1, jPhong)
aKETQUA(r, 2) = aDULIEU(iMa, jPhong)
Next iMa
Next jPhong
SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row
If SoDong > 3 Then
SoDong = SoDong - 3
.Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents
End If
With .Range(O_Nhap_Lieu_Dau_Tien)
.Resize(r, 2) = aSaoLaiMaHang
.Offset(, SoCotThemVao + 2).Resize(r, 2) = aKETQUA
End With
End With
End Sub
Em thắc mắc là con lừa về tới cổng rồi, không biết đã gặm được miếng củ cải nào chưa?VBA chỉ là nhỏng nhẽo. Người ta biết đòi thì thế nào cũng có người viết giùm thôi
Cảm ơn bạn đã hỗ trợ rất nhiều.Híc mấy bữa nay ngủ OT toàn mơ về code không à, bạn chú ý sửa 2 dòng này nhé:
Const SoCotThemVao As Long = 15 'Số cột thêm sheet KQ
Const CotDuLieuThem As Long = 8 'Số cột thêm sheet Dữ liệu
Mã:Option Explicit Sub Khong_Tot_Lam() Dim aDULIEU() As Variant, aSaoLaiMaHang() As Variant, aKETQUA() As Variant Dim iMa As Long, jPhong As Long, r As Long, SoDong As Long, SoCot As Long, Wb As Workbook Const O_Nhap_Lieu_Dau_Tien As String = "B4" Const SoCotThemVao As Long = 15'Số cột thêm sheet KQ Const CotDuLieuThem As Long = 8 'Số cột thêm sheet Dữ liệu Set Wb = ThisWorkbook With Wb.Worksheets("Du lieu") SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row SoCot = .Cells(3, .Columns.Count).End(xlToLeft).Column If SoDong < 4 Or SoCot < 3 + CotDuLieuThem Then MsgBox "Khong co du lieu dau vao": Exit Sub End If SoDong = SoDong - 2: SoCot = SoCot - 1 aDULIEU = .Range("B3").Resize(SoDong, SoCot).Value2 SoCot = SoCot - (1 + CotDuLieuThem) SoDong = SoDong - 1 ReDim aSaoLaiMaHang(1 To SoDong * SoCot, 1 To 2) ReDim aKETQUA(1 To SoDong * SoCot, 1 To 2) End With With Wb.Worksheets("KQ") SoCot = 2 + CotDuLieuThem For jPhong = SoCot To UBound(aDULIEU, 2) For iMa = 2 To UBound(aDULIEU, 1) r = r + 1 aSaoLaiMaHang(r, 1) = r aSaoLaiMaHang(r, 2) = aDULIEU(iMa, 1) aKETQUA(r, 1) = aDULIEU(1, jPhong) aKETQUA(r, 2) = aDULIEU(iMa, jPhong) Next iMa Next jPhong SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row If SoDong > 3 Then SoDong = SoDong - 3 .Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents End If With .Range(O_Nhap_Lieu_Dau_Tien) .Resize(r, 2) = aSaoLaiMaHang .Offset(, SoCotThemVao + 2).Resize(r, 2) = aKETQUA End With End With End Sub
Bài nầy nên dùng công thức ExcelQuá tuyệt, nhưng lần cuối làm phiền bạn là bên kế toán cần bổ sung thêm cột ở Sheet "Du lieu" thì chỉnh sửa như thế nào.
Xin lỗi đã làm phiền bạn chỉnh sửa nhiều lần. Cảm ơn sự hỗ trợ rất nhiệt tình này
View attachment 252459
Sub ABC()
Dim aMa(), aPhong(), aDuLieu(), Res(), Res2()
Dim eRow&, i&, k&, j&, sRow&, sCol&, sRowRes&
With Sheets("Du lieu")
eRow = .Range("B" & Rows.Count).End(xlUp).Row
If eRow < 4 Then MsgBox "Khong co du lieu dau vao": Exit Sub
aMa = .Range("B4:B" & eRow).Value
aPhong = .Range("K3:O3").Value
aDuLieu = .Range("K4:O" & eRow).Value
End With
sRow = UBound(aDuLieu): sCol = UBound(aDuLieu, 2)
sRowRes = sRow * sCol
ReDim Res(1 To sRowRes, 1 To 2)
ReDim Res2(1 To sRowRes, 1 To 2)
For j = 1 To sCol
For i = 1 To sRow
k = k + 1
Res(k, 1) = k
Res(k, 2) = aMa(i, 1)
Res2(k, 1) = aPhong(1, j)
Res2(k, 2) = aDuLieu(i, j)
Next i
Next j
With Sheets("KQ")
eRow = .Range("B" & Rows.Count).End(xlUp).Row
If eRow > 3 Then
.Range("B4:C" & eRow).ClearContents
.Range("S4:T" & eRow).ClearContents
End If
.Range("B4").Resize(sRowRes, 2) = Res
.Range("S4").Resize(sRowRes, 2) = Res2
End With
End Sub
Con chào Bác @HieuCD,Bài nầy nên dùng công thức Excel
Thử code
Mã:Sub ABC() Dim aMa(), aPhong(), aDuLieu(), Res(), Res2() Dim eRow&, i&, k&, j&, sRow&, sCol&, sRowRes& With Sheets("Du lieu") eRow = .Range("B" & Rows.Count).End(xlUp).Row If eRow < 4 Then MsgBox "Khong co du lieu dau vao": Exit Sub aMa = .Range("B4:B" & eRow).Value aPhong = .Range("K3:O3").Value aDuLieu = .Range("K4:O" & eRow).Value End With sRow = UBound(aDuLieu): sCol = UBound(aDuLieu, 2) sRowRes = sRow * sCol ReDim Res(1 To sRowRes, 1 To 2) ReDim Res2(1 To sRowRes, 1 To 2) For j = 1 To sCol For i = 1 To sRow k = k + 1 Res(k, 1) = k Res(k, 2) = aMa(i, 1) Res2(k, 1) = aPhong(1, j) Res2(k, 2) = aDuLieu(i, j) Next i Next j With Sheets("KQ") eRow = .Range("B" & Rows.Count).End(xlUp).Row If eRow > 3 Then Range("B4:C" & eRow).ClearContents Range("S4:T" & eRow).ClearContents End If .Range("B4").Resize(sRowRes, 2) = Res .Range("S4").Resize(sRowRes, 2) = Res2 End With End Sub
Dùng Dic.item(Mã hàng & Phòng)= thứ tự dòng kết quả, cuối cùng sort kết quả theo Phòng và Mã hàngCon chào Bác @HieuCD,
Hôm nay Bác lại có hứng thú vậy, tuyệt thật cảm ơn Bác đã tham gia trước đó con cứ mong mãi xem ai đó vào giúp con một tay để thế chỗ con
Giả sử có nhiều Phòng Ban trùng nhau trong hàng ngang hoặc nhiều mã hàng trùng nhau trong cột dọc,những chỗ trùng đó muốn gộp lại thành 1.
Như vậy sẽ sử dụng Dic như thế nào vậy Bác, Bác chỉ dẫn thêm cho con cách dùng này với.
Dạ vâng, con cảm Bác đã chỉ dẫn. Con sẽ thử làm và thông lại ở đây khi con có điều kiện ạDùng Dic.item(Mã hàng & Phòng)= thứ tự dòng kết quả, cuối cùng sort kết quả theo Phòng và Mã hàng
Bạn tự làm nha
Dạ vâng, con cảm Bác đã chỉ dẫn. Con sẽ thử làm và thông lại ở đây khi con có điều kiện ạ![]()
Bác ơi, bấm mặt cười nhé Bác:Dùng Dic.item(Mã hàng & Phòng)= thứ tự dòng kết quả, cuối cùng sort kết quả theo Phòng và Mã hàng
Bạn tự làm nha
Option Explicit
Sub Tap_Voi_Dictionary()
Dim Dic As New Scripting.Dictionary, sKey As String, iD As Long
Dim aDULIEU() As Variant, aSaoLaiMaHang() As Variant, aKETQUA() As Variant
Dim iMa As Long, jPhong As Long, r As Long, SoDong As Long, SoCot As Long, Wb As Workbook
Const O_Nhap_Lieu_Dau_Tien As String = "B4"
Const SoCotThemVao As Long = 15
Const CotDuLieuThem As Long = 8
Set Wb = ThisWorkbook
With Wb.Worksheets("Du lieu")
SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row
SoCot = .Cells(3, .Columns.Count).End(xlToLeft).Column
If SoDong < 4 Or SoCot < 3 + CotDuLieuThem Then
MsgBox "Khong co du lieu dau vao": Exit Sub
End If
SoDong = SoDong - 2: SoCot = SoCot - 1
aDULIEU = .Range("B3").Resize(SoDong, SoCot).Value2
SoCot = SoCot - (1 + CotDuLieuThem)
SoDong = SoDong - 1
ReDim aSaoLaiMaHang(1 To SoDong * SoCot, 1 To 2)
ReDim aKETQUA(1 To SoDong * SoCot, 1 To 2)
End With
With Wb.Worksheets("KQ")
SoCot = 2 + CotDuLieuThem
For jPhong = SoCot To UBound(aDULIEU, 2)
For iMa = 2 To UBound(aDULIEU, 1)
sKey = aDULIEU(iMa, 1) & "|" & aDULIEU(1, jPhong)
If Not Dic.Exists(sKey) And sKey <> Empty Then
r = r + 1
Dic.Add sKey, r
aSaoLaiMaHang(r, 1) = r
aSaoLaiMaHang(r, 2) = aDULIEU(iMa, 1)
aKETQUA(r, 1) = aDULIEU(1, jPhong)
aKETQUA(r, 2) = aDULIEU(iMa, jPhong)
Else
iD = Dic.Item(sKey)
aKETQUA(iD, 2) = aKETQUA(iD, 2) + aDULIEU(iMa, jPhong)
End If
Next iMa
Next jPhong
SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row
If SoDong > 3 Then
SoDong = SoDong - 3
.Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents
End If
With .Range(O_Nhap_Lieu_Dau_Tien)
.Resize(r, 2) = aSaoLaiMaHang
.Offset(, SoCotThemVao + 2).Resize(r, 2) = aKETQUA
End With
End With
End Sub
Bài nầy nên dùng công thức Excel
Thử code
Mã:Sub ABC() Dim aMa(), aPhong(), aDuLieu(), Res(), Res2() Dim eRow&, i&, k&, j&, sRow&, sCol&, sRowRes& With Sheets("Du lieu") eRow = .Range("B" & Rows.Count).End(xlUp).Row If eRow < 4 Then MsgBox "Khong co du lieu dau vao": Exit Sub aMa = .Range("B4:B" & eRow).Value aPhong = .Range("K3:O3").Value aDuLieu = .Range("K4:O" & eRow).Value End With sRow = UBound(aDuLieu): sCol = UBound(aDuLieu, 2) sRowRes = sRow * sCol ReDim Res(1 To sRowRes, 1 To 2) ReDim Res2(1 To sRowRes, 1 To 2) For j = 1 To sCol For i = 1 To sRow k = k + 1 Res(k, 1) = k Res(k, 2) = aMa(i, 1) Res2(k, 1) = aPhong(1, j) Res2(k, 2) = aDuLieu(i, j) Next i Next j With Sheets("KQ") eRow = .Range("B" & Rows.Count).End(xlUp).Row If eRow > 3 Then Range("B4:C" & eRow).ClearContents Range("S4:T" & eRow).ClearContents End If .Range("B4").Resize(sRowRes, 2) = Res .Range("S4").Resize(sRowRes, 2) = Res2 End With End Sub
If eRow > 3 Then
Range("B4:C" & eRow).ClearContents
Range("S4:T" & eRow).ClearContents
End If
Sort dữ liệu khi dữ liệu chưa xếp thứ tự, hoặc chỉ lấy những dòng có dữ liệuBác ơi, bấm mặt cười nhé Bác:
Mã:Option Explicit Sub Tap_Voi_Dictionary() Dim Dic As New Scripting.Dictionary, sKey As String, iD As Long Dim aDULIEU() As Variant, aSaoLaiMaHang() As Variant, aKETQUA() As Variant Dim iMa As Long, jPhong As Long, r As Long, SoDong As Long, SoCot As Long, Wb As Workbook Const O_Nhap_Lieu_Dau_Tien As String = "B4" Const SoCotThemVao As Long = 15 Const CotDuLieuThem As Long = 8 Set Wb = ThisWorkbook With Wb.Worksheets("Du lieu") SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row SoCot = .Cells(3, .Columns.Count).End(xlToLeft).Column If SoDong < 4 Or SoCot < 3 + CotDuLieuThem Then MsgBox "Khong co du lieu dau vao": Exit Sub End If SoDong = SoDong - 2: SoCot = SoCot - 1 aDULIEU = .Range("B3").Resize(SoDong, SoCot).Value2 SoCot = SoCot - (1 + CotDuLieuThem) SoDong = SoDong - 1 ReDim aSaoLaiMaHang(1 To SoDong * SoCot, 1 To 2) ReDim aKETQUA(1 To SoDong * SoCot, 1 To 2) End With With Wb.Worksheets("KQ") SoCot = 2 + CotDuLieuThem For jPhong = SoCot To UBound(aDULIEU, 2) For iMa = 2 To UBound(aDULIEU, 1) sKey = aDULIEU(iMa, 1) & "|" & aDULIEU(1, jPhong) If Not Dic.Exists(sKey) And sKey <> Empty Then r = r + 1 Dic.Add sKey, r aSaoLaiMaHang(r, 1) = r aSaoLaiMaHang(r, 2) = aDULIEU(iMa, 1) aKETQUA(r, 1) = aDULIEU(1, jPhong) aKETQUA(r, 2) = aDULIEU(iMa, jPhong) Else iD = Dic.Item(sKey) aKETQUA(iD, 2) = aKETQUA(iD, 2) + aDULIEU(iMa, jPhong) End If Next iMa Next jPhong SoDong = .Cells(.Rows.Count, "B").End(xlUp).Row If SoDong > 3 Then SoDong = SoDong - 3 .Range(O_Nhap_Lieu_Dau_Tien).Resize(SoDong, SoCotThemVao + 4).ClearContents End If With .Range(O_Nhap_Lieu_Dau_Tien) .Resize(r, 2) = aSaoLaiMaHang .Offset(, SoCotThemVao + 2).Resize(r, 2) = aKETQUA End With End With End Sub
Ủa hình như không cần sort 2 điều kiện nữa Bác ạ, hic Bác góp ý thêm cho con ạ.
Con cảm ơn Bác @HieuCD
Bài đã được tự động gộp:
Bác ơi, Bác quên 2 dấu "." ở đầu kìa, bạn ấy mà chuyển cái mặt cười sang sheet khác là 'xong phim'
Mã:If eRow > 3 Then Range("B4:C" & eRow).ClearContents Range("S4:T" & eRow).ClearContents End If
Con chào Bác,Sort dữ liệu khi dữ liệu chưa xếp thứ tự, hoặc chỉ lấy những dòng có dữ liệu