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




- Tham gia
- 8/12/19
- Bài viết
- 241
- Được thích
- 30
Bạn nói rõ mua hàng lần đầu điều kiện là gì,Mua hàng kế cuối điều kiện gì,Và mua hàng gần nhất điều kiện là gì.Kính gửi anh/chị,
E bị vướng khi lấy số lượng nhập lần đầu, kế cuối và gần nhất. E có để data và kết quả mong muốn theo file đính kèm ạ. Mong các anh/chị xem và giúp đỡ em ạ. E cảm ơn nhiều ạ.
Bạn nói rõ mua hàng lần đầu điều kiện là gì,Mua hàng kế cuối điều kiện gì,Và mua hàng gần nhất điều kiện là gì.
Dạ, e cảm ơn bác @VetMini ạ. Nhưng e có viết code theo cách 2 nhưng chưa ra ạ. Bác @VetMini có thể giúp e theo cách 2 được không ạ. E cảm ơn bác @VetMini ạCó ít nhất 3 cách làm (tức là hiện tại tôi biết 3, có thể có ngừoi biết thêm cách khác)
1. Cách truyền thống nhất:
- Sắp xếp bảng theo mặt hàng và ngày (giảm dần)
- Đọc bảng đã sắp xếp, dòng đầu tiên của mặt hàng là ngày gần nhất, dòng kế là ngày cận kế, dòng cuối là ngày đầu tiên (xa nhất).
2. Cách mà GPE "khoái" dùng, tức là dùng đít sần:
- Lập ra 2 mảng. Mảng A gồm 3 cột chứa ngày (3 ngày: gần nhất, cận kế, và xa nhất), và mảng B gồm bốn cột chứa số liệu (gần nhất, cận kế, đầu tiên, và tổng)
- Đọc bảng, dùng đít sần để ghi chỉ số tương ứng của mặt hàng trong hai mảng A, B. Đồng thời:
-- cộng tổng vào cột cuối của mảng B
-- dò ngày xem dòng hiện đang đọc thuộc về gần nhất, cận kế hay xa nhất, và cập nhật cột tương ứng trong bảng B
3. Cách mà GPE cũng tương đối "khoái", tức là dùng ADO để gom dữ liệu.
Cách này thì code căn bản ở đây có cả đống. Vấn đề là cái câu SQL hơi khó.
Thử CodeKính gửi anh/chị,
E bị vướng khi lấy số lượng nhập lần đầu, kế cuối và gần nhất. E có để data và kết quả mong muốn theo file đính kèm ạ. Mong các anh/chị xem và giúp đỡ em ạ. E cảm ơn nhiều ạ.
Sub ABC()
Dim sArr(), Res(), Ma$
Dim eR&, i&, k&, iD&, N&, sRow&, TongSo#
With Sheets("Sheet1")
eR = .Range("I" & Rows.Count).End(xlUp).Row 'Dong cuoi
If eR > 1 Then .Range("I2:N" & eR).Clear 'Xoa ket qua cu
eR = .Range("A" & Rows.Count).End(xlUp).Row 'Dong cuoi
If eR < 2 Then MsgBox ("Khong co du lieu"): Exit Sub
Res = .Range("A2:C" & eR).Value 'Du lieu goc
.Range("A2:C" & eR).Sort .[B2], 1, .[A2], , 1, Header:=xlNo ' Sort du lieu
sArr = .Range("A2:C" & eR + 1).Value 'Mang du lieu da Sort
.Range("A2:C" & eR).Value = Res 'Tra lai du lieu goc
.Range("D1").Formula = "=SUMPRODUCT(1/COUNTIF(B2:B" & eR & ",B2:B" & eR & "))" 'So ma hang
N = .Range("D1").Value * 4 'So dong ket qua
.Range("D1").ClearContents 'Xoa o tam
End With
ReDim Res(1 To N, 1 To 6)
sRow = UBound(sArr)
For i = 1 To sRow - 1
If Ma <> sArr(i, 2) Then 'Lan dau
iD = i
Ma = sArr(i, 2)
TongSo = 0
k = k + 1
Call GanKetQua(sArr, Res, k, TongSo, i, 3)
End If
If Ma <> sArr(i + 1, 2) Then
If i > iD + 1 Then 'Lan ke cuoi
k = k + 1
Call GanKetQua(sArr, Res, k, TongSo, i - 1, 4)
End If
If i > iD Then 'Lan gan nhat
k = k + 1
Call GanKetQua(sArr, Res, k, TongSo, i, 5)
End If
k = k + 1 'Dong tong
Res(k, 1) = sArr(i, 2)
Res(k, 6) = TongSo
End If
Next i
With Sheets("Sheet1")
.Range("I2").Resize(k, 6) = Res
.Range("I2").Resize(k, 6).Borders.LineStyle = 1
End With
End Sub
Private Sub GanKetQua(sArr, Res, k, TongSo, ByVal iR&, ByVal jC&)
Res(k, 1) = sArr(iR, 2)
Res(k, 2) = sArr(iR, 1)
Res(k, jC) = sArr(iR, 3)
Res(k, 6) = sArr(iR, 3)
TongSo = TongSo + sArr(iR, 3)
End Sub
Dạ, e cảm ơn Thầy @HieuCD nhiều lắm ạThử Code
Mã:Sub ABC() Dim sArr(), Res(), Ma$ Dim eR&, i&, k&, iD&, N&, sRow&, TongSo# With Sheets("Sheet1") eR = .Range("I" & Rows.Count).End(xlUp).Row 'Dong cuoi If eR > 1 Then .Range("I2:N" & eR).Clear 'Xoa ket qua cu eR = .Range("A" & Rows.Count).End(xlUp).Row 'Dong cuoi If eR < 2 Then MsgBox ("Khong co du lieu"): Exit Sub Res = .Range("A2:C" & eR).Value 'Du lieu goc .Range("A2:C" & eR).Sort .[B2], 1, .[A2], , 1, Header:=xlNo ' Sort du lieu sArr = .Range("A2:C" & eR + 1).Value 'Mang du lieu da Sort .Range("A2:C" & eR).Value = Res 'Tra lai du lieu goc .Range("D1").Formula = "=SUMPRODUCT(1/COUNTIF(B2:B" & eR & ",B2:B" & eR & "))" 'So ma hang N = .Range("D1").Value * 4 'So dong ket qua .Range("D1").ClearContents 'Xoa o tam End With ReDim Res(1 To N, 1 To 6) sRow = UBound(sArr) For i = 1 To sRow - 1 If Ma <> sArr(i, 2) Then 'Lan dau iD = i Ma = sArr(i, 2) TongSo = 0 k = k + 1 Call GanKetQua(sArr, Res, k, TongSo, i, 3) End If If Ma <> sArr(i + 1, 2) Then If i > iD + 1 Then 'Lan ke cuoi k = k + 1 Call GanKetQua(sArr, Res, k, TongSo, i - 1, 4) End If If i > iD Then 'Lan gan nhat k = k + 1 Call GanKetQua(sArr, Res, k, TongSo, i, 5) End If k = k + 1 'Dong tong Res(k, 1) = sArr(i, 2) Res(k, 6) = TongSo End If Next i With Sheets("Sheet1") .Range("I2").Resize(k, 6) = Res .Range("I2").Resize(k, 6).Borders.LineStyle = 1 End With End Sub Private Sub GanKetQua(sArr, Res, k, TongSo, ByVal iR&, ByVal jC&) Res(k, 1) = sArr(iR, 2) Res(k, 2) = sArr(iR, 1) Res(k, jC) = sArr(iR, 3) Res(k, 6) = sArr(iR, 3) TongSo = TongSo + sArr(iR, 3) End Sub
Đúng là 100 người thì 101 gu. Tôi thì khoái món "đít thon". Cực chẳng đã mới chấp nhận "đít to". Còn "đít sần" nhiều mụn thì nhường bác VetMini.2. Cách mà GPE "khoái" dùng, tức là dùng đít sần:
...
- Đọc bảng, dùng đít sần để
Không phải bác ơi. Tôi vốn thích đít son.Đúng là 100 người thì 101 gu. Tôi thì khoái món "đít thon". Cực chẳng đã mới chấp nhận "đít to". Còn "đít sần" nhiều mụn thì nhường bác VetMini.
Thế thì bác thuộc giới cao cấp, sành ăn rồi.Không phải bác ơi. Tôi vốn thích đít son.
Dạ. E cảm ơn bác @VetMini nhiều ạ.Hôm nay thử nói về thuật toán dùng đít sần.
Dic chỉ là một công cụ giúp truy vấn dữ liệu kiểu key-item. Phần lớn bài trên diễn đàn này sử dụng Dic vì muốn lợi dụng tính chất duy nhất của key để giải đáp bài toán lọc duy nhất.
Và bài này, nếu sử dụng Dic cũng chẳng qua cái thông lệ đó.
Đã là thông lệ thì nó rất nhàm chán. Dic chỉ dùng để lọc mã duy nhất, với mã là key và item là chỉ số của mảng kết quả. Code này ở diễn đàn có đến hàng trăm.
Rốt cuộc lại thì con toán khó khăn quy về cách góp dọn dữ liệu cho mảng kết quả. Bài toán này là tìm LỚN NHẤT, LỚN NHÌ, và NHẤT.
Bài toán tìm lớn/nhỏ nhất là bài căn bản của lập trình, thường được nằm trong bài tập của chương dạy về mảng. Bài này quá dễ, không cần nói thêm.
Bài toán tìm n số lớn nhất là bài hơi cần động não một chút. Và nó là bài tôi muốn nhắc đến ở đây.
Thuật toán tìm n số lớn nhất trong một mảng số:
1. lập một mảng n phần tử
2. với mỗi số, so sánh nó với mảng n và chèn vào đúng chỗ.
Thuật toán chèn, (mảng n chứa các số đã sắp xếp từ lớn xuống nhỏ):
1. vòng lặp duyệt mảng n
2. so sánh số với từng trị trong mảng:
2.1 nếu nhỏ hơn, qua phần tử kế
2.2 nếu bằng, thoát vòng lặp
2.3 nếu lớn hơn, thay trị này và đẩy các phần tử xuống
(các xảo thuật khác nhau nằm ở thuật toán "đẩy phần tử" này)
Code minh hoạ:
For i = LBound(mangSo) To UBound(mangSo)
so = mangSo(i)
For i2 = lbMangSapXep To ubMangSapXep
If so = mangSX(i2) Then ' số này có rồi, không cần nữa
Exit For
ElseIf so > mangSX(i2) Then ' chèn vào, và đẩy xuống
tmp = mangSX(i2)
mangSX(i2) = so
so = tmp
End If
Next i2
Next i
Bài này chỉ tìm 2 số lớn nhất, và 1 số nhỏ nhất. Thuật toán phức tạp hơn nhiều.