Khuya rồi, chúc ngủ ngonDạ vầng Bác ơi, con cũng thấy cần thêm mấy chỗ đó ạ.
Lúc nào Bác có thời gian Bác xem giúp con ạ, muộn rồi Bác giữ gìn sức khỏe ạ.
Con chào Bác.
Khuya rồi, chúc ngủ ngonDạ vầng Bác ơi, con cũng thấy cần thêm mấy chỗ đó ạ.
Lúc nào Bác có thời gian Bác xem giúp con ạ, muộn rồi Bác giữ gìn sức khỏe ạ.
Con chào Bác.
Dạ vầng, Bác cũng nghỉ đi ạ.Khuya rồi, chúc ngủ ngon
Lồng 2 cái vòng lặp for vào nhau có nhanh hơn và gọn hơn anh à.Có cách nào bỏ 2 biến "m" và "n" không?![]()
Bác có thể hướng dẫn em cách làm file này bằng query được không ạDùng Power query
Có khi nào muốn chọn Profit =0 hay <0 không? Hay luôn chọn >0.Dạ vầng Bác ơi, con cũng thấy cần thêm mấy chỗ đó ạ.
Lúc nào Bác có thời gian Bác xem giúp con ạ, muộn rồi Bác giữ gìn sức khỏe ạ.
Con chào Bác.
Ùi, con chào Thầy ạ.Có khi nào muốn chọn Profit =0 hay <0 không? Hay luôn chọn >0.
Xử lý các điều kiện "<", "<=", "=", ">=", ">" không phải chuyện dễ.Ùi, con chào Thầy ạ.
Con cảm ơn Thầy đã quan tâm đến vấn đề của con ạ.
Dạ điều kiện cột này có thể lựa chọn đầy đủ các điều kiện so sánh: (>=<) Thầy ạ.
Dạ vầng Thầy ạ, vậy có thể thiết kế thêm một ô nào nữa để lựa chọn các điều kiện "<", "<=", "=", ">=", ">" này được không ạ Thầy?Xử lý các điều kiện "<", "<=", "=", ">=", ">" không phải chuyện dễ.
Híc!
Bạn làm theo video nàyBác có thể hướng dẫn em cách làm file này bằng query được không ạ
Bạn thử code này xem đúng yêu cầu chưa:Dạ vầng Thầy ạ, vậy có thể thiết kế thêm một ô nào nữa để lựa chọn các điều kiện "<", "<=", "=", ">=", ">" này được không ạ Thầy?
Ví dụ trong tập tin đính kèm con đã tách điều kiện trong ô E2 thành 2 ô E2 và F2 Thầy ạ.
Option Explicit
Sub NTKTNN()
Dim sArr(), dArr(), CusName, ProCat, fDate As Long, tDate As Long, Profit As String, Bo As Boolean
Dim i As Long, J As Long, K As Long
Application.ScreenUpdating = False
With Sheets("Filter")
CusName = Split(.Range("B1").Value, ";")
ProCat = Split(.Range("B2").Value, ";")
fDate = .Range("D1").Value
tDate = .Range("D2").Value
Profit = .Range("E2").Value
End With
With Sheets("Orders")
sArr = .Range("A1:J" & .Cells(.Rows.Count, "A").End(xlUp).Rows).Value
ReDim dArr(1 To UBound(sArr), 1 To UBound(sArr, 2))
For i = 1 To UBound(sArr, 1)
If UBound(CusName) >= 0 Then
For J = 0 To UBound(CusName)
If InStr(1, sArr(i, 8), CusName(J), 1) > 0 Then Bo = True: Exit For
Next
If Bo = False Then GoTo Next_I
Bo = False
End If
If UBound(ProCat) >= 0 Then
For J = 0 To UBound(ProCat)
If InStr(1, sArr(i, 10), ProCat(J), 1) > 0 Then Bo = True: Exit For
Next
If Bo = False Then GoTo Next_I
Bo = False
End If
If fDate > 0 And tDate > 0 Then
If sArr(i, 2) >= fDate And sArr(i, 2) <= tDate Then Bo = True
If Bo = False Then GoTo Next_I
Bo = False
End If
If Profit <> "" Then
If Evaluate(sArr(i, 6) & Profit) Then Bo = True
If Bo = False Then GoTo Next_I
End If
K = K + 1
For J = 1 To UBound(sArr, 2)
dArr(K, J) = sArr(i, J)
Next
Next_I:
Next
End With
Sheets("Filter").Range("A4:J10000").ClearContents
Sheets("Filter").Range("A4").Resize(UBound(sArr), UBound(sArr, 2)) = dArr
Application.ScreenUpdating = True
End Sub
Mỗi vòng lặp lại phải tính lại UBound(CusName)If UBound(CusName) >= 0 Then
Dùng For each thì không cần kiểm tra Ubound.For J = 0 To UBound(CusName)
Góp ý rất hay bác ạ, đúng là for each thì không cần phải kiểm tra ubound. Nhưng nếu không kiểm tra vậy thì một số trường hợp không có điều kiện (người để trống) code vẫn duyệt qua nó (em đang ví dụ với cusname), như vậy nó sẽ tính cái boolean là false và next sang i khác ạMỗi vòng lặp lại phải tính lại UBound(CusName)
Dùng For each thì không cần kiểm tra Ubound.
Thì mình kiểm tra và oánh dấu ngay từ đầu ấy.Góp ý rất hay bác ạ, đúng là for each thì không cần phải kiểm tra ubound. Nhưng nếu không kiểm tra vậy thì một số trường hợp không có điều kiện (người để trống) code vẫn duyệt qua nó (em đang ví dụ với cusname), như vậy nó sẽ tính cái boolean là false và next sang i khác ạ
Sao em thấy hình như bớt được khúc if nhưng phải tạo nhiều biến hơn phải không bác?Thì mình kiểm tra và oánh dấu ngay từ đầu ấy.
Dim flagCusName as boolean
If len(.Range("B1").Value) > 0 then
flagCusName = True
CusName = Split(.Range("B1").Value, ";")
Else
flagCusName = False
End if
'...
For i = 1 To UBound(sArr, 1)
If flagCusName = True then
For Each cuName in CusName
'...
Next
'...
Else
'...
End If
Ợ. Code xem ở giải thuật chứ đâu đi đếm biến với đếm dòng. @@Sao em thấy hình như bớt được khúc if nhưng phải tạo nhiều biến hơn phải không bác?![]()
Thì em cũng biết code ai đâu đi đếm biến và dòngỢ. Code xem ở giải thuật chứ đâu đi đếm biến với đếm dòng. @@
Dùng ADO để Select bảng ban đầu. Với điều kiện ghép như [Customer name] dạng "a;b;c" ta dùng Replace và nối chuỗi để thay thế thành ([Customer name] like "%a%" OR [Customer name] like "%b%" OR [Customer name] like "%c%") rồi đưa vào điều kiện where thôi. Với điều kiện > hay >= dùng nối chuỗi bình thường.Dạ vầng Thầy ạ, vậy có thể thiết kế thêm một ô nào nữa để lựa chọn các điều kiện "<", "<=", "=", ">=", ">" này được không ạ Thầy?
Ví dụ trong tập tin đính kèm con đã tách điều kiện trong ô E2 thành 2 ô E2 và F2 Thầy ạ.
Mình thường viết kiểu nầyBạn thử code này xem đúng yêu cầu chưa:
Mã:Option Explicit Sub NTKTNN() Dim sArr(), dArr(), CusName, ProCat, fDate As Long, tDate As Long, Profit As String, Bo As Boolean Dim i As Long, J As Long, K As Long Application.ScreenUpdating = False With Sheets("Filter") CusName = Split(.Range("B1").Value, ";") ProCat = Split(.Range("B2").Value, ";") fDate = .Range("D1").Value tDate = .Range("D2").Value Profit = .Range("E2").Value End With With Sheets("Orders") sArr = .Range("A1:J" & .Cells(.Rows.Count, "A").End(xlUp).Rows).Value ReDim dArr(1 To UBound(sArr), 1 To UBound(sArr, 2)) For i = 1 To UBound(sArr, 1) If UBound(CusName) >= 0 Then For J = 0 To UBound(CusName) If InStr(1, sArr(i, 8), CusName(J), 1) > 0 Then Bo = True: Exit For Next If Bo = False Then GoTo Next_I Bo = False End If If UBound(ProCat) >= 0 Then For J = 0 To UBound(ProCat) If InStr(1, sArr(i, 10), ProCat(J), 1) > 0 Then Bo = True: Exit For Next If Bo = False Then GoTo Next_I Bo = False End If If fDate > 0 And tDate > 0 Then If sArr(i, 2) >= fDate And sArr(i, 2) <= tDate Then Bo = True If Bo = False Then GoTo Next_I Bo = False End If If Profit <> "" Then If Evaluate(sArr(i, 6) & Profit) Then Bo = True If Bo = False Then GoTo Next_I End If K = K + 1 For J = 1 To UBound(sArr, 2) dArr(K, J) = sArr(i, J) Next Next_I: Next End With Sheets("Filter").Range("A4:J10000").ClearContents Sheets("Filter").Range("A4").Resize(UBound(sArr), UBound(sArr, 2)) = dArr Application.ScreenUpdating = True End Sub
...
With Sheets("Filter")
CusName = Split(";" & .Range("B1").Value, ";")
...
For i = 1 To UBound(sArr, 1)
For J = 1 To UBound(CusName)
If InStr(1, sArr(i, 8), CusName(J), 1) = 0 Then GoTo Next_I
Next
...
Ủa bác Hiếu, ubound của mảng split gốc 0 mà bác, với lại mảng cusname có nhiều phần tử, nếu duyệt phần tử đầu không có thì duyệt tiếp chứ theo em thấy code đó nếu gặp phần tử đầu tiên không có là next luôn rồi bác?For J = 1 To UBound(CusName) If InStr(1, sArr(i, 8), CusName(J), 1) = 0 Then GoTo Next_I
Ủa bác Hiếu, ubound của mảng split gốc 0 mà bác, với lại mảng cusname có nhiều phần tử, nếu duyệt phần tử đầu không có thì duyệt tiếp chứ theo em thấy code đó nếu gặp phần tử đầu tiên không có là next luôn rồi bác?
CusName = Split(";" & .Range("B1").Value, ";")
...
With Sheets("Filter")
CusName = Split(";" & .Range("B1").Value, ";")
...
For i = 1 To UBound(sArr, 1)
For J = 1 To UBound(CusName)
If InStr(1, sArr(i, 8), CusName(J), 1) > 0 Then exit for
Next
If J = 1 + UBound(CusName) Then GoTo Next_I
...