Tổng hợp theo điều kiện theo tiêu chí các mã số trong ngoặc (1 người xem)

Liên hệ QC

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

nguyenmanhnam

Thành viên tiêu biểu
Tham gia
24/7/10
Bài viết
434
Được thích
266
Em xin nhờ mọi người giúp em bài toán tổng hợp theo điều kiện là các mã số trong dấu ngoặc (các mã số thay đổi).

Tonghop.jpg






Vì trình độ có hạn, em chưa giải quyết được đều phải làm thủ công, rất mong mọi người giúp đỡ
 

File đính kèm

Em xin nhờ mọi người giúp em bài toán tổng hợp theo điều kiện là các mã số trong dấu ngoặc (các mã số thay đổi).

Tonghop.jpg






Vì trình độ có hạn, em chưa giải quyết được đều phải làm thủ công, rất mong mọi người giúp đỡ
Trong Excel cố gắng chọn kiẻu dữ liệu đơn giản để dễ tính toán, text là text mà number ra number, làm chi trong chuỗi có số cho khó khăn thêm.
Nếu chỉnh bảng dữ liệu lại như thế này thì "bi nhiêu ngang dọc" đều dễ dàng.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em xin nhờ mọi người giúp em bài toán tổng hợp theo điều kiện là các mã số trong dấu ngoặc (các mã số thay đổi).
Vì trình độ có hạn, em chưa giải quyết được đều phải làm thủ công, rất mong mọi người giúp đỡ
Dùng công thức này xem:
PHP:
=SUMPRODUCT((COUNTIF(D3,"*"&$A$3:$A$13&"*")*$B$3:$B$13))
 
Upvote 0
Nhưng báo cáo của bọn em phải theo mẫu, thực tế nó khoảng vài trăm dòng

Ví dụ: Chỉ tiêu A (11,12,15), các dòng dưới có thể là Chỉ tiêu B(11,13)..., Tổng hợp theo nhóm (11,12,13,14), ví dụ khi xếp yêu cầu thêm 14 vào chỉ tiêu A thì em chỉ việc đánh thêm thành Chỉ tiêu A (11,12,14, 15), tức là em muốn tránh dùng các cột phụ (không dùng thêm cột E:K) như bài của bác ah.

Em cũng muốn qua đây học hỏi bài toán tách số ra khỏi chữ tức là trong cụm từ Chỉ tiêu A (11,12,15) làm sao tách được ra 11,12,15và cộng số lượng theo các con số này.

Rất mong bác và mọi người giúp cho bằng VBA.
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn Ndu... mình vừa học thêm được một "độc chiêu" của Sumproduct() và Countif().
Chữ số lẫn lộn. Quái thật!

Công thức gọn thì có gọn nhưng vẫn tiềm ẩn sai sót nhé! (ví dụ trong list có số 12 lại vừa có số 121 chẳng hạn)
Nói chung: Nhập liệu không theo chuẩn thì phải chấp nhận rủi ro
 
Upvote 0
Công thức gọn thì có gọn nhưng vẫn tiềm ẩn sai sót nhé! (ví dụ trong list có số 12 lại vừa có số 121 chẳng hạn)
Nói chung: Nhập liệu không theo chuẩn thì phải chấp nhận rủi ro

Xin thày nói rõ hơn, vì em thử có vấn đề gì đâu, nếu có cả 12 và 121 thì nó cộng thêm cả số lượng của 121 vào mà.
 
Upvote 0
Xin thày nói rõ hơn, vì em thử có vấn đề gì đâu, nếu có cả 12 và 121 thì nó cộng thêm cả số lượng của 121 vào mà.

- Vùng A3:A13 bạn cho =11 tất, chừa lại A6 ta gõ số 12
- Xong, tính xem Chỉ tiêu A (121) nó ra bao nhiêu ---> Lý ra phải = 0 mới đúng
Ẹc... Ẹc...
 
Upvote 0
Thế thì gay quá thày nhỉ, có lẽ em sẽ nhập số liệu theo cách bác Ba Tê cho dễ làm.

Liệu có cách nào tối ưu trong việc bố trí dữ liệu đầu vào hơn không thày? (vì làm thế mỗi khi in em lại phải ẩn cột phụ đi)
 
Upvote 0
Thế thì gay quá thày nhỉ, có lẽ em sẽ nhập số liệu theo cách bác Ba Tê cho dễ làm.

Liệu có cách nào tối ưu trong việc bố trí dữ liệu đầu vào hơn không thày? (vì làm thế mỗi khi in em lại phải ẩn cột phụ đi)
TỐI ƯU là dùng VBA
Cái này quá dễ ---> Bài toán kiểm tra sự tồn tại ---> Dùng Dictionary
Ẹc... Ẹc...
 
Upvote 0
Trước kia đọc một số bài của thày về Dic, em biết chút ít về cách dùng của nó. Tuy vậy, trước khi làm cần tách các số ra riêng biệt, xin thày hộ em bài mẫu này với ah.
 
Upvote 0
Trước kia đọc một số bài của thày về Dic, em biết chút ít về cách dùng của nó. Tuy vậy, trước khi làm cần tách các số ra riêng biệt, xin thày hộ em bài mẫu này với ah.
- Chuổi Chỉ tiêu A (12,11) gì gì đó, ta sẽ tách ra, lấy từ sau dấu "(" đến trước dấu ")" (cái này công thức cũng làm được)
- Xong, dùng Split, cho chuổi vừa cắt ở trên vào 1 mảng ( Split(chuoi, ",") )
- Duyệt qua các phần tử trong chuổi, cho vào Dictionary
- Duyệt qua các cell trong vùng A3:A13 ---> giá trị nào có tồn tại trong Dic thì cộng dòng giá trị B của dòng tương ứng
Thế thôi
Mời các đồng chí đang nghiên cứu về mảng ra tay nhé
Ẹc... Ẹc...
 
Upvote 0
Một phương án tối....thui như đêm 30 đây
Mã:
Public Function Tong(Vung, Cll)
    Dim Tach, d, Mg, I, CoRe, Kq
    Set d = CreateObject("scripting.dictionary")
    Set CoRe = CreateObject("VBScript.RegExp"):           Mg = Vung.Value
        For I = 1 To Vung.Rows.Count
            If Not d.exists(Mg(I, 1)) Then
                d.Add Mg(I, 1), Mg(I, 2)
            Else
                d.Item(Mg(I, 1)) = d.Item(Mg(I, 1)) + Mg(I, 2)
            End If
        Next I
            With CoRe
                .Global = True
                .Pattern = "[^0-9,,]"
                Tach = .Replace(Cll, "")
            End With
                Tach = Split(Tach, ",")
                    For I = LBound(Tach) To UBound(Tach)
                        Kq = Kq + d.Item(Val(Tach(I)))
                    Next I
    Tong = Kq
End Function
Lâu lâu ôn bài không thôi quên hết. Hihi
 

File đính kèm

Upvote 0
Mình cũng tham gian cho vui nhà vui cửa coi, chơi 3,4 vòng lặp cho máy chết luôn!!!!
PHP:
Sub tong()
Dim data, dic As Object, iRow As Long, i As Long, item, VungDL, KQ, KQEnd As Long
Set dic = CreateObject("Scripting.Dictionary")
data = Split(Mid(Replace(Range("D3").Value, "...)", ""), InStr(Range("D3").Value, "(") + 1, 100), ",")
With Sheet1
VungDL = .Range("A3:B13").Value

ReDim KQ(1 To UBound(VungDL, 1), 1 To 2)
For iRow = 1 To UBound(VungDL, 1)
    If Not dic.exists(VungDL(iRow, 1)) Then
        i = i + 1
        dic.item(VungDL(iRow, 1)) = i
        KQ(i, 1) = VungDL(iRow, 1)
        KQ(i, 2) = VungDL(iRow, 2)
    Else
        KQ(dic.item(VungDL(iRow, 1)), 2) = KQ(dic.item(VungDL(iRow, 1)), 2) + VungDL(iRow, 2)
    End If
Next
For iRow = 1 To i
    For Each item In data
        If CDbl(item) = KQ(iRow, 1) Then
            KQEnd = KQEnd + KQ(iRow, 2)
        End If
    Next
Next
.Range("E3").Value = KQEnd
End With
End Sub
 

File đính kèm

Upvote 0
Hai cái * ở đầu và ở cuối có tác dụng gì thế? mà khi em bỏ chúng đi thì các phần tử 1 trong mảng COUNTIF(D3,"*"&$A$3:$A$13&"*") khi ấn F9 nó biến hết thành số 0 (những số 1 chuyển về số 0)

PHP:
=SUMPRODUCT((COUNTIF(D3,"*"&$A$3:$A$13&"*")*$B$3:$B$13))
 
Upvote 0
Trong Code của thày Concogia, Dic thì em biết nhưng cái CoRe = CreateObject("VBScript.RegExp") nó là cái gì vậy?

PHP:
Public Function Tong(Vung, Cll)
    Dim Tach, d, Mg, I, CoRe, Kq
    Set d = CreateObject("scripting.dictionary")
    Set CoRe = CreateObject("VBScript.RegExp"):           Mg = Vung.Value
        For I = 1 To Vung.Rows.Count
            If Not d.exists(Mg(I, 1)) Then
                d.Add Mg(I, 1), Mg(I, 2)
            Else
                d.Item(Mg(I, 1)) = d.Item(Mg(I, 1)) + Mg(I, 2)
            End If
        Next I
            With CoRe
                .Global = True
                .Pattern = "[^0-9,,]"
                Tach = .Replace(Cll, "")
            End With
                Tach = Split(Tach, ",")
                    For I = LBound(Tach) To UBound(Tach)
                        Kq = Kq + d.Item(Val(Tach(I)))
                    Next I
    Tong = Kq
End Function
 
Upvote 0
Trong Code của thày Concogia, Dic thì em biết nhưng cái CoRe = CreateObject("VBScript.RegExp") nó là cái gì vậy?

PHP:
Public Function Tong(Vung, Cll)
    Dim Tach, d, Mg, I, CoRe, Kq
    Set d = CreateObject("scripting.dictionary")
    Set CoRe = CreateObject("VBScript.RegExp"):           Mg = Vung.Value
        For I = 1 To Vung.Rows.Count
            If Not d.exists(Mg(I, 1)) Then
                d.Add Mg(I, 1), Mg(I, 2)
            Else
                d.Item(Mg(I, 1)) = d.Item(Mg(I, 1)) + Mg(I, 2)
            End If
        Next I
            With CoRe
                .Global = True
                .Pattern = "[^0-9,,]"
                Tach = .Replace(Cll, "")
            End With
                Tach = Split(Tach, ",")
                    For I = LBound(Tach) To UBound(Tach)
                        Kq = Kq + d.Item(Val(Tach(I)))
                    Next I
    Tong = Kq
End Function
Cái biến tên CoRe là chữghép với 2 chữ đầu của RegExp chứ có gì đâu, còn cái CreateObject("VBScript.RegExp") bạn thử thì từ từ "ngâm cú" nó cho vui chứ giải thích cái này hơi "mơ huyền.....hồ", thí dụ, đọc cái này xong hổng biết bạn có hiểu hông chứ mình.....chẳng hiểu mô tê gì ráo
Một biểu thức RegExp ( chúng ta tạm gọi là biểu thức so mẫu hay biểu thức tìm kiếm) được dùng nhiều trong việc tìm kiếm và xử lí chuỗi.
RegExp Là Gì ?
RegExp có thể hiểu đơn giản là một biểu thức chính qui.
Khi bạn muốn tìm kiếm trong một chuỗi kí tự bạn phải dùng các "mẫu giải thích" để thực hiện việc tìm kiếm. RegExp là một cách viết các "mẫu" đó.
Một "mẫu" đơn giản nhất là một kí tự chẳng hạn : a
Một "mẫu" hoàn chỉnh và đầy đủ sẽ đòi hỏi bao gồm nhiều kí tự ,các kí hiệu thay thế sắp xếp theo một công thức đúng ...
Với các "mẫu" được viết ra bạn có thể dùng nó để xác định và tìm kiếm các vị trí trong một chuỗi và nhiều công việc khác nữa ...
Híc+-+-+-+:=\+
 
Upvote 0
Em vẫn còn dốt lắm chưa hiểu được các cụm từ sau
PHP:
.Global = True
                .Pattern = "[^0-9,,]"
.Global,Pattern là thuộc tính gì hả thày?

còn cái Dấu mũ (^) nữa, (lũy thừa chăng?) chắc là không phải).

Các thày giải thích giúp em với.
 
Upvote 0
Em vẫn còn dốt lắm chưa hiểu được các cụm từ sau
PHP:
.Global = True
                .Pattern = "[^0-9,,]"
.Global,Pattern là thuộc tính gì hả thày?

còn cái Dấu mũ (^) nữa, (lũy thừa chăng?) chắc là không phải).

Các thày giải thích giúp em với.
Huhu, mình cũng chỉ tự mò mẫm học nên.......... giải thích .....đại nhé, hông hiểu cũng chịu thôi
code chạy hết dữ liệu trong Cll tìm thằng nào thỏa điều kiện thì thay, nếu
thì nó chạy tới chỗ đầu tiên thỏa điều kiện thì thay thế, thay xong nó nghỉ luôn, hổng đi kiếm tiếp
còn cái Dấu mũ (^) nữa, (lũy thừa chăng?) chắc là không phải).
Cái này lấy câu hỏi của bạn, xóa khúc giữa, thành câu trả lời cho bạn. Ngộ. Híc
Nôm na thì thằng này giống như điều kiện để thay thế (còn cú pháp nó thì cực kỳ "dzắc dzối", phải mò mẫm lâu lắm), như trong bài của bạn tìm trong Cll thằng nào hổng phải số & "," thì thay nó bằng ""
+-+-+-++-+-+-++-+-+-+
 
Upvote 0
Xin thày cho hỏi nếu lọc Text thì ^0-9,, nó sẽ được thay là gì? Tức em muốn hỏi một số đối tượng hay dùng nằm trong cái ngoặc [ ]ý mà.
Nói chung là nên học để biết từ cơ bản... Mấy cái "trò" này là VBScript ---> Tặng bạn file này về tự nghiên cứu nhé
Còn riêng phần thắc mắc ở trên (^0-9) bạn có thể mở file đính kèm, chuyển sang tab Search, gõ từ khóa Pattern vào sẽ có câu trả lời
-------------------
Ứng dụng của nó là topic này:
http://www.giaiphapexcel.com/forum/showthread.php?16983-Tách-số-không-dùng-vòng-lặp
 

File đính kèm

Upvote 0
Thưa thày, trong công thức =SUMPRODUCT((COUNTIF(D3,"*"&$A$3:$A$13&"*")*$B$3:$B$13)) có dấu * có phải để "dẹp bỏ" toàn bộ các chữ trong các ô A1:A3 vì khi có hai dấu * chặn đầu và cuối thì nó thay thế cho mọi ký tự chữ, chỉ quan tâm đến số thôi?

Hình như cũng chưa hẳn đúng, vì:


VD: tại sao tìm 121 mà dãy $A$3:$A$13 có 12 thôi nhưng Countif nó cũng ra kết quả là 1 được nhỉ?


(>>Ký tự * thay thế cho một chuỗi các ký tự ?)
 
Lần chỉnh sửa cuối:
Upvote 0
Global,Pattern là thuộc tính gì hả thày?

còn cái Dấu mũ (^) nữa, (lũy thừa chăng?) chắc là không phải).

Các thày giải thích giúp em với.

Tôi mới học như bạn thôi, tôi hiểu đến đâu nói đến đó nhé, nếu sai nhờ các thày chỉ thêm:

1. Global = True tức nếu tìm thấy thì lọc ra.

2. Theo như tôi hiểu Pattern nó có các sự lựa chọn tựa như chức năng AutoFilter trong Excel , ví dụ như:
\W: Lọc riêng tất cả các ký tự là chữ thông thường (lọc tất cả các ký tự thông thường hay gõ văn bản ra)
\w: Lọc ra tất cả ký tự đặc biệt.
[0-9] <=> \d: lọc ra tất cả những kí tự không phải là số
[^0-9]: Chỉ lọc ra các con số.
[a-z] lọc ra những ký tự không phải là chữ (số, kí tự đặc biệt khác...)
[^a-z] ngược lại chỉ lọc ra chữ thôi (có ^ nghĩa là ngược lại).

…..
Các ký tự bình thường khác bạn chỉ muốn lọc ra riêng lẻ theo ý muốn thì thêm ký tự đó vào "\..." hoặc "[^...]", nếu có nhiều ký tự cần lọc thì các ký tự cách nhau dấu phảy (,). Ví dụ .Pattern= "\a" tức là chỉ lọc riêng a thôi (Cái này thì tôi không chắc lắm vì tôi thí nghiệm thấy đúng trong 1 số trường hợp thử).
 
Lần chỉnh sửa cuối:
Upvote 0
Em thấy VBScript.RegExp rât tuyệt vời trong việc tách, em chưa có nhiều kinh nghiệm lắm nhưng không biết nó có thể áp dụng trong một số trường hợp khác không?

Ví dụ:

ô A1 có nội dung là Bê tông dầm D3: 2*(1+6) làm sao mà nó chỉ tính các số sau dấu : có được không ah, hay là phải quay về vòng lặp?

Kết quả: Tức B1=Tach(A1)=14
 
Upvote 0
Em thấy VBScript.RegExp rât tuyệt vời trong việc tách, em chưa có nhiều kinh nghiệm lắm nhưng không biết nó có thể áp dụng trong một số trường hợp khác không?

Ví dụ:

ô A1 có nội dung là Bê tông dầm D3: 2*(1+6) làm sao mà nó chỉ tính các số sau dấu : có được không ah, hay là phải quay về vòng lặp?

Kết quả: Tức B1=Tach(A1)=14

Thì bạn tách lấy từ sau dấu 2 chấm, ra được kết quả thì cho vào xử lý thôi
Ví dụ:
PHP:
Function ValExp(ByVal Exp As String) As Double
  Dim tmp As String
  On Error Resume Next
  tmp = Mid(Exp, InStr(Exp, ":") + 1, Len(Exp))
  With CreateObject("VBScript.RegExp")
    .Global = True: .Pattern = "[^0-9 + - * / . ( )]"
    ValExp = Evaluate(.Replace(tmp, ""))
  End With
End Function
 
Upvote 0
Em thấy VBScript.RegExp rât tuyệt vời trong việc tách, em chưa có nhiều kinh nghiệm lắm nhưng không biết nó có thể áp dụng trong một số trường hợp khác không?

Ví dụ:

ô A1 có nội dung là Bê tông dầm D3: 2*(1+6) làm sao mà nó chỉ tính các số sau dấu : có được không ah, hay là phải quay về vòng lặp?

Kết quả: Tức B1=Tach(A1)=14
Mình có thể dùng cách này mình chưa viết Function, bạn có thể dựa vào mà viết Function
Với A1 là dữ liệu của bạn
PHP:
Sub test()
With CreateObject("VBScript.RegExp")
    .Global = True:    .Pattern = "(.*):"
Range("b1").Value = Evaluate(.Replace(Range("a1").Value, ""))
End With
End Sub
 
Upvote 0

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

Back
Top Bottom