Tạo báo cáo giống như Pivot Table. (2 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

thang.phduy2

Thành viên mới
Tham gia
20/1/21
Bài viết
12
Được thích
0
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ị.
 

File đính kèm

Sao bạn không Ghi lại Code của Pivot luôn
 
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ị.
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
 
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
Chia theo cột E ở E3 và E11.

Cảm ơn bạn đã reply.
Bài đã được tự động gộp:

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
Cảm ơn anh. Code chạy ngon lành.
 
Lần chỉnh sửa cuố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ị.
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

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
 
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ị.
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
 
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
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]
 
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

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ùng Sub tốc độ nhanh hơn Function
 
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
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?
 
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?
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)
 
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

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
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
 
Thế khi
For i = 1 to EndRow Step 2
Thì sao?
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 ạ.
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
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 ạ :"'
Bài đã được tự động gộp:

Định hỏi anh đây: Tại sao lại có điều kiện If sArr(i, 3) = 1 Then?
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? }}}}}
 
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 ạ.
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?
 
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?
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.
 
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
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.
 
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.
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.. (@$%@
 
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
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?
 
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?
Con 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
Mã:
Function KeyExists(Result, sKey, j, k) As Boolean
For k = 1 To j
'...
Next k
k xuất phát là 1 khi j=0 k vẫn sẽ là 1.
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)
 
Con 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
Mã:
Function KeyExists(Result, sKey, j, k) As Boolean
For k = 1 To j
'...
Next k
k xuất phát là 1 khi j=0 k vẫn sẽ là 1.
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)
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.
 
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.
ủa câu 1 có gì khác à Chú Mỹ, chờ con test thử xem khác gì ạ.
Câu 2 con giải thích vậy mà sai á trời không khai báo đương nhiên là ByRef thì con biết rồi còn truyền thì con cũng đã nói là truyền sang sub nên nó giữ nguyên mà hic Chú Mỹ đưa câu trả lời của để so sánh với câu trả lời của Chú Mỹ bằng phép tính A=B luôn như phép toán đó hả !$@!!
 
Không có "vòng lặp step".

1613804255222.png
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" :p
Kiếm được 'học trò cưng' rồi hem biết có mật ong rừng hông. :D
 
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" :p
Kiếm được 'học trò cưng' rồi hem biết có mật ong rừng hông. :D

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" :p
Kiếm được 'học trò cưng' rồi hem biết có mật ong rừng hông. :D
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.
Trường hợp của Bạn OT sẽ thử.
---
Phần diễn biến của Bạn, OT hiểu bạn đang muốn nói gì (nếu không tôn trọng Bạn OT cũng sẽ bỏ qua không trả lời)
Đây là nơi học hỏi giao lưu chia sẻ kiến thức là quan trọng còn OT là ai thì cũng không phải vấn đề, với OT sự tôn trọng mọi người & tuân thủ qui định nơi này là quan tọng nhất. Ngay cả khi nhờ vả riêng tư ai đó , OT luôn muốn gửi lời cảm ơn bằng hiện vật phần lớn là bị từ chối OT cũng rất ngại, (vẫn có người thông cảm vì phải nài nỉ nhiều lần mà nhận một chút)
Không dấu gì Bạn OT cũng vẫn còn một nick nữa nhưng từ lâu cũng không viết bài nick này là ảnh đại diện của 2 mẹ con OT (có người đã biết đến nick này với nick đó là một cặp) , OT thay đổi cũng vì vấn đề riêng tư liên quan đến công việc sau khi chuyển công tác.
Bạn ở HN nếu muốn biết OT thì OT có thể gặp bạn để giao lưu.. còn trên đây với OT không tiện mong bạn thông cảm.
Cảm ơn Bạn đã quan tâm.
 
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.
Em 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 ạ.
 
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ả.

Xin lỗi Bạn vì OT đã hiểu nhầm,
cảm ơn Bạn đã chỉ dẫn với gợi ý của Bạn OT thử làm để kiểm tra thì kết quả như sau, mong Bạn chỉ dẫn thêm ạ:
Mã:
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

1613812801163.png
 
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?

1613814348668.png

Đ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.
 
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.
Ủ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 ạ.
Cũng có thể là do OT viết sai câu lệnh nên nó mới vậy ạ, híc OT xem thêm ạ :
Mã:
    ...
    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

Đây ạ, khi stp=0 (hoặc <0) thì i lặp đi lặp lại là 1 khồn tăng nên không thoát được i:
Hic mớ đầu OT cũng làm đơn giản như vi dụ của Bạn nhưng chưa hình dung được bước chạy với các thay đổi giá trị: startCount & stp nên phải tạo thêm các vòng lặp để đưa xuống sheet cho dễ nhìn hơn, vì trong cửa số debug OT coi không quen ạ:

1613815909469.png
À với step < 0 thì thoát luôn i Bạn à, nhưng do OT để nó chạy từ âm đến dương qua 0 nên nó không thoát được được, OT hiểu rồi.
Cảm ơn Bạn đã nhắc.
 
Lần chỉnh sửa cuối:
Phần diễn biến của Bạn, OT hiểu bạn đang muốn nói gì
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 đó 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ứ?
 
Lần chỉnh sửa cuối:
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.
Cảm ơn Bạn,
Do OT không hiểu về vấn đề này (bảo sao Bạn cứ bảo làm thật đơn giản thôi) chỉ nghĩ đơn giản không thấy rõ được các bước lặp loại này nên loay hoay mãi làm thử để đưa xuốn sheet để xem cho dễ thôi ạ, tránh đoán mò như những bài trước ..

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ứ?
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ứ ạ.
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 đó ạ:
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
 
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 đó ạ:
Nhiều mà sai thì nhiều làm gì (như befaint nói đụng vào counter)
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ẫ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.

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 đó
 
Không phải ngẫu nhiên tôi viết code để test trong bài 21
Mã:
EndRow = 1000
For i = 1 to EndRow
    k = i
Next
Msgbox i & "-" & k
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.
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à:

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
Giải thích code:
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ả:

1613837120708.png

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). 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

1613837153998.png

Test với Step âm: phải cho m lớn hơn k (start > end) mới chạy

1613837430986.png
 
Lần chỉnh sửa cuối:
Không phải ngẫu nhiên tôi viết code để test trong bài 21
Mã:
EndRow = 1000
For i = 1 to EndRow
    k = i
Next
Msgbox i & "-" & k
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.
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à:

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
Giải thích code:
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
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 ạ.
1613837629160.png

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ậ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
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ỹ.
 
Lần chỉnh sửa cuối:
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 ạ.
Đó 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.
Phải tập suy luận chứ chả lẽ lần sau vợ bảo đếm rễ giá lại cứ thế mà đếm sao?
 
Đó 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?
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 đó? :fish:
 
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ỹ.
Code trên chỉ để trả lời câu hỏi về hàm Function KeyExists
Bà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?
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
 
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
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 >_<
 
Em 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 ạ.
Power 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"
 
Power 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"
Nghỉ ngợi gì mờ quên ngủ vậy /-*+/
 

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

Back
Top Bottom