Việt Đức Phạm
Thành viên mới

- Tham gia
- 17/5/17
- Bài viết
- 1
- Được thích
- 0
- Giới tính
- Nam
Đưa file giả định lên, để nhận được kết quả.Chào anh chị em có trường hợp này nhờ anh chị hỗ trợ giúp.
Mình muốn nhập một lượng vào ô Tổng bên trên, bảng tính tự động chia lượng cho mình vào các ô bên dưới. Lượng bên dưới được chia random ( không phải là số liền kề liên tiếp 1 2 3), Mình xin cảm ơn các bạnView attachment 298363
Lúc còn đi làm công nhân sợ nhất là phải làm mấy việc như thế này. Đồ giả khó kiểm soát đúng sai.Chào anh chị em có trường hợp này nhờ anh chị hỗ trợ giúp.
Mình muốn nhập một lượng vào ô Tổng bên trên, bảng tính tự động chia lượng cho mình vào các ô bên dưới. Lượng bên dưới được chia random ( không phải là số liền kề liên tiếp 1 2 3), Mình xin cảm ơn các bạnView attachment 298363
Coi chừng bị Excel chưỡi cho bây chừ!Lúc đọc báo cáo sợ nhất là mấy cái bảng tính thiết kế kiểu này. Nhìn như cái sọt rác.
Bài này chắc là solver, tuy nhiên vì chưa thuần chủng được nó nên tớ không chắc lắm là có thành công không. Nên mò thử.tự động
Trừ phi người thực hiện rất khó tính, chứ bài toán này là dạng bá cá mau. Ở đây thi thoảng vẫn gặp.Bài này chắc là solver, tuy nhiên vì chưa thuần chủng được nó nên tớ không chắc lắm là có thành công không. Nên mò thử.
Option Explicit
Function SoTuDong(ByVal Tien As Long, Dong As Integer) As Variant
Dim i, T&, Tong&, ConLai&, TongCong&, D&, C&
Dim Rng As Range
D = Int(Tien / Dong / 2): C = D * 3
ReDim KQ(1 To Dong, 1 To 1)
Do
TongCong = 0: Tong = 0
For i = 1 To Dong
If i <> Dong Then
T = Application.WorksheetFunction.RandBetween(D, C)
KQ(i, 1) = T
Tong = Tong + T
ConLai = Tong - Tien
Else
If ConLai < 0 Then KQ(Dong, 1) = ConLai * -1
TongCong = Tong + KQ(Dong, 1)
End If
Next i
Loop While TongCong <> Tien
SoTuDong = KQ
End Function
Nhưng số lít chỉ gấp 3 lần số dòng trở lại thì trùng khá nhiều!Mà đề bài là không liên tục thôi; Trùng chắc được chấp nhận!Góp vui. 1 giải pháp bằng VBA.
Option Explicit
Function SoTuDong(ByVal Tien As Long, Dong As Integer) As Variant
End Function
Cú pháp : SoTuDong=(Tổng số;số dòng) Enter để có kết quả. cứ mỗi lần Enter là có 1 kết quả khác nhau nhưng tổng số vẵn bằng Số cho trước.
Ví dụ: Số lít = 100 ; số dòng =10 : D4=SoTuDong(100;10)
thì nó mới khó bác ạ.khó tính
Em đang thử thì kết quả nhận được chưa xét đến điều kiện các số liên tiếp không được hơn kém nhau <=1 đơn vị.SoTuDong
có nhưng mà lại khôngTạo cột phụ
Cảm ơn anh đã ghé xem bài và tương tác.Nhưng số lít chỉ gấp 3 lần số dòng trở lại thì trùng khá nhiều!Mà đề bài là không liên tục thôi; Trùng chắc được chấp nhận!
Có thể bạn thao tác nhầm lẫn chỗ nào, chứ về lý thuyết tổng đó không thể nào khác 100 được.có nhưng mà lại không
Cũng được, nhưng phải tạo cột phụ 99 ô, tương ứng với tổng 100 lit.có nhưng mà lại không
Function SoTuDong(ByVal Tien As Long, Dong As Integer) As Variant
Dim fNum As Integer, TB As Long, J As Integer, Tong As Integer
TB = Tien / Dong: Randomize
ReDim KQ(1 To Dong, 1 To 1)
Do
J = J + 1:
If J = Dong Then
KQ(Dong, 1) = Tien - Tong: Exit Do
End If
fNum = J + TB * Rnd()
KQ(J, 1) = fNum \ 1
Tong = Tong + KQ(J, 1)
Loop
SoTuDong = KQ()
End Function
Excel 365 có hàm tạo số ngẫu nhiên cho mảng, có mảng động, nên có thể áp dụng cho số tổng và số dòng là bất kỳ.Ở bài #7 tôi đã đề cập vụ này rồi. Cách phân bổ duy nhất để tránh 0 là trừ trước.
Mỗi ô sẽ nhận 1 trước khi bắt đầu phân bổ.
Tại sao code của bác ấn F9 nó không nhảy giá trị như code của bác HUONGHCKT như trên vậy nhỉ? Là lạ bác ạ!Cho phép ham vui xíu nha:
Nhưng số lít cần nhập nên gấp 6 lần trở lên so với số dòng mới đẹp mảng nhận đượcPHP:Function SoTuDong(ByVal Tien As Long, Dong As Integer) As Variant Dim fNum As Integer, TB As Long, J As Integer, Tong As Integer TB = Tien / Dong: Randomize ReDim KQ(1 To Dong, 1 To 1) Do J = J + 1: If J = Dong Then KQ(Dong, 1) = Tien - Tong: Exit Do End If fNum = J + TB * Rnd() KQ(J, 1) = fNum \ 1 Tong = Tong + KQ(J, 1) Loop SoTuDong = KQ() End Function
Solver có vẻ không hay vì nó cho cảm giác không phải random thực sự, nó dồn to vào 1 chỗ, phần còn lại bị teo nhỏ nhỉ.
File này chủ yếu là test solver có thể tìm được kết quả yêu cầu hay không nên để đơn giản vậy chạy cho nhanh.Tại sao code của bác ấn F9 nó không nhảy giá trị như code của bác HUONGHCKT như trên vậy nhỉ? Là lạ bác ạ!![]()
![]()
Solver có vẻ không hay vì nó cho cảm giác không phải random thực sự, nó dồn to vào 1 chỗ, phần còn lại bị teo nhỏ nhỉ.
Chỉ điều chỉnh 1 giá trị có thể làm kết quả chênh lệch không đềuFunction PhanBo(ByVal tong As Long, ByVal phan As Long)
' ham phan bo so luong "tong" theo so luong "phan"
' output: mot mang "phan" phan tu; dieu kien: moi phan tu duoc phan bo it nhat 1
'
If tong < phan Then
PhanBo = "Khong du luong de phan bo"
Exit Function
End If
Randomize
ReDim a(1 To phan) As Long
For i = 1 To phan
a(i) = Application.RandBetween(1, 1000000)
tongA = tongA + a(i)
Next i
tongA = (tong - phan) / tongA ' tinh he so cho moi phan tu
For i = 1 To phan
a(i) = Int(a(i) * tongA) + 1 ' cong 1 de bao dam moi phan tu >= 1
tong = tong - a(i)
Next i
If tong > 0 Then ' thanh ly so le do sai so tinh toan
i = Application.RandBetween(1, phan)
a(i) = a(i) + tong
End If
PhanBo = a
End Function
Hàm trả về một mảng dọc.
Để sử dụng:
- select 10 ô liên tiếp
- gõ =PhanBo(số lượng, 10)
- gõ Ctrl+Shift+Enter
Giải thuật được tính theo kiểu để tránh tối đa trường hợp chênh lệch nhiều quá (tránh tối đa là đủ rồi, đã random thì tránh 100% hơi khó.)