Đưa mỗi bức ảnh lên thì có khi cả mấy tháng chưa chắc đã được đâu bạn.đã loay hoay mấy ngày nay vẫn không được.
Bạn xem thử. . .Đây là file danh sách
Bài này là kinh điển kỹ thuật của nhà băng cuối ngày sort phát sinh, gộp, và tính tổng. Chỉ là ở đây, người ta làm ngược tổng từ dưới lên (ít có, nhưng không hẳn là không ai làm)Bạn xem thử. . .
Dùng mảng code chạy nhay hơnĐây là file danh sách và macro mình làm thử nhưng chạy không ra được đúng sum tổng ở các dòng dưới:
Sub Tinhtong()
Dim m As Long
Dim rA As Range
For Each rA In Range("C7", Range("F" & Rows.Count).End(xlUp)).SpecialCells(xlConstants, xlNumbers).Areas
rA.Cells(0).Formula = "=SUM(" & rA.Address & ")"
Next rA
End Sub
Sub ABC()
Dim sh As Worksheet, rng As Range, TT(), t(), sR&, i&, j&
Set sh = ThisWorkbook.Sheets("VP_2")
Set rng = sh.Range("A6:F" & sh.Range("A1000000").End(xlUp).Row)
sR = rng.Rows.Count
ReDim TT(1 To 1, 1 To 4)
ReDim t(1 To 1, 1 To 4)
For i = sR To 1 Step -1
If IsNumeric(rng(i, 1)) Then
For j = 3 To 6
t(1, j - 2) = t(1, j - 2) + rng(i, j)
TT(1, j - 2) = TT(1, j - 2) + rng(i, j)
Next j
Else
rng(i, 3).Resize(, 4) = t
rng(i, 3).Resize(, 4).Font.Bold = True
ReDim t(1 To 1, 1 To 4)
End If
Next i
sh.Range("C5").Resize(, 4) = TT
End Sub
Sub ABC_1()
Dim Sh As Worksheet, Rng As Range, TT(), t(), SoDg&, I&, J&, Col As Integer
Set Sh = ThisWorkbook.Sheets("VP_2")
Set Rng = Sh.Range("A6:F" & Sh.Range("A1000000").End(xlUp).Row)
SoDg = Rng.Rows.Count
ReDim TT(1 To 1, 1 To 4)
ReDim t(1 To 1, 1 To 4)
For I = SoDg To 1 Step -1
If IsNumeric(Rng(I, 1).Value) Then
For J = 3 To 6
t(1, J - 2) = t(1, J - 2) + Rng(I, J)
' TT(1, J - 2) = TT(1, J - 2) + Rng(I, J) '
Next J
Else
Rng(I, 3).Resize(, 4) = t
Rng(I, 3).Resize(, 4).Font.Bold = True
For Col = 1 To 4
TT(1, Col) = TT(1, Col) + t(1, Col)
Next Col
ReDim t(1 To 1, 1 To 4)
End If
Next I
Sh.Range("C5").Resize(, 4) = TT
End Sub
Cháu. Phiền chú giải thích giúp. Lỡ có người không biết như cháu nữa. Cám ơn chú ạBạn nào không biết thì lên tiếng tôi sẽ giải thích. Không thấy thì tôi coi như mọi người đều hiểu, chỉ có mình lo xa.
Úi bác phức tạp thật. Có lúc bác đưa cơm đến tận mồm, có lúc bác lại vứt cho cái nồi với cái chiếu nhậu. Copy vào nó cứ đỏ lòm là biết cần lửa, lửa xong thấy ... là thiếu gạo, gạo xong lại thấy ? là lại đi tìm rau, mà ở đô thị ra chợ thì lâu lắm, xung quanh không ai làm vườn, thế là nhịn. Thiệt là khó quá đi.Chú thêm cho các bạn nào mới bước vào khái niệm dùng mảng:
Các bạn có để ý code bài #6 của tôi dùng Erase để xóa mảng trong khi bài #7 và #8 dùng Redim để làm việc tương tự?
Bạn nào không biết thì lên tiếng tôi sẽ giải thích. Không thấy thì tôi coi như mọi người đều hiểu, chỉ có mình lo xa.
Xem code khai báo. Khi tôi dùng Dim a(1 To 10) thì a được xác định là mảng tĩnh. Khi hai bài kia khai Dim a() thì VBA hiểu là mảng động.Cháu. Phiền chú giải thích giúp. Lỡ có người không biết như cháu nữa. Cám ơn chú ạ
Bỏi tôi biết là từ Erase/ReDim dễ bị hiểu lầm cho nên tôi cố tình nói chgo bạn ở bài #10 hỏi.Úi bác phức tạp thật....
Về vấn đề chính: theo em thì Erase là xóa (không cần google dịch), Dim là định nghĩa biến => Redim là định nghĩa lại biến, mà định nghĩa lại thì nó phải xem cái cũ không tồn tại nghĩa là xóa.
...
Em đọc xong và rối tung, cơ bản là do không có cơ bản nên chịu. Em chỉ thấy khi code có array thì y rằng dưới sẽ có redim, và cứ nhớ vậy cho gọn.Xem code khai báo. Khi tôi dùng Dim a(1 To 10) thì a được xác định là mảng tĩnh. Khi hai bài kia khai Dim a() thì VBA hiểu là mảng động.
Mảng tĩnh luôn xác định vị trí cố định trong bộ nhớ, và được VBA tạo ngay lúc khai báo. Mảng động chỉ là giành trước tên biến, chưa xác định gì cả (ngoài việc nếu bạn có thêm As kiểu gì đó thì mảng bắt buộc phải là kiểu ấy).
Để trở về trị mặc định (điển hình 0 với kiểu số, "" với kiểu chuỗi,...), mảng động dùng Erase, mảng tĩnh dùng ReDim. Nói cách khác:
1. mảng tĩnh không thể ReDim. Đã tĩnh rồi cón ReDim sửa đổi số cột/dòng khỉ mốc gì nữa.
2. mảng động không thể Erase (không hẳn đúng 100%, xem phần cuối đoạn này sẽ rõ). Dùng lệnh này là bạn tách rời tên mảng ra khỏi bộ nhớ của nó. Tức là muốn dùng a kế tiếp thì bạn phải ReDim nó lại. Chả hiệu quả chút nào so với ReDim. Nhưng nếu code của bạn gặp vấn đề với lượng bộ nhớ thì Erase là cách hữu hiệu nhất để bảo đảm mảng nhả bộ nhớ ra.
Ghi chú thêm về bộ nhớ: nếu bạn gặp vấn đè với lượng bộ nhớ thì không nên dùng mảng tĩnh. Bởi vì Erase nó chả giúp cho bạn thấu về bộ nhớ. Tuy nhiên nếu vấn đề không đễn nỗi nặng và lý do chính nằm ở mảng chuỗi thì cái nào cũng được. Trong mảng chuỗi, các vị trí phần tử chỉ chứa con trỏ đến chuỗi giá trị.
Bỏi tôi biết là từ Erase/ReDim dễ bị hiểu lầm cho nên tôi cố tình nói chgo bạn ở bài #10 hỏi.
Ở đây tôi biết chỉ có mình bạn ấy và 1 bạn nữa là có thì giờ nghe chuyện "lý thuyết" của tôi. Những người khác xem trọng "thực hành" hơn.
Và thục hành ra sao tôi không biết chứ về lý thuyết thì hiểu đơn giản như vậy là SAI!
Điển hình nhất: bạn bảo ReDim là định nghĩa lại biến là sai. Chịu khó đọc câu thứ hai của phần trên. Nếu nói đúng thì phải là "lập mảng mới với kích thước mới". Lập mảng khác với định nghĩa mảng.
Khai báo (Dim) là lệnh dẫn trình dịch, xảy ra trước khi code chạy. Sửa mảng (ReDim) là lệnh bình thường, xảy ra khi code chạy.
Hồi nào tôi cứ ngỡ việc phân biệt lệnh dẫn và lệnh chạy là chuyện thực tế. Té ra bà con coi đấy là lý thuyết?
Xin lỗi tôi viết nhầm. Đúng thì phải là:...
Trên bác bôi đậm không biết là có ý đồ chiến thuật gì vậy ạ?
Có vẻ không hợp lý lắm.cơ bản là do không có cơ bản
Vẫn đang suy ngẫm, chưa kịp hỏi thì anh đã điều chỉnh lại rồi.Mảng động dùng ReDim, mảng tĩnh dùng Erase (có muốn ReDim VBA cũng không cho phép).
Em thì lý thuyết không nhớ được nên phải tóm nó gọn lại.Xin lỗi tôi viết nhầm. Đúng thì phải là:
Mảng động dùng ReDim, mảng tĩnh dùng Erase (có muốn ReDim VBA cũng không cho phép).
há há há. Văn 5, 6 nên nó lại rất hợp lý.Có vẻ không hợp lý lắm.
Vẫn đang suy ngẫm, chưa kịp hỏi thì anh đã điều chỉnh lại rồi.
Đỏ: tôi có bài viết về lệnh for/next. Nó không hẳn đơn giản như bạn nghĩ....VD: array kèm redim. for cần false updating... Nói chung là làm cho dễ nhớ, quan điểm "sai thì sửa, chửa thì đẻ".
Tình huống vui vẻ thôi bác.Đỏ: tôi có bài viết về lệnh for/next. Nó không hẳn đơn giản như bạn nghĩ.
Xanh: nếu bạn có con gái thì bạn có còn quan niệm ấy không? Có những việc đợi đến mới sửa sai, có những việc đaoịh đến sửa sai thì đã bút sa gà chết.
Chú: tôi hiểu chỗ dỏ, nó liên quan đến chỗ xanh. Từ next là tôi nói trại từ need (không ai Tây bồi êm bằng tôi đâu ).
Tôi có nói chuyện phá hay để đâu - đó là chính kiến về xã hội. Mà nói chính kiến thì cả đời còn chưa hết....
Nhưng mà có chứ bác, nếu may mắn mà có con gái, rồi nếu đen đen mà nó rơi vào xanh xanh thì vẫn phải cho xanh chứ không cho phá được.
...
Sau khi đọc đoạn này, Chợt nhận ra bản thân cháu cũng đang mập mờ chỗ này.2. mảng động không thể Erase (không hẳn đúng 100%, xem phần cuối đoạn này sẽ rõ). Dùng lệnh này là bạn tách rời tên mảng ra khỏi bộ nhớ của nó. Tức là muốn dùng a kế tiếp thì bạn phải ReDim nó lại. Chả hiệu quả chút nào so với ReDim. Nhưng nếu code của bạn gặp vấn đề với lượng bộ nhớ thì Erase là cách hữu hiệu nhất để bảo đảm mảng nhả bộ nhớ ra.