thang.phduy2
Thành viên mới

- Tham gia
- 20/1/21
- Bài viết
- 12
- Được thích
- 0
Tạo bảng cáo cáo giống pivot, chứ k phải insert pivot table.Sao bạn không Ghi lại Code của Pivot luôn
Theo ví dụ kết quảChào anh chị.
Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.
Cảm ơn anh chị.
Sub ABC()
Dim sArr(), Res() As String, ResQt(), Dic As Object
Dim i&, k&, iR&, sRow&, iKey$
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Sheet1")
sArr = .Range("A2", .Range("E" & Rows.Count).End(xlUp)).Value
End With
sRow = UBound(sArr)
ReDim Res(1 To sRow, 1 To 4)
ReDim ResQt(1 To sRow, 1 To 1)
For i = 1 To sRow
If sArr(i, 3) = 1 Then
iKey = sArr(i, 1) & "|" & sArr(i, 4)
If Not Dic.Exists(iKey) Then
k = k + 1
Dic.Add iKey, k
Res(k, 1) = sArr(i, 4)
Res(k, 2) = sArr(i, 5)
Res(k, 4) = sArr(i, 1)
End If
iR = Dic.Item(iKey)
ResQt(iR, 1) = ResQt(iR, 1) + 1
End If
Next i
With Sheets("Sheet3")
i = .Range("B" & Rows.Count).End(xlUp).Row
If i > 1 Then .Range("B2:E" & i).ClearContents
.Range("B2").Resize(k, 4) = Res
.Range("D2").Resize(k, 1) = ResQt
.Range("B2").Resize(k, 4).Sort .[E2], 1, .[B2], , 1
End With
End Sub
Chia theo cột E ở E3 và E11.Mình thấy phần Qty bạn điền tay đâu có đúng đâu nhỉ? Nó bằng 9 chứ sao bằng 7 được vậyView attachment 254270
Cảm ơn anh. Code chạy ngon lành.Theo ví dụ kết quả
Mã:Sub ABC() Dim sArr(), Res() As String, ResQt(), Dic As Object Dim i&, k&, iR&, sRow&, iKey$ Set Dic = CreateObject("Scripting.Dictionary") With Sheets("Sheet1") sArr = .Range("A2", .Range("E" & Rows.Count).End(xlUp)).Value End With sRow = UBound(sArr) ReDim Res(1 To sRow, 1 To 4) ReDim ResQt(1 To sRow, 1 To 1) For i = 1 To sRow If sArr(i, 3) = 1 Then iKey = sArr(i, 1) & "|" & sArr(i, 4) If Not Dic.Exists(iKey) Then k = k + 1 Dic.Add iKey, k Res(k, 1) = sArr(i, 4) Res(k, 2) = sArr(i, 5) Res(k, 4) = sArr(i, 1) End If iR = Dic.Item(iKey) ResQt(iR, 1) = ResQt(iR, 1) + 1 End If Next i With Sheets("Sheet3") i = .Range("B" & Rows.Count).End(xlUp).Row If i > 1 Then .Range("B2:E" & i).ClearContents .Range("B2").Resize(k, 4) = Res .Range("D2").Resize(k, 1) = ResQt .Range("B2").Resize(k, 4).Sort .[E2], 1, .[B2], , 1 End With End Sub
Thử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:Chào anh chị.
Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.
Cảm ơn anh chị.
Option Explicit
Private Function KeyExists(aExists, sKey, j, k) As Boolean
For k = 1 To j
If aExists(k) = sKey Then
KeyExists = True
Exit For
End If
Next k
End Function
Sub Tham_Khao_ForNext()
Dim aExists, sKey As String, sArr(), Result()
Dim r As Long, i As Long, j As Long, k As Long
Dim shData As Worksheet, shKQ As Worksheet
Set shData = ThisWorkbook.Worksheets("Sheet1")
Set shKQ = ThisWorkbook.Worksheets("Sheet3")
r = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
If r < 2 Then Exit Sub
shKQ.Range("A2").Resize(10000, 5).ClearContents
sArr = shData.Range("A1").Resize(r, 5).Value2
ReDim Result(1 To r, 1 To 5): ReDim aExists(1 To r)
For i = 1 To r
If sArr(i, 3) = 1 Then
sKey = sArr(i, 1) & "|" & sArr(i, 4)
If Not KeyExists(aExists, sKey, j, k) Then
aExists(k) = sKey
j = j + 1
Result(j, 1) = j
Result(j, 2) = sArr(i, 4)
Result(j, 3) = sArr(i, 5)
Result(j, 5) = sArr(i, 1)
End If
Result(k, 4) = Result(k, 4) + 1
End If
Next i
shKQ.Range("A2").Resize(j, 5) = Result
End Sub
Thêm cho bạn 1 cách dùng ADO:Chào anh chị.
Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.
Cảm ơn anh chị.
Sub GopDL()
With CreateObject("ADODB.Recordset")
.Open "Select [article_no],[Size],sum(Qty),[Carton] from [Sheet1$] where [Carton] is not null Group By [article_no],[Size],[Carton] order by [Carton]", "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
Sheet2.Range("G2").CopyFromRecordset .DataSource
End With
End Sub
Ta có thể thay thế đoạn truy vấn trên như sau:Thêm cho bạn 1 cách dùng ADO:
Mã:Sub GopDL() With CreateObject("ADODB.Recordset") .Open "Select [article_no],[Size],sum(Qty),[Carton] from [Sheet1$] where [Carton] is not null Group By [article_no],[Size],[Carton] order by [Carton]", "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0" Sheet2.Range("G2").CopyFromRecordset .DataSource End With End Sub
Select [article_no],[Size],sum(Qty),[Carton]
From [Sheet1$]
Where [Carton] is not null
Group By [Carton],[article_no],[Size]
Ủa, nó khác gì vậy anh Hai Lúa, Ot thấy không sắp xếp theo [Carton] nữa ạTa có thể thay thế đoạn truy vấn trên như sau:
Mã:Select [article_no],[Size],sum(Qty),[Carton] From [Sheet1$] Where [Carton] is not null Group By [Carton],[article_no],[Size]
Khác chứ em, nếu ta ưu tiên cái nào Group trước thì nó sẽ sắp xếp trước theo thứ tự.Ủa, nó khác gì vậy anh Hai Lúa, Ot thấy không sắp xếp theo [Carton] nữa ạ
À ra vậy OT biết thêm chức năng Group By ạ,, cảm ơn Anh ạ.Khác chứ em, nếu ta ưu tiên cái nào Group trước thì nó sẽ sắp xếp trước theo thứ tự.
Dùng Sub tốc độ nhanh hơn FunctionThử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:
Mã:Option Explicit Private Function KeyExists(aExists, sKey, j, k) As Boolean For k = 1 To j If aExists(k) = sKey Then KeyExists = True Exit For End If Next k End Function Sub Tham_Khao_ForNext() Dim aExists, sKey As String, sArr(), Result() Dim r As Long, i As Long, j As Long, k As Long Dim shData As Worksheet, shKQ As Worksheet Set shData = ThisWorkbook.Worksheets("Sheet1") Set shKQ = ThisWorkbook.Worksheets("Sheet3") r = shData.Range("A" & shData.Rows.Count).End(xlUp).Row If r < 2 Then Exit Sub shKQ.Range("A2").Resize(10000, 5).ClearContents sArr = shData.Range("A1").Resize(r, 5).Value2 ReDim Result(1 To r, 1 To 5): ReDim aExists(1 To r) For i = 1 To r If sArr(i, 3) = 1 Then sKey = sArr(i, 1) & "|" & sArr(i, 4) If Not KeyExists(aExists, sKey, j, k) Then aExists(k) = sKey j = j + 1 Result(j, 1) = j Result(j, 2) = sArr(i, 4) Result(j, 3) = sArr(i, 5) Result(j, 5) = sArr(i, 1) End If Result(k, 4) = Result(k, 4) + 1 End If Next i shKQ.Range("A2").Resize(j, 5) = Result End Sub
Dạ, vâng Bác vậy con sửa luôn trong bộ sưu tập của con ạ, con cảm ơn Bác ạDùng Sub tốc độ nhanh hơn Function
Viết ào ào thế mà có biết nguyên lý hoạt động của Function KeyExists hay không vậy nhóc? Tại sao k cứ thế mà tăng 1?Thử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:
Mã:Option Explicit Private Function KeyExists(aExists, sKey, j, k) As Boolean For k = 1 To j If aExists(k) = sKey Then KeyExists = True Exit For End If Next k End Function
Chú vùi dập con cũng phải vừa phải thôi chúViết ào ào thế mà có biết nguyên lý hoạt động của Function KeyExists hay không vậy nhóc? Tại sao k cứ thế mà tăng 1?
Copy về chạy thì ra kết quả. Hiểu sai bét hoặc giải thích sai nguyên lýChú vùi dập con cũng phải vừa phải thôi chú
Không hiểu mà ra kết quả được, con làm gì mà may thế, k +1 là theo j+1 phải không chú Mỹ (hehe con cũng không chắc)
Vậy rút cục là sao chú Mỹ , con bổ sung thêm một cách gải thích nữa là k tăng là vì số key tăng ạ , key bao nhiêu thì k bấy nhiêu ạ.Copy về chạy thì ra kết quả. Hiểu sai bét hoặc giải thích sai nguyên lý
Quay về nguyên lý của For Next: Khi thoát ra thì counter bằng bi nhiuVậy rút cục là sao chú Mỹ , con bổ sung thêm một cách gải thích nữa là k tăng là vì số key tăng ạ , key bao nhiêu thì k bấy nhiêu ạ.
Khi thoát rồi thì có thể là nó = 0 ạQuay về nguyên lý của For Next: Khi thoát ra thì counter bằng bi nhiu
Thế thì vứt.Khi thoát rồi thì có thể là nó = 0 ạ![]()
EndRow = 1000
For i = 1 to EndRow
k = i
Next
Msgbox i & "-" & k
À!.. đa tạ Chú Mỹ nhiều nhé.Thế thì vứt.
Mã:EndRow = 1000 For i = 1 to EndRow k = i Next Msgbox i & k
Thế khiÀ!.. đa tạ Chú Mỹ nhiều nhé.
Code chạy đúng do may mắn đầu năm, bỏ mảng aExists code sẽ tường minh và chuẩn hơnThử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:
Mã:Option Explicit Private Function KeyExists(aExists, sKey, j, k) As Boolean For k = 1 To j If aExists(k) = sKey Then KeyExists = True Exit For End If Next k End Function Sub Tham_Khao_ForNext() Dim aExists, sKey As String, sArr(), Result() Dim r As Long, i As Long, j As Long, k As Long Dim shData As Worksheet, shKQ As Worksheet Set shData = ThisWorkbook.Worksheets("Sheet1") Set shKQ = ThisWorkbook.Worksheets("Sheet3") r = shData.Range("A" & shData.Rows.Count).End(xlUp).Row If r < 2 Then Exit Sub shKQ.Range("A2").Resize(10000, 5).ClearContents sArr = shData.Range("A1").Resize(r, 5).Value2 ReDim Result(1 To r, 1 To 5): ReDim aExists(1 To r) For i = 1 To r If sArr(i, 3) = 1 Then sKey = sArr(i, 1) & "|" & sArr(i, 4) If Not KeyExists(aExists, sKey, j, k) Then aExists(k) = sKey j = j + 1 Result(j, 1) = j Result(j, 2) = sArr(i, 4) Result(j, 3) = sArr(i, 5) Result(j, 5) = sArr(i, 1) End If Result(k, 4) = Result(k, 4) + 1 End If Next i shKQ.Range("A2").Resize(j, 5) = Result End Sub
Định hỏi anh đây: Tại sao lại có điều kiện If sArr(i, 3) = 1 Then?Code chạy đúng do may mắn đầu năm, bỏ mảng aExists code sẽ tường minh và chuẩn hơn
Chú hỏi hết gì Chú hỏi hết luôn đi ạ, con viết nhiều rồi lại lên top1 đến lúc đó đâm lao rồi con lại cố theo lao bỏ cả chồng con công việc để đua tốp thì chết.Thế khi
For i = 1 to EndRow Step 2
Thì sao?
Dạ , Bác vậy ạ. Bác nói vậy chắc là đúng là con gặp may rồi.. con cảm ơn Bác đã gởi con lời tốt đẹp gián tiếp ạCode chạy đúng do may mắn đầu năm, bỏ mảng aExists code sẽ tường minh và chuẩn hơn
Chú hỏi Bác ấy thật nhiều vào để con xem 'song hùng gặp nhau' tôm tép có hưởng lây gì không?Định hỏi anh đây: Tại sao lại có điều kiện If sArr(i, 3) = 1 Then?
Phải suy luận ra chứ có 1 dòng code mà phải test trên máy à?Chú hỏi hết gì Chú hỏi hết luôn đi ạ, con viết nhiều rồi lại lên top1 đến lúc đó đâm lao rồi con lại cố theo lao bỏ cả chồng con công việc để đua tốp thì chết.
Sau khi đọc hết khuya về nếu ngồi máy con ngẫm rồi test một thể giờ con đang làm nên chưa test được chỉ dám đoán trong khả năng kiến thức ít ỏi của mình ạ.
Con xin phép tối mà cũng có thể là sau tối ... sau nữa con sẽ trả lời và tại bài viết này ạ (sửa bài ạ) ... cả ngày hôm nay đi làm mà cứ code với két xong cứ nhe răng ra cười Sếp mấy lần qua ra nhìn con rồi.Phải suy luận ra chứ có 1 dòng code mà phải test trên máy à?
Hỏi thêm đây (ôn bài cũ): Tại sao k tăng ở đâu đâu bên trời Function, k cũng không phải biến public, mà đem về sub chính vẫn còn nguyên giá trị đã tăng?
Sheet1 cột C có công thức: =IF(OR($B2>0,LEN($D2)=6),1,"")Định hỏi anh đây: Tại sao lại có điều kiện If sArr(i, 3) = 1 Then?
Theo tôi thấy thì đây là 1 kiểu nhập liệu tự động chứ không phải kiểu ràng buộc điều kiện: hoặc là điền barcode, hoặc là điền mã thì tự điền 1, ít có trường hợp mã dài ngắn khác nhau và chả lẽ mã dài hơn hay ngắn hơn thì bỏ thùng trống không.Sheet1 cột C có công thức: =IF(OR($B2>0,LEN($D2)=6),1,"")
Có khả năng cột C có giá trị rổng và mình muốn loại dòng nầy
Dạ Chú Mỹ, một thói quen khó chữa từ trước đến giờ khiến cho con không thể tiến bộ được là chỉ khi nào code chạy bị lỗi hoặc kết quả bị sai thì con mới tìm hiểu kỹ nguyên nhân hoặc là tìm trợ giúp nếu không xử lý được..Theo tôi thấy thì đây là 1 kiểu nhập liệu tự động chứ không phải kiểu ràng buộc điều kiện: hoặc là điền barcode, hoặc là điền mã thì tự điền 1, ít có trường hợp mã dài ngắn khác nhau và chả lẽ mã dài hơn hay ngắn hơn thì bỏ thùng trống không.
Tuy nhiên ý tôi hỏi là để cho thấy cái sự "bon chen" của cô nàng @Hoàng Nhật Phương mang tính chất sao chép không cần hiểu, miễn chạy ra kết quả giống là được. Giả sử code gốc sai thì việc sao chép sai cũng không biết.
Muốn tiến bộ thì suy nghĩ trả lời câu hỏi bài 23 và 27:Dạ Chú Mỹ, một thói quen khó chữa từ trước đến giờ khiến cho con không thể tiến bộ được
Con giải thích như sau ạ:Muốn tiến bộ thì suy nghĩ trả lời câu hỏi bài 23 và 27:
- Nếu for i = 1 (hoặc =m) to 10.000 step 2, (hoặc step n thì khi ra khỏi vòng lặp i bằng bao nhiêu? Cho công thức tổng quát
- Tại sao k tăng ở đâu đâu bên trời Function, k cũng không phải biến public, mà đem về sub chính vẫn còn nguyên giá trị đã tăng?
Function KeyExists(Result, sKey, j, k) As Boolean
For k = 1 To j
'...
Next k
Câu 1 đọc sai câu hỏi (for i = m to 1000 step n cơ mà?) câu 2 sai câu trả lờiCon giải thích như sau ạ:
- Với vòng lặp step:
Khi for i = 1 to 10.000 step 2 thì i = 10.000-1=9.999
Khi for i = 1 to m step n thì i = (m-n)+1, n càng tăng thì i càng giảm, m = i chỉ khi nào n=1
- Với k
k xuất phát là 1 khi j=0 k vẫn sẽ là 1.Mã:Function KeyExists(Result, sKey, j, k) As Boolean For k = 1 To j '... Next k
nếu j > 0 thì k sẽ tăng thêm 1 cứ như vậy sau mỗi lần kết thúc vằng lặp thì biến k luôn + (do For..next)
k mang về sub chính vẫn còn nguyên là do là đúng rồi (do truyền k)
ủa câu 1 có gì khác à Chú Mỹ, chờ con test thử xem khác gì ạ.Câu 1 đọc sai câu hỏi (for i = m to 1000 step n cơ mà?) câu 2 sai câu trả lời
Trả lời câu 2: Do function nhận tham số ByRef của k truyền vào, nên giá trị k của sub chính thay đổi do Function.
Không có "vòng lặp step".Với vòng lặp step:
Sub vidu()
Const startCount = 20
Const stp = 4 ' 3 truong hop: stp <0, =0, >0 '
Const maxCount = 1000
Const oanTaVan = 12
Dim i As Long
For i = startCount To maxCount Step stp
'i = i + oanTaVan ' them truong hop nay nua.
Next i
MsgBox i
End Sub
Không có "vòng lặp step".
View attachment 254330
Không đúng.
Thử như vậy xem:
PHP:Sub vidu() Const startCount = 20 Const stp = 4 ' 3 truong hop: stp <0, =0, >0 ' Const maxCount = 1000 Const oanTaVan = 12 Dim i As Long For i = startCount To maxCount Step stp 'i = i + oanTaVan ' them truong hop nay nua. Next i MsgBox i End Sub
---
Diễn biến: Bé >> Nhóc >> Cô nàng >> "chưa biết"
Kiếm được 'học trò cưng' rồi hem biết có mật ong rừng hông.![]()
Cảm ơn Bạn đã chỉ dẫn OT vừa kiểm tra 'For i = 10000 To EndRow Step 2', i= 1000 -1 đúng là sai thật , đúng là 10000.Không có "vòng lặp step".
View attachment 254330
Không đúng.
Thử như vậy xem:
PHP:Sub vidu() Const startCount = 20 Const stp = 4 ' 3 truong hop: stp <0, =0, >0 ' Const maxCount = 1000 Const oanTaVan = 12 Dim i As Long For i = startCount To maxCount Step stp 'i = i + oanTaVan ' them truong hop nay nua. Next i MsgBox i End Sub
---
Diễn biến: Bé >> Nhóc >> Cô nàng >> "chưa biết"
Kiếm được 'học trò cưng' rồi hem biết có mật ong rừng hông.![]()
Bạn hiểu lầm rồi. Phần đó tách riêng bởi dấu gạch gạch ---. Không nói tới bạn gì cả.Phần diễn biến của Bạn, OT hiểu bạn đang muốn nói gì
Em chào bác ạ!Câu 1 đọc sai câu hỏi (for i = m to 1000 step n cơ mà?) câu 2 sai câu trả lời
Trả lời câu 2: Do function nhận tham số ByRef của k truyền vào, nên giá trị k của sub chính thay đổi do Function.
Bạn hiểu lầm rồi. Phần đó tách riêng bởi dấu gạch gạch ---. Không nói tới bạn gì cả.
Sub vidu()
Dim startCount As Long, stp As Long
Dim i As Long, r As Long, iCount As Long, x As Long
Const maxCount As Long = 5
Const minStp As Long = 1 ' Khi de gia tri <0 (hoac=0) vong lap i khong thoat
Const t As Long = 7
r = 1
Range("A1").Resize(10000, 5).ClearContents
Cells(r, 1) = "startCount"
Cells(r, 2) = "stp"
Cells(r, 3) = "iCount"
Cells(r, 4) = "i"
Cells(r, 5) = "x"
For startCount = 1 To maxCount
For stp = minStp To maxCount
r = r + 1
Cells(r, 1) = startCount
Cells(r, 2) = stp
For i = startCount To maxCount Step stp
iCount = i
x = iCount + t
Next i
Cells(r, 3) = iCount
Cells(r, 4) = i
Cells(r, 5) = x
Next stp
Next startCount
End Sub
Làm gì mà loằng ngoằng thế.thử làm
Ủa có mà Bạn, OT có ghi chú khi thử các trị âm hoặc = 0 thì vòng lặp i không có điểm kết thúc ạ.Làm gì mà loằng ngoằng thế.
Chỉ cần thử nghiệm đúng 1 cấu trúc chuẩn của For...Next thôi. Để nắm chắc nó hoặt động như nào, kết thúc thì counter bằng bao nhiêu?
View attachment 254344
Điểm quan trọng là ở cái giá trị step có 3 trường hợp: <0, =0, >0 thì không chịu thử nghiệm.
Đã viết sẵn cho rồi, chỉ cần thay giá trị vào rồi xem là xong thôi.
...
Const minStp As Long = 1 ' Khi de gia tri <0 (hoac=0) vong lap i khong thoat
...
For stp = minStp To maxCount
...
For i = startCount To maxCount Step stp
...
Cái bảng báo cáo thử nghiệm có đâu?
Mà sao step < 0 lại bị thế?
Chốt lại là mình không cần làm gớm vậy. Thật đơn giản thôi.
View attachment 254345
Phần diễn biến của Bạn, OT hiểu bạn đang muốn nói gì
Phần đó nói về sự tích lão chết tiệt từ chối 1 tấn mật ong rừng, không có mật để chia cho befaint nên ảnh puồn.Bạn hiểu lầm rồi. Phần đó tách riêng bởi dấu gạch gạch ---. Không nói tới bạn gì cả.
Cảm ơn Bạn,View attachment 254349
Không ai can thiệp tới counter trong vòng lặp. Khi nào cần tỏ ra 'nguy hiểm' lắm mới thay đổi counter thôi.
Thảo nào Chú Mỹ nhớ lâu vậy vì hay liên tưởng việc làm trong cuộc sống đến kiến thức, nhưng pahir có kiến thức thì mới liên tưởng được chứ ạ.Phần đó nói về sự tích lão chết tiệt từ chối 1 tấn mật ong rừng, không có mật để chia cho befaint nên ảnh puồn.
Tôi kể câu chuyện chiều nay tại sao đến giờ mới đọc các câu trả lời:
Bà xã bảo: ông rảnh quá ông lấy rổ giá (giá đỗ) ra bứt và đếm xem bao nhiêu cái rễ. Mình vừa bứt vừa đếm đến hơn 100 thì bả hỏi "xong chưa", mình nói chưa xong, quay lại thì quên mất con số. Báo cho bả biết thì bả bảo đếm tiếp nhưng bắt đầu lại từ 1 cũng được. Mình nghe lời đếm lại từ 1 và bị đếm lại như thế 4, 5 lần. Khi xong hết báo cho bả biết là 12, rồi hỏi bà cần biết số rễ làm gì mà giờ chỉ còn 12?
Bả nói xong rồi thì thôi, ông tự suy luận đi, cuối cùng mình kết luận là bả biểu mình lặt rau.
Câu chuyện liên quan ở đây là: Với yêu cầu viết công thức tính ra giá trị counter khi thoát vòng lặp For i = m to 1000 Step n (chứ không phải giá trị cuối của vòng lặp), nếu đã liệt kê ra 1 bảng rồi thì phải suy luận đưa ra 1 công thức tính cho m và n bất kỳ. Và phải suy luận mới ra, đó là mục đích cuối của việc đố, cũng như phải suy luận mới ra việc bị lặt rau chứ không phải đếm rễ
Ghi chú:
Step âm là trừ cho đến khi nhỏ hơn hoặc bằng 1000. Vậy thì m phải đặt con số lớn hơn 1000 chứ?
Khi for i = 1 to m step n thì i = (m-n)+1, n càng tăng thì i càng giảm, m = i chỉ khi nào n=1
Nhiều mà sai thì nhiều làm gì (như befaint nói đụng vào counter)Con cũng chưa tìm hiểu việc đặt số nó có ảnh hưởng gì không nhưng vì duy nghĩ đặt vòng lặp for lồng nhiều vào nhau nên con giảm con số để mang tính test thử rồi ngẫm ra công thức dạng như bài 33 đó ạ:
Vẫu cứ là sai câu hỏi: i = m to 1000 step n, chứ không phải i=1 to m step n.Khi for i = 1 to m step n thì i = (m-n)+1, n càng tăng thì i càng giảm, m = i chỉ khi nào n=1
EndRow = 1000
For i = 1 to EndRow
k = i
Next
Msgbox i & "-" & k
Sub TestOutputCounter()
Dim m As Long, i As Long, n As Long, k As Long, j As Long, p As Long
For i = 2 To 20
m = Cells(i, 1)
k = Cells(i, 2)
n = Cells(i, 3)
For j = m To k Step n
p = j
Next
Cells(i, 4) = p
Cells(i, 5) = j
Next
End Sub
Trời ạ đúng là ra hại não thật không thể yêu thương được, con thì đang mải loay hoay với cái vidu của Bạn @befaint , Bạn nhắc phải đọc thật chậm thôi và đơn giản thôi giờ mới thấy thấm.Không phải ngẫu nhiên tôi viết code để test trong bài 21
tôi viết k = i trong vòng lặp và Msgbox ngoài vòng lặp là để k lấy giá trị cuối của i trong vòng lặp, và Msgbox hiển thị 1 số cuối trong vòng lặp so sánh với khi ra khỏi vòng lặp.Mã:EndRow = 1000 For i = 1 to EndRow k = i Next Msgbox i & "-" & k
Code viết nhiều để test cũng theo cấu trúc trên cho trường hợp tổng quát For i = m to k step n là:
Giải thích code:PHP:Sub TestOutputCounter() Dim m As Long, i As Long, n As Long, k As Long, j As Long, p As Long For i = 2 To 20 m = Cells(i, 1) k = Cells(i, 2) n = Cells(i, 3) For j = m To k Step n p = j Next Cells(i, 4) = p Cells(i, 5) = j Next End Sub
Lấy m (start), k (end), n (step) trên bảng tính ở 3 cột A, B, C. Kết quả số cuối của counter j trong vòng lặp gán vào cột D, giá trị sau khi ra khỏi vòng lặp của j gán xuống cột E
Kết quả:
View attachment 254354
Nhận xét:
p (last counter) = m (start) +bội số lớn nhất của n (step) mà nhỏ hơn (k (end) - m (start)). Chỉ cần cộng counter thêm 1 step thì lớn hơn end. Đó chính là Output counter j
Có thể tính ra last counter bằng công thức sau đó cộng thêm step để cho ra counter
D2 = Last counter = End - MOD( End - Start, Step) =B2-MOD(B2-A2,C2)
E2 = Output Counter + Step = End - MOD( End - Start, Step) + Step = B2-MOD(B2-A2,C2)+C2
View attachment 254355
Test với Step âm: phải cho m lớn hơn k (start > end) mới chạy
View attachment 254357
Cũng còn may chứ không tôi hỏi tới i = m to k step n là còn bể não nữa đó
Những ai hiểu hết code for next và viết code cũng phải bể não như thế này hả Chú Mỹ.Nhận xét:
p (last counter) = m (start) +bội số lớn nhất của n (step) mà nhỏ hơn (k (end) - m (start)). Chỉ cần cộng counter thêm 1 step thì lớn hơn end. Đó chính là Output counter j
Có thể tính ra last counter bằng công thức sau đó cộng thêm step để cho ra counter
D2 = Last counter = End - MOD( End - Start, Step) =B2-MOD(B2-A2,C2)
E2 = Output Counter + Step = End - MOD( End - Start, Step) + Step = B2-MOD(B2-A2,C2)+C2
Đó là cách để suy luận trực quan. Khi quen rồi thì suy luận trực tiếp cách tính ở trong đầu không cần giấy và nháp.Trời ạ đúng là ra hại não thật không thể yêu thương được, con thì đang mải loay hoay với cái vidu của Bạn @befaint , Bạn nhắc phải đọc thật chậm thôi và đơn giản thôi giờ mới thấy thấm.
Con mới làm qua qua cái này để xem công thức tổng quát thế nào quay ra thì thấy bài của Chú Mỹ (công thức khiếp quá) để con đọc thật chậm ạ:
Cảm ơn Chú Mỹ nhiều ạ.
Dạ con ơn Chú Mỹ nhiều , khuya rồi Chú ngủ sớm đi ạ, Chú Mỹ vừa làm quả thông lão cho con đỡ bể não như này thì Chú Mỹ nằm có ngủ được không đó?Đó là cách để suy luận trực quan. Khi quen rồi thì suy luận trực tiếp cách tính ở trong đầu không cần giấy và nháp.
Chả lẽ lần sau vợ bảo đếm rễ lại cứ thế mà đếm sao?
Code trên chỉ để trả lời câu hỏi về hàm Function KeyExistsNhững ai hiểu hết code for next và viết code cũng phải bể não như thế này hả Chú Mỹ.
Nếu không bể não làm sao trả lời được câu hỏi tại sao. Mà không biết hỏi tại sao thì cả đời chỉ xin code hoặc copy code về chạy, chứ chả bao giờ có thể tự viếtBài 15 đã viết:Viết ào ào thế mà có biết nguyên lý hoạt động của Function KeyExists hay không vậy nhóc? Tại sao k cứ thế mà tăng 1?
Dạ, một lần nữa con cảm ơn Chú Mỹ nhiều nhé. Chú Mỹ nghỉ đi ạ, ngày mai nếu có 'rễ giá' đếm Chú không bị nhặt rau nữa >_<Nếu không bể não làm sao trả lời được câu hỏi tại sao. Mà không biết hỏi tại sao thì cả đời chỉ xin code hoặc copy code về chạy, chứ chả bao giờ có thể tự viết
Power Query chỉ cần GroupBy thôiEm chào bác ạ!
Em thấy 1 vấn đề có rất nhiều giải pháp,
Bác có thể giải quyết bằng Power Query không ạ.
let
Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content],
"Grouped Rows" = Table.Group(Source, { "article_no", "Size", "Carton"}, {{"Quantity", each List.Sum([Qty]), type nullable number}}),
"Reordered Columns" = Table.ReorderColumns("Grouped Rows",{"article_no", "Size", "Quantity", "Carton"})
in
"Reordered Columns"
Nghỉ ngợi gì mờ quên ngủ vậyPower Query chỉ cần GroupBy thôi
PHP:let Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content], "Grouped Rows" = Table.Group(Source, { "article_no", "Size", "Carton"}, {{"Quantity", each List.Sum([Qty]), type nullable number}}), "Reordered Columns" = Table.ReorderColumns("Grouped Rows",{"article_no", "Size", "Quantity", "Carton"}) in "Reordered Columns"