Hỗ trợ tính tổng ở vị trí gần nhất

Liên hệ QC

Tình nghĩa giang hồ

Thanh sơn bất cải, lục thủy trường lưu
Tham gia
29/9/20
Bài viết
330
Được thích
429
Chào anh chị, em có vấn đề này nhờ anh chị hỗ trợ giúp

Dữ liệu của em gồm có: cột A, và cột D. Ở cột D (giá trị Assigned lúc âm, lúc dương).

Cột B là kết quả mong muốn, còn cột G vị trí thì em ghi để biết thôi, chứ thực tế không có cột này.

Quy luật 1: nếu Assigned là dương thì tìm tổng >= với nó. VD Assigned = 10, thì tổng 5 + 5, 5+6, 6+ 7……đều ok, vì tất cả tổng đó đều >= 10. NHƯNG em chỉ lấy 1 giá trị tổng thôi, và theo vị trí làm ưu tiên. Nếu ở vị trí 0,1 và 1,2, hoặc 2,3 có tổng thỏa yêu cầu thì ta chọn vị trí tổng 0,1 vì ưu tiên vị trí.

Quy luật 2: nếu nếu Assigned là âm, thì tìm tổng <= với nó. VD: Assined = 12- thì tổng (3-) + (9-) hoặc (9-) + (4-) đều được. NHƯNG (3-) và (9-) ở vị trí 2 và 4 CÒN (9-) và (4-) ở vị trí 4 và 6. Ta phải chọn vị trí 2 và 4.

Vấn đề này luôn ưu tiên vị trí, và em chỉ cần 1 tổng thôi là đủ.

Nhờ anh chị hỗ trợ giúp em trường hợp này.



Ghi chú: Em có nghe A.Việt Mini và anh Ad nói về giá trị số âm ở cột bên phải thành text thì: thật sự dữ liệu này em đổ từ phần mềm ra, nên nó ra vậy, trường hợp để vậy vẫn xử lý được thì anh chị xử lý giúp em. Còn số âm để dấu – bên phải gây khó khăn thì anh chị tạo giúp em cột phụ (kế cột A chẳng hạn), để chuyển – bên phải thành – bên trái giống thông thường cho dễ thao tác.

Em cảm ơn anh chị nhiều.
 

File đính kèm

  • tổng số dương.jpg
    tổng số dương.jpg
    79.2 KB · Đọc: 11
  • tính tổng số âm.jpg
    tính tổng số âm.jpg
    77.6 KB · Đọc: 11
  • tìm tổng theo vị trí.xlsx
    8.8 KB · Đọc: 8
Chào anh chị, em có vấn đề này nhờ anh chị hỗ trợ giúp

Dữ liệu của em gồm có: cột A, và cột D. Ở cột D (giá trị Assigned lúc âm, lúc dương).

Cột B là kết quả mong muốn, còn cột G vị trí thì em ghi để biết thôi, chứ thực tế không có cột này.

Quy luật 1: nếu Assigned là dương thì tìm tổng >= với nó. VD Assigned = 10, thì tổng 5 + 5, 5+6, 6+ 7……đều ok, vì tất cả tổng đó đều >= 10. NHƯNG em chỉ lấy 1 giá trị tổng thôi, và theo vị trí làm ưu tiên. Nếu ở vị trí 0,1 và 1,2, hoặc 2,3 có tổng thỏa yêu cầu thì ta chọn vị trí tổng 0,1 vì ưu tiên vị trí.

Quy luật 2: nếu nếu Assigned là âm, thì tìm tổng <= với nó. VD: Assined = 12- thì tổng (3-) + (9-) hoặc (9-) + (4-) đều được. NHƯNG (3-) và (9-) ở vị trí 2 và 4 CÒN (9-) và (4-) ở vị trí 4 và 6. Ta phải chọn vị trí 2 và 4.

Vấn đề này luôn ưu tiên vị trí, và em chỉ cần 1 tổng thôi là đủ.

Nhờ anh chị hỗ trợ giúp em trường hợp này.



Ghi chú: Em có nghe A.Việt Mini và anh Ad nói về giá trị số âm ở cột bên phải thành text thì: thật sự dữ liệu này em đổ từ phần mềm ra, nên nó ra vậy, trường hợp để vậy vẫn xử lý được thì anh chị xử lý giúp em. Còn số âm để dấu – bên phải gây khó khăn thì anh chị tạo giúp em cột phụ (kế cột A chẳng hạn), để chuyển – bên phải thành – bên trái giống thông thường cho dễ thao tác.

Em cảm ơn anh chị nhiều.
Các số tính tổng là phải = 2 hay là có thể khác
 
Upvote 0
Giả sử kết quả có 2 cặp: 2-16 và 4-6
kết quả thế nào?
 
Upvote 0
Nếu đây là bài toán liên quan đến công nợ - thanh toán, có lẽ bạn nên quan tâm việc này:
Ưu tiên "=" trước, sau đó mới xét ">" theo vị trí
VD:
Hóa đơn 1: 100.000
Hóa đơn 2: 150.000
Hóa đơn 3: 200.000
Số tiền thanh toán: 300.000
Kkết quả của nợ phải thu theo HĐ có thể là:

KQ1: Bù trừ theo vị trí (HĐ1+HĐ2+1 phần HĐ3)
HĐ 3: 150.000

hoặc KQ2: Bù trừ theo hóa đơn (HĐ1 và HĐ3)
HĐ2: 150.000
 
Upvote 0
Giả sử kết quả có 2 cặp: 2-16 và 4-6
kết quả thế nào?
Anh hỏi em mới ngớ ra, 2-16 và 4-6 thì lúc đó khả năng 2-4-6 đã khớp lệnh rồi. vậy clear công nợ 2-4-6
Bài đã được tự động gộp:

Nếu đây là bài toán liên quan đến công nợ - thanh toán, có lẽ bạn nên quan tâm việc này:
Ưu tiên "=" trước, sau đó mới xét ">" theo vị trí
VD:
Hóa đơn 1: 100.000
Hóa đơn 2: 150.000
Hóa đơn 3: 200.000
Số tiền thanh toán: 300.000
Kkết quả của nợ phải thu theo HĐ có thể là:

KQ1: Bù trừ theo vị trí (HĐ1+HĐ2+1 phần HĐ3)
HĐ 3: 150.000

hoặc KQ2: Bù trừ theo hóa đơn (HĐ1 và HĐ3)
HĐ2: 150.000
Đúng rồi anh đây là bài toán theo công nợ, mục đích là clear công nợ nè.
Bài đã được tự động gộp:

Nếu đây là bài toán liên quan đến công nợ - thanh toán, có lẽ bạn nên quan tâm việc này:
Ưu tiên "=" trước, sau đó mới xét ">" theo vị trí
VD:
Hóa đơn 1: 100.000
Hóa đơn 2: 150.000
Hóa đơn 3: 200.000
Số tiền thanh toán: 300.000
Kkết quả của nợ phải thu theo HĐ có thể là:

KQ1: Bù trừ theo vị trí (HĐ1+HĐ2+1 phần HĐ3)
HĐ 3: 150.000

hoặc KQ2: Bù trừ theo hóa đơn (HĐ1 và HĐ3)
HĐ2: 150.000
trong VD của anh thì :
KQ1: Bù trừ theo vị trí (HĐ1+HĐ2+1 phần HĐ3)
HĐ 3: 150.000
Kết quả 1 là hợp lý hơn đó anh.
Công nợ bên em là đang làm theo cách của kết quả 1.
Còn em là người cải tiến giúp công nợ một cách tự động, và không am hiểu công nợ lắm. Đang học từ từ để cải tiến đó anh.
 
Upvote 0
Anh hỏi em mới ngớ ra, 2-16 và 4-6 thì lúc đó khả năng 2-4-6 đã khớp lệnh rồi. vậy clear công nợ 2-4-6
4-6 khớp lệnh thì tại sao phải cần đến 2-4-6?

Tóm lại là duyệt qua từng vị trí theo thứ tự dòng, cứ gặp ">=" là xử thôi đúng không?

Làm bằng VBA có OK không bạn?
 
Upvote 0
4-6 khớp lệnh thì tại sao phải cần đến 2-4-6?

Tóm lại là duyệt qua từng vị trí theo thứ tự dòng, cứ gặp ">=" là xử thôi đúng không?

Làm bằng VBA có OK không bạn?
dạ được anh, em đang cần làm bằng VBA đó anh. Cứ theo cách của anh ạ. Em cảm ơn anh.
 
Upvote 0
Dạ nếu tổng 2 thỏa yêu cầu thì ngưng, còn tổng 2 số không thỏa mãn >= hoặc <= thì lúc đó: phải tổng 3,hoặc tổng 4 anh.
Tham khảo code dưới đây.
Chưa xét các trường hợp không tìm thấy nghiệm thỏa mãn nhé bạn
Mã:
Option Explicit

Sub abc()
Dim Nguon
Dim Gh
Dim test As Boolean
Dim tam0, tam1
Dim csD
Dim Kq
Dim rws, i, j, k

With Sheet1
    Nguon = .Range("A2", .Range("A2").End(xlDown))
    Gh = .Range("D2")
End With
test = Gh > 0
rws = UBound(Nguon)
ReDim tam1(rws - 1)
ReDim csD(rws - 1)
With CreateObject("Scripting.Dictionary")
    ReDim tam0(rws)
    For i = 1 To rws
        If (Nguon(i, 1) > 0) = test Then
            If test Then
                k = Nguon(i, 1)
            Else
                k = Left(Nguon(i, 1), Len(Nguon(i, 1)) - 1) * 1
            End If
            tam1(j) = k
            csD(j) = i
           
            tam0(0) = j
            .Item(j) = Array(k, 0, tam0)
           
            j = j + 1
        End If
    Next i
    tam0 = .items
    ReDim Preserve tam1(j - 1)
    ReDim Preserve csD(j - 1)
End With
If Not test Then
    k = Left(Gh, Len(Gh) - 1) * 1
    Gh = k
End If
ReDim Kq(1 To rws, 1 To 1)
tohop_tong tam1, csD, tam0, Gh, Kq
Sheet1.Range("C2").Resize(UBound(Kq), UBound(Kq, 2)) = Kq
End Sub

Sub tohop_tong(ByVal Nguon_, ByVal csD_, ByRef Loc, ByVal Gh_, ByRef Kq_)
Dim tgr
Dim stt
Dim mang
Dim tam
Dim i, j, k, x, z, t
With CreateObject("Scripting.Dictionary")
    k = 1
    Do While k > 0
        For i = 0 To UBound(Loc) - 1
            tgr = Loc(i)(0)
            stt = Loc(i)(1)
            mang = Loc(i)(2)
            tam = mang
            If mang(stt) < UBound(Nguon_) Then
                For j = mang(stt) + 1 To UBound(Nguon_)
                    If tgr + Nguon_(j) < Gh_ Then
                        tam(stt + 1) = j
                        '.Item(.Count) = Array(tgr + Nguon_(j), j, tam)
                        .Item(.Count) = Array(tgr + Nguon_(j), stt + 1, tam)
                        k = 1
                    Else
                        k = 0
                        Kq_(csD_(j), 1) = csD_(j) - 1
                        For z = 0 To stt
                            t = mang(z)
                            Kq_(csD_(t), 1) = csD_(t) - 1
                        Next z
                        Exit For
                    End If
                Next j
            End If
            If k = 0 Then Exit For
        Next i
        Loc = .items
        .RemoveAll
    Loop
End With
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Tham khảo cách khác nhé (có 1 biến nếu bớt 1 ký tự thì VBA k cho phép, nên đành giữ nguyên, dù nội dung nó hơi nhạy cảm LOL :)) )
PHP:
Option Explicit
Sub test()
Dim i&, j&, k&, l&, m&, lr&, sum&, rng, Ass&, r As String
lr = Cells(Rows.Count, "A").End(xlUp).Row - 1
ReDim arr(1 To lr - 1, 1 To 1)
rng = Range("A2:A" & lr + 1).Value
Ass = Range("D2").Value
    For i = 1 To lr - 3
        sum = 0: r = ""
        If Sgn(Ass) = Sgn(rng(i, 1)) Then
                sum = rng(i, 1)
                r = "|" & i
                If Abs(sum) >= Abs(Ass) Then GoTo thoat
        End If
        For j = i + 1 To lr - 2
            If Sgn(Ass) = Sgn(rng(i, 1)) And Sgn(Ass) = Sgn(rng(j, 1)) Then
                sum = sum + rng(j, 1)
                r = r & "|" & j
                If Abs(sum) >= Abs(Ass) Then GoTo thoat
            End If
            For k = j + 1 To lr - 1
                If Sgn(Ass) = Sgn(rng(i, 1)) And Sgn(Ass) = Sgn(rng(k, 1)) Then
                    sum = sum + rng(k, 1)
                    r = r & "|" & k
                    If Abs(sum) >= Abs(Ass) Then GoTo thoat
                End If
                For l = k + 1 To lr
                    If Sgn(Ass) = Sgn(rng(i, 1)) And Sgn(Ass) = Sgn(rng(l, 1)) Then
                        sum = sum + rng(l, 1)
                        r = r & "|" & l
                        If Abs(sum) >= Abs(Ass) Then GoTo thoat
                    End If
                Next
            Next
        Next
    Next
thoat:
    Range("B2").Resize(lr, 1).ClearContents
    For m = 1 To lr
        If r & "|" Like "*|" & m & "|*" Then
            Cells(m + 1, 2).Value = m - 1
        End If
    Next
End Sub
 

File đính kèm

  • tìm tổng theo vị trí.xlsm
    17.2 KB · Đọc: 3
Upvote 0
Web KT

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

Back
Top Bottom