Функция Excel для заполнения сетки конкретными данными, которая ограничена тем, сколько раз можно использовать точку данных - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь заполнить сетку Excel 16 столбцами на 12 строк вниз с 19 различными точками данных.Каждую точку можно использовать только определенное количество раз (отличное для каждой точки), и точка данных не может дублировать себя в одной ячейке в любом направлении.Пример:

Точки данных A, B, C, D, E

A, B, C, D, E

D, E, A, B, C

B, C, D, E, A

Существует ли формула (или набор формул), которую я могу использовать для создания случайного «шаблона» точек данных, который учитываетограниченное количество каждой точки может быть использовано И проверяет, находится ли этот результат в соседней ячейке?

Data Points Available
A   21
B   17
C   14
D   8
E   7
F   6
G   4
H   3
I   3
J   3
K   2
L   1
M   1
N   1
O   1
P   1
Q   1
R   1
S   1

1 Ответ

0 голосов
/ 06 мая 2019

Если у вас Office 365 или Excel 2016+, то для этого вы можете использовать функцию TEXTJOIN .Если у вас более старая версия Excel, то этот UDF (, первоначально созданный Скоттом Кранером ):

'TEXTJOIN UDF created by Scott Craner at www.stackoverflow.com on Aug 23 2017
'Code from https://stackoverflow.com/questions/45843881/textjoin-udf-for-excel-2013
Function TEXTJOIN(delim As String, skipblank As Boolean, arr)
    Dim d As Long
    Dim c As Long
    Dim arr2()
    Dim t As Long, y As Long
    t = -1
    y = -1
    If TypeName(arr) = "Range" Then
        arr2 = arr.Value
    Else
        arr2 = arr
    End If
    On Error Resume Next
    t = UBound(arr2, 2)
    y = UBound(arr2, 1)
    On Error GoTo 0

    If t >= 0 And y >= 0 Then
        For c = LBound(arr2, 1) To UBound(arr2, 1)
            For d = LBound(arr2, 1) To UBound(arr2, 2)
                If arr2(c, d) <> "" Or Not skipblank Then
                    TEXTJOIN = TEXTJOIN & arr2(c, d) & delim
                End If
            Next d
        Next c
    Else
        For c = LBound(arr2) To UBound(arr2)
            If arr2(c) <> "" Or Not skipblank Then
                TEXTJOIN = TEXTJOIN & arr2(c) & delim
            End If
        Next c
    End If
    TEXTJOIN = Left(TEXTJOIN, Len(TEXTJOIN) - Len(delim))
End Function

Затем создайте настройку данных, которая выглядит следующим образом:

enter image description here

Столбец A содержит значение (точку данных), которая будет представлена ​​в сетке.Столбец B содержит общее количество, которое можно выбрать.

Таблица в V2: AK13 содержит строки, показывающие доступные значения из столбца A, разделенные | (это позволяет иметь точки данных в столбце A, которыепеременной длины, они не обязательно должны быть одним символом).Формула, используемая в ячейке V2 и копируемая снова и вниз:

=IFERROR(textjoin("|",TRUE,INDEX(REPT($A$2:$A$20,($B$2:$B$20-COUNTIF($D$1:$S1,$A$2:$A$20)-COUNTIF($C2:C2,$A$2:$A$20)>0)*((D1<>$A$2:$A$20)*(C2<>$A$2:$A$20))),)),"")

Наконец, для конечной выходной сетки, в ячейке D2 и копируемая снова и вниз, эта формула:

=IF(V2="","",TRIM(MID(SUBSTITUTE(V2,"|",REPT(" ",LEN(V2))),LEN(V2)*RANDBETWEEN(0,LEN(V2)-LEN(SUBSTITUTE(V2,"|","")))+1,LEN(V2))))

Вы можете скрыть столбцы U: AK, если хотите, или вырезать / вставить эту временную таблицу на другой лист.

Обратите внимание, что этот подход делает несколько предположений:

  • В дубликатах нетсоседние ячейки, где смежные определены как указано выше, ниже, влево или вправо (допустимы диагональные дубликаты)
  • Таблица результатов должна заполняться сначала слева направо, затем сверху вниз

ЕслиСмежный должен быть определен так, чтобы диагональные дубликаты также были запрещены, тогда формула в ячейке V2 и копируемая сверху и снизу становится такой:

=IFERROR(textjoin("|",TRUE,INDEX(REPT($A$2:$A$20,($B$2:$B$20-COUNTIF($D$1:$S1,$A$2:$A$20)-COUNTIF($C2:C2,$A$2:$A$20)>0)*((D1<>$A$2:$A$20)*(C2<>$A$2:$A$20)*(C1<>$A$2:$A$20)*(E1<>$A$2:$A$20))),)),"")

Если таблица результатов должна быть заполнена сверху вниз сначала, а затем слева доверно, формула в ячейке V2, скопированная снова и снова, становится такой:

=IFERROR(textjoin("|",TRUE,INDEX(REPT($A$2:$A$20,($B$2:$B$20-COUNTIF($C$2:C$13,$A$2:$A$20)-COUNTIF(D$1:D1,$A$2:$A$20)>0)*((D1<>$A$2:$A$20)*(C2<>$A$2:$A$20)*(C1<>$A$2:$A$20)*(C3<>$A$2:$A$20))),)),"")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...