Nhờ xem lại hàm sumifs trong vba

Liên hệ QC

kid.phan2705

Thành viên mới
Tham gia
14/5/14
Bài viết
12
Được thích
0
Hiện tại e có 1 file tổng hợp nhập xuất tồn, nếu dùng hàm sumifs thì ra đúng kết quả. Tuy nhiên nếu dùng function.sumifs trong vba thì nó không hoạt động đúng.
Yêu cầu là check mã vật tư trước ngày start => số lượng hàng tồn
E đã thử nghiệm ở hàm sumifs thì ra đúng. Lò mò xài vba với đoạn code như hình thì nó lại bỏ qua cái điều kiện thứ 2 (check ngày).
Mọi người giúp e sai ở chỗ nào với.


1651907347322.png
 

File đính kèm

  • Test.xlsm
    66.9 KB · Đọc: 18
Giải pháp
Hiện tại e có 1 file tổng hợp nhập xuất tồn, nếu dùng hàm sumifs thì ra đúng kết quả. Tuy nhiên nếu dùng function.sumifs trong vba thì nó không hoạt động đúng.
Yêu cầu là check mã vật tư trước ngày start => số lượng hàng tồn
E đã thử nghiệm ở hàm sumifs thì ra đúng. Lò mò xài vba với đoạn code như hình thì nó lại bỏ qua cái điều kiện thứ 2 (check ngày).
Mọi người giúp e sai ở chỗ nào với.
Code thay thế thì dễ thôi, chỉ cần nhờ ai đó viết hộ. Nhưng nếu bạn không biết sai ở đâu thì ngày mai, tuần sau, tháng tới bạn cũng sẽ lặp lại lỗi đó. Chả nhẽ cứ đi nhờ viết code thay thế?

Lỗi của bạn là tham chiếu chưa đủ (dòng phải từ 4) nên kết quả nếu có sẽ không chính xác. Đó là lỗi nhỏ...
Hiện tại e có 1 file tổng hợp nhập xuất tồn, nếu dùng hàm sumifs thì ra đúng kết quả. Tuy nhiên nếu dùng function.sumifs trong vba thì nó không hoạt động đúng.
Yêu cầu là check mã vật tư trước ngày start => số lượng hàng tồn
E đã thử nghiệm ở hàm sumifs thì ra đúng. Lò mò xài vba với đoạn code như hình thì nó lại bỏ qua cái điều kiện thứ 2 (check ngày).
Mọi người giúp e sai ở chỗ nào với.
Code thay thế thì dễ thôi, chỉ cần nhờ ai đó viết hộ. Nhưng nếu bạn không biết sai ở đâu thì ngày mai, tuần sau, tháng tới bạn cũng sẽ lặp lại lỗi đó. Chả nhẽ cứ đi nhờ viết code thay thế?

Lỗi của bạn là tham chiếu chưa đủ (dòng phải từ 4) nên kết quả nếu có sẽ không chính xác. Đó là lỗi nhỏ. Lỗi lớn ở dòng a = ..., cụ thể ở "<" & day1
Mã:
For i = 4 To lrnxt
        a = WorksheetFunction.SumIfs(rngslnhap, rngvtnhap, Ton.Range("A" & i), rngngaynhap, "<" & day1)
Hiện tại NXT!O2 = 12.04.2022 (trên máy tôi ngày tháng có dạng dd.mm.yyyy) nên day1 = 12.04.2022 (do Dim day1 As Variant, day2 As Variant), và "<" & day1 = "<12.04.2022". Trong VBA chuỗi kiểu đó sẽ sai.

Nếu bạn sửa thành
Dim day1 As Long, day2 As Long

thì day1 = 44663, và "<" & day1 = "<44663". Lúc này code sẽ chạy đúng.

Tóm lại sửa thành
Mã:
Dim day1 As Long, day2 As Long
 
Upvote 0
Giải pháp
Chú @batman1 nếu giả sử cháu không khai day1 as long...... Mà chỉ khai dim day1, day2. Kết quả có đúng không nhỉ? Và không gán type cho biến có bất lợi gì không nhỉ? Tại cháu không ngồi máy mà tò mò
 
Upvote 0
Chú @batman1 nếu giả sử cháu không khai day1 as long...... Mà chỉ khai dim day1, day2. Kết quả có đúng không nhỉ? Và không gán type cho biến có bất lợi gì không nhỉ? Tại cháu không ngồi máy mà tò mò
Kết quả giống như khai báo của tác giả thôi vì mặc định là Variant.

Bất lợi gì ở đây? Bất lợi là khai báo không đúng hoặc không "tối ưu" thôi, chứ không phải là ở chỗ khai báo hay không khai báo. Không gán kiểu thì mặc định là Variant. Nếu trong trường hợp cụ thể biến chuẩn phải nên là Variant thì khai báo kiểu Variant tường minh hay không đều như nhau. Nhưng nếu biến phải là Long thì dù khai báo nhưng là Variant thì vẫn sai.
 
Upvote 0
Kết quả giống như khai báo của tác giả thôi vì mặc định là Variant.

Bất lợi gì ở đây? Bất lợi là khai báo không đúng hoặc không "tối ưu" thôi, chứ không phải là ở chỗ khai báo hay không khai báo. Không gán kiểu thì mặc định là Variant. Nếu trong trường hợp cụ thể biến chuẩn phải nên là Variant thì khai báo kiểu Variant tường minh hay không đều như nhau. Nhưng nếu biến phải là Long thì dù khai báo nhưng là Variant thì vẫn sai.
Cám ơn chú nhiều. Tại nhiều khi biếng viết code nháp. Không có options ở đầu sub. Viết xong bắt đầu khai báo biến. Thành ra không điền kiểu biến. Nên mới hỏi chú việc bất lợi. Cám ơn chú vì những thông tin đã chia sẻ
 
Upvote 0
Cám ơn chú nhiều. Tại nhiều khi biếng viết code nháp. Không có options ở đầu sub. Viết xong bắt đầu khai báo biến. Thành ra không điền kiểu biến. Nên mới hỏi chú việc bất lợi. Cám ơn chú vì những thông tin đã chia sẻ
Vấn đề là khai báo và thực thi theo kiểu ít hoặc tốt nhất là không phụ thuộc vào những thay đổi hay thiết lập nào đó. Vd.
ngày 12 tháng 4 năm 2022 trên máy tôi là 12.04.2022, trên máy bạn là 12/04/2022, trên máy khác lại khác nữa. Rồi lăn tăn chuyện trong VBA là mm/dd/yyyy hay dd/mm/yyyy, là ngày 12 tháng 4 năm 2022 hay ngày 4 tháng 12 năm 2022. Thế có phải rách việc không? Khác gì bàn tay trần thọc xuống bể phốt. Trong khi đó nếu Dim day1 As Long thì day1 = 44663 trên bất kỳ máy nào, mọi lúc mọi nơi. Con số 44663 luôn luôn đại diên cho ngày 12 tháng 4 năm 2022, không thể hiểu khác được, không thể là ngày 4 tháng 12 năm 2022 được.

Tóm lại tuy không được lanh lợi như con nhà người ta thì phải khôn ngoan hơn con nhà người ta. :D
 
Upvote 0
@batman1 dạ. Cháu hiểu rồi ạ. Cám ơn chú nhiều về thông tin chú chia sẻ ạ
 
Upvote 0
Code thay thế thì dễ thôi, chỉ cần nhờ ai đó viết hộ. Nhưng nếu bạn không biết sai ở đâu thì ngày mai, tuần sau, tháng tới bạn cũng sẽ lặp lại lỗi đó. Chả nhẽ cứ đi nhờ viết code thay thế?

Lỗi của bạn là tham chiếu chưa đủ (dòng phải từ 4) nên kết quả nếu có sẽ không chính xác. Đó là lỗi nhỏ. Lỗi lớn ở dòng a = ..., cụ thể ở "<" & day1
Mã:
For i = 4 To lrnxt
        a = WorksheetFunction.SumIfs(rngslnhap, rngvtnhap, Ton.Range("A" & i), rngngaynhap, "<" & day1)
Hiện tại NXT!O2 = 12.04.2022 (trên máy tôi ngày tháng có dạng dd.mm.yyyy) nên day1 = 12.04.2022 (do Dim day1 As Variant, day2 As Variant), và "<" & day1 = "<12.04.2022". Trong VBA chuỗi kiểu đó sẽ sai.

Nếu bạn sửa thành


thì day1 = 44663, và "<" & day1 = "<44663". Lúc này code sẽ chạy đúng.

Tóm lại sửa thành
Mã:
Dim day1 As Long, day2 As Long
Em cảm ơn a nhiều, đã được thông não. Đúng là e từng gặp trường hợp như a nói. Giờ đã hiểu sơ sơ ra rồi :D
 
Upvote 0
Thử cái code này xem.
Mã:
Sub tinhsoluong()
   Dim i As Long, lr As Long, dic As Object, arr, data, kq() As Double, a As Long, dk As String, b As Long, ngaybd As Long, ngaykt As Long
   Set dic = CreateObject("scripting.dictionary")
   With Sheets("NXT")
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        arr = .Range("A4:B" & lr).Value
        ngaybd = .Range("o2").Value2
        ngaykt = .Range("R2").Value2
        For i = 1 To UBound(arr)
            dk = arr(i, 1)
            If Not dic.exists(dk) Then
               dic.Add dk, i
            End If
        Next i
        ReDim kq(1 To UBound(arr), 1 To 8)
   End With
   With Sheets("Nhap")
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        arr = .Range("A3:i" & lr).Value
        For i = 1 To UBound(arr)
            If CLng(arr(i, 2)) < ngaybd Then
               dk = arr(i, 4)
               a = dic.Item(dk)
               If a Then
                  kq(a, 1) = kq(a, 1) + arr(i, 7)
                  kq(a, 2) = kq(a, 2) + arr(i, 9)
                  kq(a, 7) = kq(a, 1) + kq(a, 3)
                  kq(a, 8) = kq(a, 2) + kq(a, 4)
               End If
            ElseIf CLng(arr(i, 2)) <= ngaykt Then
               dk = arr(i, 4)
               a = dic.Item(dk)
               If a Then
                  kq(a, 3) = kq(a, 3) + arr(i, 7)
                  kq(a, 4) = kq(a, 4) + arr(i, 9)
                  kq(a, 7) = kq(a, 1) + kq(a, 3)
                  kq(a, 8) = kq(a, 2) + kq(a, 4)
               End If
            End If
       Next i
  End With
  With Sheets("Xuat")
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        arr = .Range("A3:K" & lr).Value
        For i = 1 To UBound(arr)
            If CLng(arr(i, 2)) < ngaybd Then
               dk = arr(i, 6)
               a = dic.Item(dk)
               If a Then
                  kq(a, 1) = kq(a, 1) - arr(i, 9)
                  kq(a, 2) = kq(a, 2) - arr(i, 11)
                  kq(a, 7) = kq(a, 1) + kq(a, 3) - kq(a, 5)
                  kq(a, 8) = kq(a, 2) + kq(a, 4) - kq(a, 6)
               End If
            ElseIf CLng(arr(i, 2)) <= ngaykt Then
               dk = arr(i, 6)
               a = dic.Item(dk)
               If a Then
                  kq(a, 5) = kq(a, 5) + arr(i, 9)
                  kq(a, 6) = kq(a, 6) + arr(i, 11)
                  kq(a, 7) = kq(a, 1) + kq(a, 3) - kq(a, 5)
                  kq(a, 8) = kq(a, 2) + kq(a, 4) - kq(a, 6)
               End If
            End If
       Next i
  End With
  With Sheets("NXT")
       .Range("D4:K4").Resize(UBound(kq)).Value = kq
  End With
  Set dic = Nothing
End Sub
Bạn làm hay quá
Bạn giúp mình bài của mình phần nhập + xuất + tồn cuối kỳ
Cảm ơn bạn trước
 

File đính kèm

  • NXT.xlsm
    11.9 KB · Đọc: 7
Upvote 0
Web KT

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

Back
Top Bottom