Если у вас 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
Затем создайте настройку данных, которая выглядит следующим образом:
Столбец 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))),)),"")