اذهب الي المحتوي
أوفيسنا
بحث مخصص من جوجل فى أوفيسنا
Custom Search

الردود الموصى بها

قام بنشر (معدل)

ممكن يكون طلبك هنا

https://www.youtube.com/watch?v=M1DhpzkT8kA

 او جرب هذا الكود:

Sub Observer_FullSystem()

    Dim ws As Worksheet, wsReport As Worksheet
    Dim NamesArr() As Variant
    Dim UsedRow As Object, UsedCol As Object, UsedAll As Object
    Dim lrNames As Long, lrRows As Long, lrCols As Long
    Dim r As Long, c As Long, i As Long
    Dim Available() As String
    Dim cnt As Long, MaxAllowed As Long, TotalCells As Long
    Dim TryCount As Long
    Dim MainCols As Long: MainCols = 2   ' عدد الأعمدة الأساسية
    
    Set ws = ActiveSheet
    Application.ScreenUpdating = False
    Randomize

    ' ===== Backup =====
    ws.Copy After:=Sheets(Sheets.Count)
    ActiveSheet.Name = "Backup_" & Format(Now, "ddmmyy_hhmmss")
    ws.Activate

    ' ===== قراءة الأسماء =====
    lrNames = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
    NamesArr = ws.Range("B3:B" & lrNames).Value

    ' ===== حدود الجدول =====
    lrRows = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
    lrCols = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column

    ws.Range(ws.Cells(3, 4), ws.Cells(lrRows, lrCols)).ClearContents

    ' ===== الحد الأقصى =====
    TotalCells = (lrRows - 2) * (lrCols - 3)
    MaxAllowed = Application.WorksheetFunction.RoundUp(TotalCells / (lrNames - 2), 0)

    Set UsedAll = CreateObject("Scripting.Dictionary")

    ' ===== التوزيع =====
    For r = 3 To lrRows
        Set UsedRow = CreateObject("Scripting.Dictionary")

        For c = 4 To lrCols
            TryCount = 0

RetryCell:
            TryCount = TryCount + 1
            If TryCount > 300 Then GoTo NextCell

            Set UsedCol = CreateObject("Scripting.Dictionary")
            For i = 3 To r - 1
                If ws.Cells(i, c).Value <> "" Then UsedCol(ws.Cells(i, c).Value) = 1
            Next i

            cnt = 0
            ReDim Available(1 To UBound(NamesArr, 1))

            For i = 1 To UBound(NamesArr, 1)
                If Not UsedRow.exists(NamesArr(i, 1)) _
                And Not UsedCol.exists(NamesArr(i, 1)) Then

                    If Not UsedAll.exists(NamesArr(i, 1)) _
                    Or UsedAll(NamesArr(i, 1)) < MaxAllowed Then
                        cnt = cnt + 1
                        Available(cnt) = NamesArr(i, 1)
                    End If
                End If
            Next i

            If cnt > 0 Then
                ws.Cells(r, c).Value = Available(Int(Rnd * cnt) + 1)
                UsedRow(ws.Cells(r, c).Value) = 1

                UsedAll(ws.Cells(r, c).Value) = UsedAll(ws.Cells(r, c).Value) + 1
            Else
                GoTo RetryCell
            End If

NextCell:
        Next c
    Next r

    ' ===== تقرير =====
    On Error Resume Next
    Set wsReport = Sheets("تقرير")
    On Error GoTo 0

    If wsReport Is Nothing Then
        Set wsReport = Sheets.Add
        wsReport.Name = "تقرير"
    Else
        wsReport.Cells.Clear
    End If

    wsReport.Range("A1:D1") = Array("الاسم", "الإجمالي", "أساسي", "احتياطي")

    For i = 3 To lrNames
        wsReport.Cells(i - 2, 1) = ws.Cells(i, 2)
        wsReport.Cells(i - 2, 2) = Application.CountIf(ws.Range(ws.Cells(3, 4), ws.Cells(lrRows, lrCols)), ws.Cells(i, 2))
        wsReport.Cells(i - 2, 3) = Application.CountIf(ws.Range(ws.Cells(3, 4), ws.Cells(lrRows, 3 + MainCols)), ws.Cells(i, 2))
        wsReport.Cells(i - 2, 4) = wsReport.Cells(i - 2, 2) - wsReport.Cells(i - 2, 3)
    Next i

    wsReport.Columns.AutoFit

    Application.ScreenUpdating = True
    MsgBox "تم التوزيع + إنشاء نسخة احتياطية + تقرير كامل ?", vbInformation

End Sub

 

تم تعديل بواسطه hegazee

انشئ حساب جديد او قم بتسجيل دخولك لتتمكن من اضافه تعليق جديد

يجب ان تكون عضوا لدينا لتتمكن من التعليق

انشئ حساب جديد

سجل حسابك الجديد لدينا في الموقع بمنتهي السهوله .

سجل حساب جديد

تسجيل دخول

هل تمتلك حساب بالفعل ؟ سجل دخولك من هنا.

سجل دخولك الان
  • تصفح هذا الموضوع مؤخراً   0 اعضاء متواجدين الان

    • لايوجد اعضاء مسجلون يتصفحون هذه الصفحه
×
×
  • اضف...

Important Information