Phân nhóm các ô có tổng thoả mãn điều kiện

Liên hệ QC

tinya1225

Thành viên mới
Tham gia
18/4/13
Bài viết
8
Được thích
6
Em xin kính chào các bác,

Em muốn hỏi/nhờ các bác chỉ dẫn/làm giúp để giải quyết vấn đề như sau:

1. Trong file đính kèm của em, em muốn phân nhóm các ô có tổng ở cột "LENGTH" nằm giữa giá trị nhỏ nhất (1800) và giá trị lớn nhất (2000);
2. Nhóm các ô đó được điền vào cột "GROUP" ở bên cạnh, các ô cùng nhóm sẽ có cùng giá trị;
3. Và tất nhiên một ô chỉ xuất hiện trong 1 nhóm duy nhất.

Em xin chân thành cảm ơn và chúc các bác 1 ngày làm việc hiệu quả :)
 

File đính kèm

Em xin kính chào các bác,

Em muốn hỏi/nhờ các bác chỉ dẫn/làm giúp để giải quyết vấn đề như sau:

1. Trong file đính kèm của em, em muốn phân nhóm các ô có tổng ở cột "LENGTH" nằm giữa giá trị nhỏ nhất (1800) và giá trị lớn nhất (2000);
2. Nhóm các ô đó được điền vào cột "GROUP" ở bên cạnh, các ô cùng nhóm sẽ có cùng giá trị;
3. Và tất nhiên một ô chỉ xuất hiện trong 1 nhóm duy nhất.

Em xin chân thành cảm ơn và chúc các bác 1 ngày làm việc hiệu quả :)
Bạn làm một ví dụ cụ thể là điền kết quả mong muốn như thế nào được không?
 
Đây có phải bài toàn tìm phương án cắt vật liệu tối ưu không?
Thanh nguyên liệu có chiều dài tiêu chuẩn 2000 (mm?), cắt thành các đoạn theo danh sách cho trước sao cho tốn ít thanh nguyên liệu nhất?
 
Đây có phải bài toàn tìm phương án cắt vật liệu tối ưu không?
Thanh nguyên liệu có chiều dài tiêu chuẩn 2000 (mm?), cắt thành các đoạn theo danh sách cho trước sao cho tốn ít thanh nguyên liệu nhất?
Vâng cũng gần là như vậy bác ạ.
Bài đã được tự động gộp:

Bạn làm một ví dụ cụ thể là điền kết quả mong muốn như thế nào được không?
Vâng bác,
Ví dụ: tổng 13 ô đầu là 1774<1800, vẫn tiếp tục cộng. Ô 14 là 364, nếu cộng vào thì >2000 nên sẽ bỏ qua ô 14. Cộng thêm ô 15, 16 thì tổng 1839. Thoả mãn >1800, <2000 thì dừng lại, kết thúc Nhóm 1. Nhóm 2 bắt đầu lại từ đầu, trừ những ô đã trong nhóm 1.
 
Lần chỉnh sửa cuối:
Vâng cũng gần là như vậy bác ạ.
Bài đã được tự động gộp:


Vâng bác,
Ví dụ: tổng 13 ô đầu là 1774<1800, vẫn tiếp tục cộng. Ô 14 là 364, nếu cộng vào thì >2000 nên sẽ bỏ qua ô 14. Cộng thêm ô 15, 16 thì tổng 1839. Thoả mãn >1800, <2000 thì dừng lại, kết thúc Nhóm 1. Nhóm 2 bắt đầu lại từ đầu, trừ những ô đã trong nhóm 1.
Bạn điền bằng tay kết quả mong muốn vào file rồi gửi lên nhé.
 
Ô đầu tiên: D1=1
D2:
Mã:
=IF(SUMIF($D$3:D4,D4,$C$3:C4)+C5<=$F$2,D4,MAX($D$3:D4)+1)
Kéo xuống

Có vẻ điều kiện >1800 là thừa, đúng không?
 
Ô đầu tiên: D1=1
D2:
Mã:
=IF(SUMIF($D$3:D4,D4,$C$3:C4)+C5<=$F$2,D4,MAX($D$3:D4)+1)
Kéo xuống

Có vẻ điều kiện >1800 là thừa, đúng không?
Vẫn xét điều kiện >1800, chuyện này hơi bị oải, cuối cùng còn lại <1800 thì sao cũng chưa biết.
 
Vẫn xét điều kiện >1800, chuyện này hơi bị oải, cuối cùng còn lại <1800 thì sao cũng chưa biết.
Bác ơi nếu cuối cùng <1800 thì cứ kệ thôi ạ
Bài đã được tự động gộp:

Ô đầu tiên: D1=1
D2:
Mã:
=IF(SUMIF($D$3:D4,D4,$C$3:C4)+C5<=$F$2,D4,MAX($D$3:D4)+1)
Kéo xuống

Có vẻ điều kiện >1800 là thừa, đúng không?
Bác ơi em làm theo công thức của bác đây (cột hồng)
Có 1 vấn đề: Tổng 13 ô đầu là 1774<1800 nhưng đã dừng vì nếu cộng thêm ô 14 sẽ lớn hơn 2000, cột xanh là em làm thủ công ạ.

1590404277167.png
 
Lần chỉnh sửa cuối:
Em xin kính chào các bác,

Em muốn hỏi/nhờ các bác chỉ dẫn/làm giúp để giải quyết vấn đề như sau:

1. Trong file đính kèm của em, em muốn phân nhóm các ô có tổng ở cột "LENGTH" nằm giữa giá trị nhỏ nhất (1800) và giá trị lớn nhất (2000);
2. Nhóm các ô đó được điền vào cột "GROUP" ở bên cạnh, các ô cùng nhóm sẽ có cùng giá trị;
3. Và tất nhiên một ô chỉ xuất hiện trong 1 nhóm duy nhất.

Em xin chân thành cảm ơn và chúc các bác 1 ngày làm việc hiệu quả :)
Bạn muốn liệt kê ra tất cả khả năng?
 
Em gửi bác file em điền tay đến Group 14 nhé, các cái sau tương tự nên em không làm nữa
Thử:
Mã:
E4=IF(C4>0,MATCH(1,INDEX(N(SUMIF($E$3:E3,ROW($1:$100),$C$3)+C4<2000),),),"")
Chỉ Enter.

Công thức này tạo lập đến "Nhóm 100", do dùng: ROW(1:100).
Nếu bạn muốn nâng lên thêm nữa, Vd: 200 nhóm, thì điều chỉnh thành ROW(1:200)

Thân
 

File đính kèm

Lần chỉnh sửa cuối:
Thử:
Mã:
E4=IF(C4>0,MATCH(1,INDEX(N(SUMIF($E$3:E3,ROW($1:$100),$C$3)+C4<2000),),),"")
Chỉ Enter.

Công thức này tạo lập đến "Nhóm 100", do dùng: ROW(1:100).
Nếu bạn muốn nâng lên thêm nữa, Vd: 200 nhóm, thì điều chỉnh thành ROW(1:200)

Thân
Thật là tuyệt vời, về cơ bản cách phân nhóm này đã đáp ứng yêu cầu của em rồi.

Em xin chân thành cảm ơn bác Phan Thế Hiệp và các bác đã giúp đỡ em!

Chúc các bác 1 ngày làm việc vui vẻ và hiệu quả!
 
Thử:
Mã:
E4=IF(C4>0,MATCH(1,INDEX(N(SUMIF($E$3:E3,ROW($1:$100),$C$3)+C4<2000),),),"")
Chỉ Enter.

Công thức này tạo lập đến "Nhóm 100", do dùng: ROW(1:100).
Nếu bạn muốn nâng lên thêm nữa, Vd: 200 nhóm, thì điều chỉnh thành ROW(1:200)

Thân
Em xin lỗi làm phiền bác, bác có thể giải thích ý nghĩa từng lệnh giúp em được không?
 
Em xin lỗi làm phiền bác, bác có thể giải thích ý nghĩa từng lệnh giúp em được không?
Tôi chỉ giải thích đoạn công thức:
MATCH(1, INDEX(N(SUMIF($E$3: E3,ROW($1:$100),$C$3: C3)+C4<2000),) , )
Phần công thức đơn giản như IF(C4>0, 'Đúng', 'Sai') thì chắc bạn biết rồi, không cần giải thích thêm.

1/ MATCH(1, 'Vùng/Mảng so khớp' , ) hay tương đương: MATCH(1, 'Vùng so khớp' , 0 ):
tức tìm giá trị 1 trong 'Vùng/Mảng so khớp', nếu tìm thấy thì trả về số dòng đang chứa giá trị khớp đúng đầu tiên đó. Hàm này tôi chắc bạn cũng đã rành rồi, nhưng tôi muốn ví dụ thêm để bạn dễ hình dung cho phần giải thích công thức kế tiếp.
  • Ví dụ:
    • MATCH(1, {1;1;1;1;1;1;1} , 0 ) = 1 --> tìm thấy giá trị 1 trong hàng đầu tiên của 'Vùng so khớp', là giá trị khớp đầu tiên, nên giá trị trả về là 1. Các hàng sau tuy có giá trị 1 nhưng không kể đến.
    • MATCH(1, {0;0;0;1;1;1;1} , 0 ) = 4 --> tìm thấy giá trị 1 trong hàng thứ 4 của 'Vùng so khớp', là giá trị khớp đầu tiên, nên giá trị trả về là 4. Các hàng sau tuy có giá trị 1 nhưng không kể đến.
    • MATCH(1, {0;1;0;0;0;1;1} , 0 ) = 2 --> tìm thấy giá trị 1 trong hàng thứ 2 của 'Vùng so khớp', là giá trị khớp đầu tiên, nên giá trị trả về là 2. Các hàng sau tuy có giá trị 1 nhưng không kể đến.
2/ INDEX(N(SUMIF($E$3: E3,ROW($1:$100),$C$3: C3)+C4<2000),) là công thức tạo ra kết quả là 1 'Mảng' để làm 'Vùng/Mảng so khớp' trong hàm MATCH(1,...,0) như đã nói ở trên.
  • Hàm: SUMIF($E$3: E3,ROW($1:$100),$C$3: C3) dùng "Tiêu chí lọc" là 1 'Mảng' tạo bởi hàm ROW(1:100), tức mảng gồm chứa các giá trị từ 1 đến 100, hay chính là số của các nhóm từ 1 đến 100. Câu lệnh này chạy và biến thiên theo dòng do 'Vùng dò' $E$3: E3 không có cố định biên dưới, nếu xuống dòng 4 thì sẽ thành $E$3: E4, tương tự cho các dòng dưới. Mục đích chính là nhằm cộng lũy kế theo từng nhóm của Vùng trước dòng lập công thức, và kết quả trả về là '1 Mảng' chứa toàn bộ số cộng lũy kế theo từng nhóm (từ 1 đến 100) đó.
    • Ví dụ: công thức tại dòng 29, thì SUMIF() sẽ cho ra kết quả cộng lũy kế của Vùng C3: C28. Bạn sẽ thấy Vùng E3: E28 chỉ có các nhóm 1, 2 và 3, nên kết quả trả về sẽ có giá trị chính là tổng số đã lũy kế theo nhóm 1, 2, và 3, còn các dòng khác bằng 0 (xem cột P file đính kèm).
  • SUMIF($E$3: E3,ROW($1:$100),$C$3: C3) +C4 <2000: Lấy 'Mảng' chứa số lũy kế theo từng nhóm cộng thêm giá trị 'Length' tại dòng đang đứng (xem cột Q và S), rồi so toàn bộ Mảng đó với 2000. Nếu nhỏ hơn trả ra kết quả TRUE, nếu lớn hơn là FALSE.
  • Dùng hàm N() để đổi TRUE thành 1 và FALSE thành 0 (xem cột R và T).
  • Do dùng Mảng ROW(1:100) trong 'Tiêu chí' của SUMIF(), nên để báo và hiện đủ mảng kết quả nên dùng thêm hàm Index(... , ).
  • Tóm lại: kết quả của đoạn công thức INDEX(....,) là 1 mảng chỉ chứa các giá trị gồm 2 số 0 và 1, tức những nhóm nào có số cộng lũy kế <2000 thì hiện 1, ngược lại là 0.
Khi thực hiện so khớp bằng Match(1, 'Vùng/Mảng so khớp', 0), nó sẽ tìm đến dòng, cũng là số thứ tự của nhóm thỏa điều kiện <2000 đầu tiên tìm thấy, như cách giải thích ở mục "1/" trên.

Thân
 

File đính kèm

Lần chỉnh sửa cuối:
Tôi chỉ giải thích đoạn công thức:
MATCH(1, INDEX(N(SUMIF($E$3: E3,ROW($1:$100),$C$3: C3)+C4<2000),) , )
Phần công thức đơn giản như IF(C4>0, 'Đúng', 'Sai') thì chắc bạn biết rồi, không cần giải thích thêm.

1/ MATCH(1, 'Vùng/Mảng so khớp' , ) hay tương đương: MATCH(1, 'Vùng so khớp' , 0 ):
tức tìm giá trị 1 trong 'Vùng/Mảng so khớp', nếu tìm thấy thì trả về số dòng đang chứa giá trị khớp đúng đầu tiên đó. Hàm này tôi chắc bạn cũng đã rành rồi, nhưng tôi muốn ví dụ thêm để bạn dễ hình dung cho phần giải thích công thức kế tiếp.
  • Ví dụ:
    • MATCH(1, {1;1;1;1;1;1;1} , 0 ) = 1 --> tìm thấy giá trị 1 trong hàng đầu tiên của 'Vùng so khớp', là giá trị khớp đầu tiên, nên giá trị trả về là 1. Các hàng sau tuy có giá trị 1 nhưng không kể đến.
    • MATCH(1, {0;0;0;1;1;1;1} , 0 ) = 4 --> tìm thấy giá trị 1 trong hàng thứ 4 của 'Vùng so khớp', là giá trị khớp đầu tiên, nên giá trị trả về là 4. Các hàng sau tuy có giá trị 1 nhưng không kể đến.
    • MATCH(1, {0;1;0;0;0;1;1} , 0 ) = 2 --> tìm thấy giá trị 1 trong hàng thứ 2 của 'Vùng so khớp', là giá trị khớp đầu tiên, nên giá trị trả về là 2. Các hàng sau tuy có giá trị 1 nhưng không kể đến.
2/ INDEX(N(SUMIF($E$3: E3,ROW($1:$100),$C$3: C3)+C4<2000),) là công thức tạo ra kết quả là 1 'Mảng' để làm 'Vùng/Mảng so khớp' trong hàm MATCH(1,...,0) như đã nói ở trên.
  • Hàm: SUMIF($E$3: E3,ROW($1:$100),$C$3: C3) dùng "Tiêu chí lọc" là 1 'Mảng' tạo bởi hàm ROW(1:100), tức mảng gồm chứa các giá trị từ 1 đến 100, hay chính là số của các nhóm từ 1 đến 100. Câu lệnh này chạy và biến thiên theo dòng do 'Vùng dò' $E$3: E3 không có cố định biên dưới, nếu xuống dòng 4 thì sẽ thành $E$3: E4, tương tự cho các dòng dưới. Mục đích chính là nhằm cộng lũy kế theo từng nhóm của Vùng trước dòng lập công thức, và kết quả trả về là '1 Mảng' chứa toàn bộ số cộng lũy kế theo từng nhóm (từ 1 đến 100) đó.
    • Ví dụ: công thức tại dòng 29, thì SUMIF() sẽ cho ra kết quả cộng lũy kế của Vùng C3: C28. Bạn sẽ thấy Vùng E3: E28 chỉ có các nhóm 1, 2 và 3, nên kết quả trả về sẽ có giá trị chính là tổng số đã lũy kế theo nhóm 1, 2, và 3, còn các dòng khác bằng 0 (xem cột P file đính kèm).
  • SUMIF($E$3: E3,ROW($1:$100),$C$3: C3) +C4 <2000: Lấy 'Mảng' chứa số lũy kế theo từng nhóm cộng thêm giá trị 'Length' tại dòng đang đứng (xem cột Q và S), rồi so toàn bộ Mảng đó với 2000. Nếu nhỏ hơn trả ra kết quả TRUE, nếu lớn hơn là FALSE.
  • Dùng hàm N() để đổi TRUE thành 1 và FALSE thành 0 (xem cột R và T).
  • Do dùng Mảng ROW(1:100) trong 'Tiêu chí' của SUMIF(), nên để báo và hiện đủ mảng kết quả nên dùng thêm hàm Index(... , ).
  • Tóm lại: kết quả của đoạn công thức INDEX(....,) là 1 mảng chỉ chứa các giá trị gồm 2 số 0 và 1, tức những nhóm nào có số cộng lũy kế <2000 thì hiện 1, ngược lại là 0.
Khi thực hiện so khớp bằng Match(1, 'Vùng/Mảng so khớp', 0), nó sẽ tìm đến dòng, cũng là số thứ tự của nhóm thỏa điều kiện <2000 đầu tiên tìm thấy, như cách giải thích ở mục "1/" trên.

Thân
Quá tuyệt vời bác ạ. Em xin chân thành cảm ơn bác.
 
Web KT

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

Back
Top Bottom