lặp lại có điều kiện trong excel

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

Phuong0907357642

Thành viên mới
Tham gia
5/8/11
Bài viết
41
Được thích
0
Mình có số Phiếu may mắn của các bạn PG của mình khi thực hiện chiến dịch nội bộ, Mình chỉ có báo cáo tổng hợp của từng bạn
Bây giờ cứ bao nhiêu phiếu may măn thì có bây nhiều dòng xuát hiện để có thể bỏ vô cái app quay số trúng thưởng
thì nhờ các anh chị có thể giúp em được không ạ?
Em cám ơn
 

File đính kèm

  • XUAN.xlsx
    18.2 KB · Đọc: 18
Bạn tham khảo con macro này:

PHP:
Dim Arr()
Sub LapDSDongMayMan()
 Dim Rws As Long, J As Long, W As Integer, Tong As Long, Dg As Integer, SF As Integer
 Dim Cls As Range, WF As Object, MaNV
 Dim HoTen As String
 
 Sheets("Du Lieu").Select
 Rws = Sheets("Du Lieu").UsedRange.Rows.Count
 Set WF = Application.WorksheetFunction
 Tong = WF.Sum([C2].Resize(Rws))
 [E2].Resize(Tong + 9, 3).Value = ""
 ReDim Arr(1 To Tong, 1 To 3)
 For Each Cls In [A2].Resize(Rws)
    MaNV = Cls.Value: HoTen = Cls.Offset(, 1).Value
    SF = Cls.Offset(, 2).Value
    For Dg = 1 To SF
        W = W + 1:                  Arr(W, 1) = W
        Arr(W, 2) = "'" & MaNV:     Arr(W, 3) = HoTen
    Next Dg
 Next Cls
 [E2].Resize(W, 3).Value = Arr()
 MsgBox "Xong Nha!", , W
End Sub

& chúc vui suốt tuần!
 
Lần chỉnh sửa cuối:
Mình có số Phiếu may mắn của các bạn PG của mình khi thực hiện chiến dịch nội bộ, Mình chỉ có báo cáo tổng hợp của từng bạn
Bây giờ cứ bao nhiêu phiếu may măn thì có bây nhiều dòng xuát hiện để có thể bỏ vô cái app quay số trúng thưởng
thì nhờ các anh chị có thể giúp em được không ạ?
Em cám ơn
Góp vui thêm 1 code để bạn rộng đừng lựa chọn
Bạn tham khảo code sau:
Mã:
Option Explicit

Sub ABC()
Dim i&, J&, Lr&, d&, k&, R&, t&, Z&
Dim Arr(), KQ(), S
Dim Dic As Object, Key
Application.ScreenUpdating = False

With Sheet1
Lr = .Cells(100000, 1).End(xlUp).Row
Arr = .Range("A2:C" & Lr).Value
End With
R = UBound(Arr)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 3)
    If Not Dic.Exists(Key) Then
        k = k + 1: Dic.Add (Key), k
        Dic(Key) = i
    Else
        Dic(Key) = Dic(Key) & "," & i
    End If
Next i

ReDim KQ(1 To Dic.Count * 100, 1 To 3)
For Each Key In Dic.Keys
    S = Split(Dic(Key), ",")
    For d = 1 To Key
        For Z = LBound(S) To UBound(S)
                t = t + 1
                KQ(t, 1) = t
                KQ(t, 2) = Arr(S(Z), 1)
                KQ(t, 3) = Arr(S(Z), 2)
        Next Z
    Next d
Next Key
If t Then
    Sheet2.Range("A3").Resize(10000, 3).ClearContents
    Sheet2.Range("A3").Resize(t, 3) = KQ
End If
Set Dic = Nothing
Application.ScreenUpdating = True
MsgBox " Xong"
End Sub
 
Góp vui thêm 1 code để bạn rộng đừng lựa chọn
Bạn tham khảo code sau:
Mã:
Option Explicit

Sub ABC()
Dim i&, J&, Lr&, d&, k&, R&, t&, Z&
Dim Arr(), KQ(), S
Dim Dic As Object, Key
Application.ScreenUpdating = False

With Sheet1
Lr = .Cells(100000, 1).End(xlUp).Row
Arr = .Range("A2:C" & Lr).Value
End With
R = UBound(Arr)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To R
    Key = Arr(i, 3)
    If Not Dic.Exists(Key) Then
        k = k + 1: Dic.Add (Key), k
        Dic(Key) = i
    Else
        Dic(Key) = Dic(Key) & "," & i
    End If
Next i

ReDim KQ(1 To Dic.Count * 100, 1 To 3)
For Each Key In Dic.Keys
    S = Split(Dic(Key), ",")
    For d = 1 To Key
        For Z = LBound(S) To UBound(S)
                t = t + 1
                KQ(t, 1) = t
                KQ(t, 2) = Arr(S(Z), 1)
                KQ(t, 3) = Arr(S(Z), 2)
        Next Z
    Next d
Next Key
If t Then
    Sheet2.Range("A3").Resize(10000, 3).ClearContents
    Sheet2.Range("A3").Resize(t, 3) = KQ
End If
Set Dic = Nothing
Application.ScreenUpdating = True
MsgBox " Xong"
End Sub
rất hay và dễ hiểu. Minh xin cám ơn.
Nếu được bạn có thể viết đoạn code cho việc sau khi có kết quả nó trộn dữ liệu tá lả để vô vòng quay mắn ko bạn.
Mình chỉ biết làm hàm sortby với rand và counta hà, Nhưng mong cao thủ cho mình học hỏi các xóa trộn dữ liệu ko có nguyên tắc ạ,. Cám ơn và cám ơn
 
rất hay và dễ hiểu. Minh xin cám ơn.
Nếu được bạn có thể viết đoạn code cho việc sau khi có kết quả nó trộn dữ liệu tá lả để vô vòng quay mắn ko bạn.
Mình chỉ biết làm hàm sortby với rand và counta hà, Nhưng mong cao thủ cho mình học hỏi các xóa trộn dữ liệu ko có nguyên tắc ạ,. Cám ơn và cám ơn
Nếu bạn muốn vùng kết quả là ngẫu nhiên. Nhấm vào nút "Tạo Danh sách".
Cột E:G là vùng để bạn kiểm tra kết quả, có thể bỏ đi.

PHP:
Option Explicit
Sub quayso()
Dim i&, j&, k&, r&, rng, tota&, arr(1 To 100000, 1 To 3), res(1 To 100000, 1 To 2)
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
rng = Sheets("DU LIEU").Range("B3").CurrentRegion.Value

'Tao bien arr de chua danh sach da nhan len theo so phieu
For i = 2 To UBound(rng)
    For j = 1 To rng(i, 3)
        k = k + 1: arr(k, 3) = k: arr(k, 1) = rng(i, 1): arr(k, 2) = rng(i, 2)
    Next
Next
tota = k: k = 0
Randomize

'tao r la so ngau nhien, sau do dua vao dictionary de loai trung.Neu r phat sinh lan dau thi dua vao mang ket qua res
Do
    r = Int(Rnd() * tota) + 1
    If Not dic.exists(r) Then
        k = k + 1: res(k, 1) = arr(r, 1): res(k, 2) = arr(r, 2)
        dic.Add r, ""
    End If
Loop Until k >= tota
Set dic = Nothing
Range("A3").Resize(tota, 2).Value = res
End Sub
 

File đính kèm

  • XUAN.xlsm
    28.3 KB · Đọc: 2
Hoặc thử code này:

Mã:
Public Sub Random()
Dim Lr&, u&, rd&, total&, k&, i&
Dim sArr As Variant, rArr As Variant
Randomize
With Sheets("DU LIEU")
    Lr = .Range("A" & .Rows.Count).End(xlUp).Row
    sArr = .Range("A2:C" & Lr).Value
    u = UBound(sArr, 1)
    total = Application.Sum(.Range("C2:C" & Lr))
    ReDim rArr(1 To total, 1 To 2)
End With
k = 0
Do While k < total
    rd = Int(Rnd() * u) + 1
    k = k + 1
    rArr(k, 1) = sArr(rd, 1)
    rArr(k, 2) = sArr(rd, 2)
    sArr(rd, 3) = sArr(rd, 1) - 1
    If sArr(rd, 3) = 0 Then
        sArr(rd, 1) = sArr(u, 1)
        sArr(rd, 2) = sArr(u, 2)
        sArr(rd, 3) = sArr(u, 3)
        u = u - 1
    End If
Loop
If k > 0 Then Sheet2.Range("A3").Resize(k, 2).Value = rArr
End Sub
 
Hoặc thử code này:

Mã:
Public Sub Random()
Dim Lr&, u&, rd&, total&, k&, i&
Dim sArr As Variant, rArr As Variant
Randomize
With Sheets("DU LIEU")
    Lr = .Range("A" & .Rows.Count).End(xlUp).Row
    sArr = .Range("A2:C" & Lr).Value
    u = UBound(sArr, 1)
    total = Application.Sum(.Range("C2:C" & Lr))
    ReDim rArr(1 To total, 1 To 2)
End With
k = 0
Do While k < total
    rd = Int(Rnd() * u) + 1
    k = k + 1
    rArr(k, 1) = sArr(rd, 1)
    rArr(k, 2) = sArr(rd, 2)
    sArr(rd, 3) = sArr(rd, 1) - 1
    If sArr(rd, 3) = 0 Then
        sArr(rd, 1) = sArr(u, 1)
        sArr(rd, 2) = sArr(u, 2)
        sArr(rd, 3) = sArr(u, 3)
        u = u - 1
    End If
Loop
If k > 0 Then Sheet2.Range("A3").Resize(k, 2).Value = rArr
End Sub
Chỗ này hình như là tay thư ký gõ sai sao đó :p
Mã:
sArr(rd, 3) = sArr(rd, 1) - 1'<<---
 
rất hay và dễ hiểu. Minh xin cám ơn.
Nếu được bạn có thể viết đoạn code cho việc sau khi có kết quả nó trộn dữ liệu tá lả để vô vòng quay mắn ko bạn.
Mình chỉ biết làm hàm sortby với rand và counta hà, Nhưng mong cao thủ cho mình học hỏi các xóa trộn dữ liệu ko có nguyên tắc ạ,. Cám ơn và cám ơn
Góp vui thêm 1 lựa chọn:
Lấy kết quả đã chạy code ỏ bài #3. Sau đó chạy code này. Khi chạy code kết quả trả về tên nhân viên ở dòng trên không trùng với tên nhân viên ở dòng dưới.
Kết quả chạy code có thể không ra đủ số lượng nhân viên đã lập danh sách. Đừng lo cứ chạy lại (1 số lần- nhanh thôi) là sẽ đủ.
Xem file
 

File đính kèm

  • XUAN.xlsm
    37.2 KB · Đọc: 5
. . .
(2) Lấy kết quả đã chạy code ỏ bài #3. Sau đó chạy code này. Khi chạy code kết quả trả về tên nhân viên ở dòng trên không trùng với tên nhân viên ở dòng dưới.
(1) Kết quả chạy code có thể không ra đủ số lượng nhân viên đã lập danh sách.
(1) Thêm vài dòng lệnh cho macro #3, như sau:
→ Thay vì tạo mảng 3 cột, ta tăng thêm 1 cột nữa (là 4)
→ Kích hoạt bộ tạo số ngẫu (Randomize) trước khi vô vòng lặp
→ Sau khi nạp 3 cột dữ liệu cho từng dòng trong mãng xong, ta thực hiện nạp số ngãu cho phần tử 4, ví dụ như
Mã:
 Arr(i,4)=1+9876 * Rnd()\1
→ [Cuối cùng] Giành phần xếp dữ liệu theo cột 4 (ngẫu) cho chủ bài đăng!
:D :D :D
 
(1) Thêm vài dòng lệnh cho macro #3, như sau:
→ Thay vì tạo mảng 3 cột, ta tăng thêm 1 cột nữa (là 4)
→ Kích hoạt bộ tạo số ngẫu (Randomize) trước khi vô vòng lặp
→ Sau khi nạp 3 cột dữ liệu cho từng dòng trong mãng xong, ta thực hiện nạp số ngãu cho phần tử 4, ví dụ như
Mã:
 Arr(i,4)=1+9876 * Rnd()\1
→ [Cuối cùng] Giành phần xếp dữ liệu theo cột 4 (ngẫu) cho chủ bài đăng!
:D :D :D
Cảm ơn Anh đã xem bài và chỉ bảo.
Tôi cũng đã làm thế nhưng vẫn còn bị trùng tên hàng trên và hàng dưới (có tên được lặp đến 35 lần do vậy trùng là điều không tránh khỏi. Rất khó để tránh không trùng. Trong code anh thấy có dòng If z<=R*2 nhằm hạn chế số lần chạy vòng lặp duyệt lại. nếu không có dòng này code chạy đơ luôn.
Còn nếu dùng code để chạy ngay từ Sh DuLieu đưa vào mảng và chạy code bài #9 thì số dòng kết quả chỉ được 27-28 dòng.
Tôi hy vọng vẫn có thành viên khác có giải pháp tốt hơn để có thêm kiến thức học tập.
 
Quá ngạc nhiên luôn!
Vì mình áp dụng cho macro của mình & kết quả sau sắp xếp không bao giờ trùng đến hàng đơn vị nữa kia!


STTMã NVHọ và TênSố Ngẫu
1NBT00NGUYỄN THỊ BÍCH TRÂM
234​
2PHS00PHẠM HỒNG SƠN
257​
3NNH00NGUYỄN NGỌC HANH
331​
4NTL00NGUYỄN TÙNG LÂM544
5FNA00ĐOÀN THỊ NGUYỆT ANH636
6VJT00VŨ TUẤN696
7PKK00PHƯƠNG KỲ KHƯƠNG
822​
8FHH00ĐẶNG HỮU HÀO
895​
9NDH00NGUYỄN DUY HIẾU
976​
10FHT00ĐẶNG TRẦN HOÀNG TRINH1,010
11HTT00HUỲNH THỊ THU THỦY
1027​
12HTT00HUỲNH THỊ THU THỦY
1032​
13TTM00TRẦN LÊ THANH MAI
1170​
14PHS00PHẠM HỒNG SƠN
1334​
15HTT00HUỲNH THỊ THU THỦY
1452​
16VJT00VŨ TUẤN
1982​
17PVC00PHẠM VĂN CHƯƠNG
2097​
18HTT00HUỲNH THỊ THU THỦY
2390​
19NVT00NGUYỄN VĂN THẮNG
2404​
20HTT00HUỲNH THỊ THU THỦY2,440
21TNB00TRẦN NGỌC BÍCH2,583
22NNH00NGUYỄN NGỌC HANH
2677​
23FNA00ĐOÀN THỊ NGUYỆT ANH
2699​
24NTN00NGUYỄN BÌNH PHƯƠNG THẢO NHI
2705​
25NNH00NGUYỄN NGỌC HUY
3213​
26FHH00ĐẶNG HỮU HÀO3,268
27NBT00NGUYỄN THỊ BÍCH TRÂM
3289​
28PHS00PHẠM HỒNG SƠN3,549


→ → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ←

PHP:
Dim Arr()
Sub LapDSDongMayMan()
 Dim Rws As Long, J As Long, W As Integer, Tong As Long, Dg As Integer, SF As Integer
 Dim Cls As Range, WF As Object, MaNV
 Dim HoTen As String
 
 Sheets("Du Lieu").Select
 Rws = Sheets("Du Lieu").UsedRange.Rows.Count
 Set WF = Application.WorksheetFunction
 Tong = WF.Sum([C2].Resize(Rws))
 [E2].Resize(Tong + 9, 4).Value = ""
 ReDim Arr(1 To Tong, 1 To 4):      Randomize
 For Each Cls In [A2].Resize(Rws)
    MaNV = Cls.Value: HoTen = Cls.Offset(, 1).Value
    SF = Cls.Offset(, 2).Value
    For Dg = 1 To SF
        W = W + 1:                  Arr(W, 1) = W
        Arr(W, 2) = "'" & MaNV:     Arr(W, 3) = HoTen
        Arr(W, 4) = 1 + 9876 * Rnd() \ 1
    Next Dg
 Next Cls
 [E2].Resize(W, 4).Value = Arr()
 MsgBox "Xong Nha!", , W
End Sub
 
Lần chỉnh sửa cuối:
Quá ngạc nhiên luôn!
Vì mình áp dụng cho macro của mình & kết quả sau sắp xếp không bao giờ trùng đến hàng đơn vị nữa kia!


STTMã NVHọ và TênSố Ngẫu
1NBT00NGUYỄN THỊ BÍCH TRÂM
234​
2PHS00PHẠM HỒNG SƠN
257​
3NNH00NGUYỄN NGỌC HANH
331​
4NTL00NGUYỄN TÙNG LÂM544
5FNA00ĐOÀN THỊ NGUYỆT ANH636
6VJT00VŨ TUẤN696
7PKK00PHƯƠNG KỲ KHƯƠNG
822​
8FHH00ĐẶNG HỮU HÀO
895​
9NDH00NGUYỄN DUY HIẾU
976​
10FHT00ĐẶNG TRẦN HOÀNG TRINH1,010
11HTT00HUỲNH THỊ THU THỦY
1027​
12HTT00HUỲNH THỊ THU THỦY
1032​
13TTM00TRẦN LÊ THANH MAI
1170​
14PHS00PHẠM HỒNG SƠN
1334​
15HTT00HUỲNH THỊ THU THỦY
1452​
16VJT00VŨ TUẤN
1982​
17PVC00PHẠM VĂN CHƯƠNG
2097​
18HTT00HUỲNH THỊ THU THỦY
2390​
19NVT00NGUYỄN VĂN THẮNG
2404​
20HTT00HUỲNH THỊ THU THỦY2,440
21TNB00TRẦN NGỌC BÍCH2,583
22NNH00NGUYỄN NGỌC HANH
2677​
23FNA00ĐOÀN THỊ NGUYỆT ANH
2699​
24NTN00NGUYỄN BÌNH PHƯƠNG THẢO NHI
2705​
25NNH00NGUYỄN NGỌC HUY
3213​
26FHH00ĐẶNG HỮU HÀO3,268
27NBT00NGUYỄN THỊ BÍCH TRÂM
3289​
28PHS00PHẠM HỒNG SƠN3,549


→ → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ← → → → o ← ← ←

PHP:
Dim Arr()
Sub LapDSDongMayMan()
 Dim Rws As Long, J As Long, W As Integer, Tong As Long, Dg As Integer, SF As Integer
 Dim Cls As Range, WF As Object, MaNV
 Dim HoTen As String
 
 Sheets("Du Lieu").Select
 Rws = Sheets("Du Lieu").UsedRange.Rows.Count
 Set WF = Application.WorksheetFunction
 Tong = WF.Sum([C2].Resize(Rws))
 [E2].Resize(Tong + 9, 4).Value = ""
 ReDim Arr(1 To Tong, 1 To 4):      Randomize
 For Each Cls In [A2].Resize(Rws)
    MaNV = Cls.Value: HoTen = Cls.Offset(, 1).Value
    SF = Cls.Offset(, 2).Value
    For Dg = 1 To SF
        W = W + 1:                  Arr(W, 1) = W
        Arr(W, 2) = "'" & MaNV:     Arr(W, 3) = HoTen
        Arr(W, 4) = 1 + 9876 * Rnd() \ 1
    Next Dg
 Next Cls
 [E2].Resize(W, 4).Value = Arr()
 MsgBox "Xong Nha!", , W
End Sub
Anh @SA_DQ à.
Tôi hiểu ý của chủ thớt là thế này không biết có đúng không: Đó là từ dữ liệu ban đầu tạo 1 danh sách các tên NV lung tung không trùng nhau giữa dòng trên và dòng dưới (nguyên văn ở #4 là "...có kết quả nó trộn dữ liệu tá lả...".)
Do vậy nếu chạy code của anh sẽ cho ra kết quả như hình 1 và sau khi sort theo cột H sẽ được kết quả nhu hình 2. và rất dễ nhận thấy vẫn còn có hàng trên hàng dưới trùng nhau.
 

File đính kèm

  • H1( sau khi code).png
    H1( sau khi code).png
    157.2 KB · Đọc: 6
  • H2 (sau khi sort).png
    H2 (sau khi sort).png
    180.1 KB · Đọc: 6
1729086055493.png
Một giải pháp về Dax:
JavaScript:
Expand_Row5 =
SELECTCOLUMNS(
    ADDCOLUMNS(GENERATE(
        Table2,
        GENERATESERIES(1, Table2[SỐ Phiếu may mắn])
    ),"Expandrow", Table2[SỐ Phiếu may mắn]),
    "Mã NV",[Mã NV],
    "Họ và Tên",[Họ và Tên])
 
Bài này tương đối giản dị. Tại quý vị quen chìu người xin code cho nên họ vẽ vời cho thích ý thôi.
Điển hình mới đầu chỉ cần danh sách để cho vào cái app quay số.
Rốt lại có thấy cái app quỷ quái nào đâu?

Tôi là giản dị chút nào hay chút nấy. Chả cần "ưu hóa" chạy cho nhanh làm gì. Trừ phi thớt mở sòng trong công ty. Mỗi ngày chạy vài chục lượt bán vé số và xổ trúng thưởng.

Công việc gồm 4 phần:
1. Ghi tên theo số lượng phiếu trong tay
2. Thêm cột phụ. Dùng hàm Rnd() để ghi số ngẫu nhiên
3. Sort theo cột phụ, lớn đến bé hay bé đến lớn đều được.
4. Đánh số thứ tự vào cột phụ
Sổ số chỉ việc bốc n số không trùng. Hết.

Thực ra thì do thớt làm ngược từ người mua vé sang vé nên mới rắc rối lô gic. Chứ cứ giản dị lô gic dân sổ số thì chỉ cần số vé, đem chúng link với người mua là xong.
 
1 cách khác
Mã:
Option Explicit

Sub random_()
Dim sArr
Dim ID()
Dim Res()
Dim rws, cls
Dim index, i, j, k

With Sheet1
    sArr = .Range("A2", .Range("C2").End(xlDown))
End With

rws = UBound(sArr)
ReDim ID(1 To rws)
For j = rws To 1 Step -1
    ID(rws - j + 1) = j
    k = k + sArr(j, 3)
Next j
ReDim Res(1 To k, 1 To 2)

'cls = WorksheetFunction.Max(3, k \ sArr(rws, 3))  '<-
cls = 3 '<-
index = cls + 1

k = 1
Randomize
Do While cls > 0
    j = IIf(cls = 1, 1, Rnd() * (cls - 2) \ 1 + 1)
    
    i = ID(j)
    ID(j) = ID(cls)
    ID(cls) = i
    
    sArr(i, 3) = sArr(i, 3) - 1
    If sArr(i, 3) = 0 Then
        If index <= rws Then
            ID(cls) = ID(index)
            index = index + 1
        Else
            cls = cls - 1
        End If
    End If
    
    Res(k, 1) = sArr(i, 1)
    Res(k, 2) = sArr(i, 2)
    k = k + 1
Loop

With Sheet2
    .Range("A3").Resize(UBound(Res), UBound(Res, 2)).Clear
    .Range("A3").Resize(UBound(Res), UBound(Res, 2)) = Res
End With
End Sub
 
Web KT

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

Back
Top Bottom