em có một file excel, nhờ anh chị tính tổng dùm em với ạ

Liên hệ QC
Bạn mới là người ngây thơ.
Người ta phải tung hoả mù trước để quý vị không nhận ra loại báo cáo.
Điển hình, cuối kỳ có con số hàng bán bị nổi lên (nổi = tồn kho trên giấy tờ - tồn kho thực tế). Bi giờ bài toán là viết một mớ biên lai thanh toán con số nổi này.
không phải nha bạn, t chỉ làm nhập xuất bình thường thôi, t không làm được nên mới nhờ á
 
Phần tô màu xanh giữ nguyên, gia trị cần tìm thay đổi tại E2.

Sau khi chạy, trong vùng C2:C21, giá trị nào = 1 -> lấy giá trị cột A tại dòng đó.
thanks anh nhiều nha !
Bài đã được tự động gộp:

Bạn thử tải file về coi xài được không. Chắc có thể sẽ còn phát sinh linh tinh. Hy vọng giúp được ít nhiều cho bạn
Nhớ tìm cách enable macros nhé
em chọn 700 thì nó chỉ tô vàng 600,còn chọn 800 thì tô vàng 700,nhờ anh chỉnh sửa dùm với ạ
 

File đính kèm

  • image_2021_05_17T12_48_08_667Z.png
    image_2021_05_17T12_48_08_667Z.png
    236.2 KB · Đọc: 11
Lần chỉnh sửa cuối:
thanks anh nhiều nha !
Bài đã được tự động gộp:


em chọn 700 thì nó chỉ tô vàng 600,còn chọn 800 thì tô vàng 700,nhờ anh chỉnh sửa dùm với ạ
Mình biết nguyên nhân tại sao rồi, vì có 2 số 100 nên bị như vậy. Khi nào mình ngồi máy tính sẽ gợi ý giải pháp cho bạn. Chắc đến cuối tuần mình mới về văn phòng. Mong có ai đó sửa dùm
 
@chi ngan nguyen
Thử sửa code bài 14, dùng thử

Mã:
Option Explicit
Dim MgNguon(), MgKQ()

Sub A_KiemTra()
Dim k As Long, KQi() As Double, Cot As Long, n As Long, Tong As Double, Item, Tim As Range
Tong = [C1].Value
MgNguon = Range("A2", Range("A" & Rows.Count).End(3)).Value
Range("A2", Range("A" & Rows.Count).End(3)).Interior.ColorIndex = xlNone
n = UBound(MgNguon, 1)
ReDim MgKQ(1 To n, 1 To 1)
   For k = 1 To n
      ReDim KQi(1 To k, 1 To 1) As Double
      Main k, KQi, 0, 1, 1, Cot, n, Tong
      If Cot Then
         Dim i, j
       
         k = 2
         For i = 1 To n
            If MgKQ(i, 1) = "" Or k > Range("A" & Rows.Count).End(3).Row Then Exit For
            Item = MgKQ(i, 1)
            For j = k To Range("A" & Rows.Count).End(3).Row
                If Range("A" & j) = Item Then
                    Range("A" & j).Interior.ColorIndex = 3
                    k = j + 1
                    Exit For
                End If
            Next j
        Next i
      End If
   Next
Erase MgNguon:  Erase MgKQ
End Sub

Mã:
Sub Main(k As Long, KQi, CongDon As Double, PhanTu As Long, SoDem As Long, Cot As Long, n As Long, Tong As Double)
Dim i As Long, j As Long
If Cot Then Exit Sub
If SoDem <= k Then
   For j = PhanTu To n - k + SoDem
      KQi(SoDem, 1) = MgNguon(j, 1)
      Main k, KQi, CongDon + KQi(SoDem, 1), j + 1, SoDem + 1, Cot, n, Tong
   Next j
Else
   If CongDon = Tong Then
      Cot = Cot + 1
      ReDim Preserve MgKQ(1 To n, 1 To Cot)
      For i = 1 To k
         MgKQ(i, Cot) = KQi(i, 1)
      Next
   End If
End If
End Sub
 

File đính kèm

@chi ngan nguyen
Thử sửa code bài 14, dùng thử

Mã:
Option Explicit
Dim MgNguon(), MgKQ()

Sub A_KiemTra()
Dim k As Long, KQi() As Double, Cot As Long, n As Long, Tong As Double, Item, Tim As Range
Tong = [C1].Value
MgNguon = Range("A2", Range("A" & Rows.Count).End(3)).Value
Range("A2", Range("A" & Rows.Count).End(3)).Interior.ColorIndex = xlNone
n = UBound(MgNguon, 1)
ReDim MgKQ(1 To n, 1 To 1)
   For k = 1 To n
      ReDim KQi(1 To k, 1 To 1) As Double
      Main k, KQi, 0, 1, 1, Cot, n, Tong
      If Cot Then
         Dim i, j
      
         k = 2
         For i = 1 To n
            If MgKQ(i, 1) = "" Or k > Range("A" & Rows.Count).End(3).Row Then Exit For
            Item = MgKQ(i, 1)
            For j = k To Range("A" & Rows.Count).End(3).Row
                If Range("A" & j) = Item Then
                    Range("A" & j).Interior.ColorIndex = 3
                    k = j + 1
                    Exit For
                End If
            Next j
        Next i
      End If
   Next
Erase MgNguon:  Erase MgKQ
End Sub

Mã:
Sub Main(k As Long, KQi, CongDon As Double, PhanTu As Long, SoDem As Long, Cot As Long, n As Long, Tong As Double)
Dim i As Long, j As Long
If Cot Then Exit Sub
If SoDem <= k Then
   For j = PhanTu To n - k + SoDem
      KQi(SoDem, 1) = MgNguon(j, 1)
      Main k, KQi, CongDon + KQi(SoDem, 1), j + 1, SoDem + 1, Cot, n, Tong
   Next j
Else
   If CongDon = Tong Then
      Cot = Cot + 1
      ReDim Preserve MgKQ(1 To n, 1 To Cot)
      For i = 1 To k
         MgKQ(i, Cot) = KQi(i, 1)
      Next
   End If
End If
End Sub
Những dạng nầy không dể nuốt, lúc đầu chỉ tìm 1 số, sẽ tìm tiếp số thứ 2, 3 ...
 

File đính kèm

Những dạng nầy không dể nuốt, lúc đầu chỉ tìm 1 số, sẽ tìm tiếp số thứ 2, 3 ...
Không hiểu ý bác lắm.

Code trên sửa lại muốn giũ nguyên ý code cũ, chỉ thay đổi cách hiển thị xuống sheet.
Nếu là tự làm sẽ thêm "exit for" trong cái "if cot ...end" để hiển thị chỉ 1 kết quả
 
@chi ngan nguyen
Thử sửa code bài 14, dùng thử

Mã:
Option Explicit
Dim MgNguon(), MgKQ()

Sub A_KiemTra()
Dim k As Long, KQi() As Double, Cot As Long, n As Long, Tong As Double, Item, Tim As Range
Tong = [C1].Value
MgNguon = Range("A2", Range("A" & Rows.Count).End(3)).Value
Range("A2", Range("A" & Rows.Count).End(3)).Interior.ColorIndex = xlNone
n = UBound(MgNguon, 1)
ReDim MgKQ(1 To n, 1 To 1)
   For k = 1 To n
      ReDim KQi(1 To k, 1 To 1) As Double
      Main k, KQi, 0, 1, 1, Cot, n, Tong
      If Cot Then
         Dim i, j
      
         k = 2
         For i = 1 To n
            If MgKQ(i, 1) = "" Or k > Range("A" & Rows.Count).End(3).Row Then Exit For
            Item = MgKQ(i, 1)
            For j = k To Range("A" & Rows.Count).End(3).Row
                If Range("A" & j) = Item Then
                    Range("A" & j).Interior.ColorIndex = 3
                    k = j + 1
                    Exit For
                End If
            Next j
        Next i
      End If
   Next
Erase MgNguon:  Erase MgKQ
End Sub

Mã:
Sub Main(k As Long, KQi, CongDon As Double, PhanTu As Long, SoDem As Long, Cot As Long, n As Long, Tong As Double)
Dim i As Long, j As Long
If Cot Then Exit Sub
If SoDem <= k Then
   For j = PhanTu To n - k + SoDem
      KQi(SoDem, 1) = MgNguon(j, 1)
      Main k, KQi, CongDon + KQi(SoDem, 1), j + 1, SoDem + 1, Cot, n, Tong
   Next j
Else
   If CongDon = Tong Then
      Cot = Cot + 1
      ReDim Preserve MgKQ(1 To n, 1 To Cot)
      For i = 1 To k
         MgKQ(i, Cot) = KQi(i, 1)
      Next
   End If
End If
End Sub
thanks bạn nhiều nha
 
@ Thớt
Thêm lệnh thoát vòng lặp, kiểm tra lại xem sao
Mã:
Option Explicit
Dim MgNguon(), MgKQ()

Sub A_KiemTra()
Dim k As Long, KQi() As Double, Cot As Long, n As Long, Tong As Double, Item, Tim As Range
Tong = [C1].Value
MgNguon = Range("A2", Range("A" & Rows.Count).End(3)).Value
Range("A2", Range("A" & Rows.Count).End(3)).Interior.ColorIndex = xlNone
n = UBound(MgNguon, 1)
ReDim MgKQ(1 To n, 1 To 1)
   For k = 1 To n
      ReDim KQi(1 To k, 1 To 1) As Double
      Main k, KQi, 0, 1, 1, Cot, n, Tong
      If Cot Then
         Dim i, j
        
         k = 2
         For i = 1 To n
            If MgKQ(i, 1) = "" Or k > Range("A" & Rows.Count).End(3).Row Then Exit For
            Item = MgKQ(i, 1)
            For j = k To Range("A" & Rows.Count).End(3).Row
                If Range("A" & j) = Item Then
                    Range("A" & j).Interior.ColorIndex = 3
                    k = j + 1
                    Exit For
                End If
            Next j
        Next i
        
        Exit For '<-----------------
        
      End If
   Next
Erase MgNguon:  Erase MgKQ
End Sub

Sub Main(k As Long, KQi, CongDon As Double, PhanTu As Long, SoDem As Long, Cot As Long, n As Long, Tong As Double)
Dim i As Long, j As Long
If Cot Then Exit Sub
If SoDem <= k Then
   For j = PhanTu To n - k + SoDem
      KQi(SoDem, 1) = MgNguon(j, 1)
      Main k, KQi, CongDon + KQi(SoDem, 1), j + 1, SoDem + 1, Cot, n, Tong
   Next j
Else
   If CongDon = Tong Then
      Cot = Cot + 1
      ReDim Preserve MgKQ(1 To n, 1 To Cot)
      For i = 1 To k
         MgKQ(i, Cot) = KQi(i, 1)
      Next
   End If
End If
End Sub
 

File đính kèm

@ Thớt
Thêm lệnh thoát vòng lặp, kiểm tra lại xem sao
Mã:
Option Explicit
Dim MgNguon(), MgKQ()

Sub A_KiemTra()
Dim k As Long, KQi() As Double, Cot As Long, n As Long, Tong As Double, Item, Tim As Range
Tong = [C1].Value
MgNguon = Range("A2", Range("A" & Rows.Count).End(3)).Value
Range("A2", Range("A" & Rows.Count).End(3)).Interior.ColorIndex = xlNone
n = UBound(MgNguon, 1)
ReDim MgKQ(1 To n, 1 To 1)
   For k = 1 To n
      ReDim KQi(1 To k, 1 To 1) As Double
      Main k, KQi, 0, 1, 1, Cot, n, Tong
      If Cot Then
         Dim i, j
       
         k = 2
         For i = 1 To n
            If MgKQ(i, 1) = "" Or k > Range("A" & Rows.Count).End(3).Row Then Exit For
            Item = MgKQ(i, 1)
            For j = k To Range("A" & Rows.Count).End(3).Row
                If Range("A" & j) = Item Then
                    Range("A" & j).Interior.ColorIndex = 3
                    k = j + 1
                    Exit For
                End If
            Next j
        Next i
       
        Exit For '<-----------------
       
      End If
   Next
Erase MgNguon:  Erase MgKQ
End Sub

Sub Main(k As Long, KQi, CongDon As Double, PhanTu As Long, SoDem As Long, Cot As Long, n As Long, Tong As Double)
Dim i As Long, j As Long
If Cot Then Exit Sub
If SoDem <= k Then
   For j = PhanTu To n - k + SoDem
      KQi(SoDem, 1) = MgNguon(j, 1)
      Main k, KQi, CongDon + KQi(SoDem, 1), j + 1, SoDem + 1, Cot, n, Tong
   Next j
Else
   If CongDon = Tong Then
      Cot = Cot + 1
      ReDim Preserve MgKQ(1 To n, 1 To Cot)
      For i = 1 To k
         MgKQ(i, Cot) = KQi(i, 1)
      Next
   End If
End If
End Sub
Nếu tìm không có số lượng cần lấy thì máy cũng vẫn quay vòng không thoát được nha bạn, nhờ bạn vô sửa thêm với ạ
 

File đính kèm

  • image_2021_05_18T08_44_02_804Z.png
    image_2021_05_18T08_44_02_804Z.png
    52.6 KB · Đọc: 7
@ Thớt
Thêm lệnh thoát vòng lặp, kiểm tra lại xem sao
Mã:
Option Explicit
Dim MgNguon(), MgKQ()

Sub A_KiemTra()
Dim k As Long, KQi() As Double, Cot As Long, n As Long, Tong As Double, Item, Tim As Range
Tong = [C1].Value
MgNguon = Range("A2", Range("A" & Rows.Count).End(3)).Value
Range("A2", Range("A" & Rows.Count).End(3)).Interior.ColorIndex = xlNone
n = UBound(MgNguon, 1)
ReDim MgKQ(1 To n, 1 To 1)
   For k = 1 To n
      ReDim KQi(1 To k, 1 To 1) As Double
      Main k, KQi, 0, 1, 1, Cot, n, Tong
      If Cot Then
         Dim i, j
       
         k = 2
         For i = 1 To n
            If MgKQ(i, 1) = "" Or k > Range("A" & Rows.Count).End(3).Row Then Exit For
            Item = MgKQ(i, 1)
            For j = k To Range("A" & Rows.Count).End(3).Row
                If Range("A" & j) = Item Then
                    Range("A" & j).Interior.ColorIndex = 3
                    k = j + 1
                    Exit For
                End If
            Next j
        Next i
       
        Exit For '<-----------------
       
      End If
   Next
Erase MgNguon:  Erase MgKQ
End Sub

Sub Main(k As Long, KQi, CongDon As Double, PhanTu As Long, SoDem As Long, Cot As Long, n As Long, Tong As Double)
Dim i As Long, j As Long
If Cot Then Exit Sub
If SoDem <= k Then
   For j = PhanTu To n - k + SoDem
      KQi(SoDem, 1) = MgNguon(j, 1)
      Main k, KQi, CongDon + KQi(SoDem, 1), j + 1, SoDem + 1, Cot, n, Tong
   Next j
Else
   If CongDon = Tong Then
      Cot = Cot + 1
      ReDim Preserve MgKQ(1 To n, 1 To Cot)
      For i = 1 To k
         MgKQ(i, Cot) = KQi(i, 1)
      Next
   End If
End If
End Sub
Mình thấy dòng lệnh này chạy được rồi nhưng với tìm tổng nhỏ hơn 1000 và dãy số không quá 20 dòng, mình test thử tìm tổng trên 2000 và dãy số là 40 dòng là chạy 5 phút không ra kết quả.
 
Nếu tìm không có số lượng cần lấy thì máy cũng vẫn quay vòng không thoát được nha bạn, nhờ bạn vô sửa thêm với ạ
Dữ liệu nhiều quá sẽ đứng máy
Mã:
Function SumFind(Total As Double, ParamArray RngS() As Variant) As String
  Dim Data(), Cll As Range, Arr(), tmp, tSum As Double
  Dim i As Long, n As Long, k As Long
 
  For i = LBound(RngS) To UBound(RngS)
    For Each Cll In RngS(i)
      tmp = Val(Cll.Value)
      If tmp <> 0 Then
        If tmp = Total Then
          SumF1 = Cll.Address(0, 0): Exit Function
        Else
          n = n + 1
          ReDim Preserve Data(1 To 2, 1 To n)
          Data(1, n) = Val(Cll.Value):  Data(2, n) = Cll.Address(1, 0)
        End If
      End If
    Next
  Next
  Call QuickSort(Data)
  ReDim Arr(1 To n)
  Arr(1) = 1:     tSum = Data(1, 1)
  n = 1:          k = 1
  Do While Total <> tSum
    If Arr(1) = UBound(Data, 2) Then
      SumF1 = "#N/A":        Exit Function
    End If
    If tSum > Total Then
      k = Arr(n - 1) + 1
      tSum = tSum - Data(1, Arr(n)) - Data(1, Arr(n - 1)) + Data(1, k)
      n = n - 1
      Arr(n) = k
    Else
      If k = UBound(Data, 2) Then
        k = Arr(n - 1) + 1
        tSum = tSum - Data(1, Arr(n)) - Data(1, Arr(n - 1)) + Data(1, k)
        n = n - 1
        Arr(n) = k
      Else
        k = k + 1
        tSum = tSum + Data(1, k)
        n = n + 1
        Arr(n) = k
      End If
    End If
  Loop
  SumFind = GetRes(Data, Arr, n)
End Function

Private Sub QuickSort(Data)
  Dim oSList As Object, sArr, S
  Dim j As Long, k As Long, jk As Long, m As Long

  Set oSList = CreateObject("System.Collections.SortedList")
  For j = LBound(Data, 2) To UBound(Data, 2)
    oSList.Item(Data(1, j)) = oSList.Item(Data(1, j)) & "," & j
  Next j
  sArr = Data
  For j = 0 To oSList.Count - 1
    S = Split(oSList.GetByIndex(j), ",")
    For m = 1 To UBound(S)
      jk = CLng(S(m))
        k = k + 1
        Data(1, k) = sArr(1, jk): Data(2, k) = sArr(2, jk)
    Next m
  Next j
  Set oSList = Nothing
End Sub

Private Function GetRes(Data, Arr, n) As String
  Dim oSList As Object, sArr, S, iKey, tmp
  Dim j As Long, k As Long, jk As Long, m As Long

  Set oSList = CreateObject("System.Collections.SortedList")
  For j = 1 To n
    tmp = CLng(Split(Data(2, Arr(j)), "$")(1))
    oSList.Item(tmp) = oSList.Item(tmp) & "," & j
  Next j
  tmp = Empty
  For j = 0 To oSList.Count - 1
    S = Split(oSList.GetByIndex(j), ",")
    For m = 1 To UBound(S)
      jk = CLng(S(m))
      tmp = tmp & "+" & Data(2, Arr(jk))
    Next m
  Next j
  tmp = Replace(tmp, "$", "")
  GetRes = "=" & Mid(tmp, 2, Len(tmp) - 1)
  Set oSList = Nothing
End Function
Công thức trong file
Mã:
C4 =SumFind(C1,A2:A21)
 

File đính kèm

Đây là bài toán tìm tổng con (subset sum). Mình cũng viết mấy bài ở GPE tìm tổng con bằng quy hoạch động dùng VBA (vì mình cũng thỉnh thoảng phải "bốc thuốc"): với n số nguyên dương cho trước, tìm bộ số có tổng = S, bài toán này có khi không giải nổi nếu n và s lớn. Nếu n nhỏ khoảng vài chục thì dùng đệ quy cho dễ viết code, độ phức tạp phụ thuộc vào n. Nếu n cao hơn thì dùng đệ quy dễ tràn stack, lúc này nên dùng quy hoạch động và độ phức tạp phụ thuộc cả vào n và s.
@chi ngan nguyen bạn nên đưa dữ liệu gần giống thực lên, lúc đấy mọi người sẽ có code phù hợp.
Ví dụ code bài của mình ở link dưới, dữ liệu cần được sort tăng dần trước khi chạy, bạn thử xem chạy được không, nếu dữ liệu lớn hơn thì bạn cứ báo, mình sẽ đưa công cụ khác.
 
mình vẫn chưa hiểu file này luôn bạn à, bạn nói lại cho mình đi.
bài này dùng solver để giải, bạn tìm với từ khóa solver trên diễn đàn xem.
Bài đã được tự động gộp:

Mình thấy dòng lệnh này chạy được rồi nhưng với tìm tổng nhỏ hơn 1000 và dãy số không quá 20 dòng, mình test thử tìm tổng trên 2000 và dãy số là 40 dòng là chạy 5 phút không ra kết quả.
Bân thử với file bài 16 xem sao, số dòng <=200
 
Web KT

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

Back
Top Bottom