Я боролся с
Это образец еженедельных данных, отображаемых в A2:D43021 на листе 1.
Лист2 в настоящее время выглядит так.
Я ищу единую формулу динамического массива для ячейки E2 Sheet2 (ячейка под датой 03.01.70).
Эта формула должна взять значения исполнителя и песни в этой строке и значение даты в этом столбце, найти строку на Листе 1 с этими значениями и вернуть соответствующее значение НА ЭТОЙ НЕДЕЛЕ.
Затем он должен распределить возвращаемые значения по всем строкам и всем столбцам, начиная с ячейки E2 листа 2.
На основе приведенного выше примера Лист1, Лист2 должен выглядеть следующим образом.
Я использовал Power Query для создания сводной таблицы, но мне хотелось бы выполнять больше вычислений непосредственно из Листа 1.
Мой компьютер слишком слаб, чтобы обрабатывать формулы поиска в каждой ячейке.
Я работал с версиями этой формулы для ячейки E2, но не могу понять логику заполнения как по вертикали, так и по горизонтали.
=LET(
data,'Sheet1'!A2:D43021,
artist, $C$2:$C$4557,
song, $D$2:$D$4557,
datehdr, $E$1:$TF$1,
BYROW(artist&song,
LAMBDA(row,
MATCH(
TRUE,
(row=INDEX(data,,2)&INDEX(data,,3))*(INDEX(datehdr,,1)=INDEX(data,,1)),
0
)
)
)
)
Любые предложения будут ценны.
О, ГБ, тебе нужны были только два последних столбца? РЖУ НЕ МОГУ!
Точно! После того, как я увидел, как все пытаются заполнить все столбцы, я понял, что нужно больше визуальных эффектов.
пожалуйста, попробуйте сейчас, я обновил ответы, а также ссылку!
Попробуйте использовать следующую формулу, используя LAMBDA()
вспомогательную функцию MAKEARRAY()
, она сгенерирует весь массив, как указано в вашем ОП:
• Формула, используемая в ячейке C1 из Sheet2
.
=LET(
_Data, Sheet1!A2:D15,
_ArtistSong, CHOOSECOLS(_Data,2,3),
_Uniq, UNIQUE(_ArtistSong),
_Date, TAKE(_Data,,1),
_Output, MAKEARRAY(ROWS(_Uniq),COLUMNS(DROP(C1:F1,,2)), LAMBDA(r,c,
TOROW(FILTER(TAKE(_Data,,-1), (INDEX(_Uniq,r,1)=INDEX(_ArtistSong,,1))*
(INDEX(_Uniq,r,2)=INDEX(_ArtistSong,,2))*(INDEX(DROP(C1:F1,,2),c)=_Date),"")))),
HSTACK(_Uniq, _Output))
Согласно новому обновлению OP:
=LET(
α, C2:D8,
δ, E1:F1,
MAKEARRAY(ROWS(α),COLUMNS(δ),LAMBDA(r,c,
FILTER(Sheet1!D2:D15,(INDEX(α,r,1)=Sheet1!B2:B15)*
(INDEX(α,r,2)=Sheet1!C2:C15)*(INDEX(δ,c)=Sheet1!A2:A15),""))))
Спасибо за решение по одной формуле. Когда я помещаю формулу в любое место диапазона Лист2 A1:D43021, это вызывает ошибку циклической ссылки. На Листе 2, если у меня уже настроен заголовок в строке 1, как можно отредактировать формулу, чтобы она возвращала данные только при размещении на Листе 2 C2?
@GBMedusa ну, тебе нужно будет удалить заголовки. Позвольте мне обновить то же самое!
@GBMedusa просто удалите эту часть, которая находится в конце: VSTACK(HSTACK(Sheet1!B1:C1,_UniqD),
и одну из последних скобок.
Удалить все заголовки или только те, что в C1:F1?
@GBMedusa видишь, я обновил, просто скопируй это
Формула по-прежнему создает циклическую ссылку.
@GBMedusa вы можете скачать Excel из здесь он не должен возвращать ошибку
@GBMedusa также попробуйте тот, который я сейчас обновил! Тот, который я обновил сейчас, нуждается в заголовках, как и у вас.
Спасибо за вашу помощь. Я заменил заголовок и поместил вашу формулу в ячейку C2. К сожалению, все еще получаю ошибку circ ref. Кроме того, невозможно получить доступ к файлу OneDrive. Я зайду позже, после работы.
@GBMedusa, но вы не должны получить ошибку. Нет, вы сохраняете заголовок, который написали вручную. ОК, и введите формулу в C2, формула теперь использует заголовок, а не встраивает в формулу TOROW(UNIQUE())
из фактического источника.
Еще одно действительно ленивое решение, которое я бы посоветовал использовать с осторожностью:
=CHOOSECOLS(WRAPROWS(TOROW(SORT(A2:D15,{2,3},1,FALSE)),8),{2,3,4,8})
Сначала отсортируйте данные по песне и имени исполнителя так, чтобы строка 1 — это 03.01.1970, строка 2 — 10.01.1970…
Затем используйте WRAPROWS
и TOROW
, чтобы изменить форму таблицы:
Наконец, используйте CHOOSECOLS
, чтобы сохранить соответствующие столбцы.
Отредактировано:
Поскольку эта формула основана на предположении, что каждый (исполнитель + песня) имеет две строки: одну для 03.01.1970, другую для 10.01.1970, если это не так, например, если один из (исполнитель + песня) имеет три даты или одна только одна дата, вся эта формула сломается.
И я увидел, что другие ответы справляются с этим правильно, поэтому решил потратить некоторое время на написание формулы, которая тоже справится с этим.
То есть, если у одного из артистов три свидания, это все равно сработает:
=LET(
data, A2:D16,
sorted_dates, SORT(UNIQUE(INDEX(data, , 1), FALSE, FALSE), 1, 1),
artists, INDEX(data, , 2),
songs, INDEX(data, , 3),
unique_artists_and_songs, UNIQUE(HSTACK(artists, songs), FALSE, FALSE),
rowNum, ROWS(unique_artists_and_songs),
colNum, ROWS(sorted_dates),
REDUCE(
HSTACK("Artist", "Song", TOROW(sorted_dates)),
SEQUENCE(rowNum, 1, 1, 1),
LAMBDA(a, i,
LET(
artist, INDEX(unique_artists_and_songs, i, 1),
song, INDEX(unique_artists_and_songs, i, 2),
filtered, FILTER(data, (artists = artist) * (songs = song), ""),
dates, INDEX(filtered, , 1),
ranks, INDEX(filtered, , 4),
sorted_ranks, MAP(sorted_dates, LAMBDA(d, XLOOKUP(d, dates, ranks, "", 0))),
result, HSTACK(artist, song, TOROW(sorted_ranks)),
VSTACK(a, result)
)
)
)
)
Не испытано. Но хорошо. Однако проверили ли вы четность нечета!
@MayukhBhattacharya, я думаю, что основная проблема с TOROW
+ WRAPROWS
заключается в том, что он основан на предположении, что каждый (исполнитель + песня) имеет две строки: одну для 03.01.1970, другую для 10.01.1970, если это не так это правда, например, если у одного из (исполнитель + песня) есть три даты или только одна дата, не только вся эта формула сломается, но и будет довольно сложно увидеть проблему.
Sheet2!A1
:=LET(data,Sheet1!A2:D43021,dcol,1,acol,2,scol,3,rcol,4,
headers,{"1ST DATE";"1ST POS";"ARTIST";"SONG"},
di,IF(data = "","",data),d,FILTER(di,CHOOSECOLS(di,dcol)<>""),
sd,CHOOSECOLS(d,dcol),sa,CHOOSECOLS(d,acol),
ss,CHOOSECOLS(d,scol),sr,CHOOSECOLS(d,rcol),
artist_song,UNIQUE(HSTACK(sa,ss)),
au,TAKE(artist_song,,1),su,DROP(artist_song,,1),
du,TOROW(UNIQUE(sd)),
h,HSTACK(TOROW(headers),du),
f_date,MAP(au,su,LAMBDA(a,s,XLOOKUP(1,(sa=a)*(ss=s),sd))),
f_pos,MAP(au,su,LAMBDA(a,s,XLOOKUP(1,(sa=a)*(ss=s)*(sr=1),sd,""))),
f_pos_count,MAP(au,su,LAMBDA(a,s,
IFERROR(ROWS(FILTER(sd,(sa=a)*(ss=s)*(sr=1))),))),
ranks,MAKEARRAY(ROWS(artist_song),COLUMNS(du),LAMBDA(r,c,
XLOOKUP(1,(sd=INDEX(du,c))*(sa=INDEX(au,r))*(ss=INDEX(su,r)),sr,""))),
r,VSTACK(h,HSTACK(f_date,f_pos,HSTACK(artist_song,ranks))),
r)
r
любой другой переменной, чтобы увидеть, что она содержит.MAKEARRAY
, вероятно, является наиболее эффективным способом решить вашу проблему, т. е. сосредоточиться на ranks
.Источник
Результат
Тяжелый раствор.
На самом деле это не так уж сложно, если даты динамичны. Я использую сокращение вместо makearray просто потому, что так проще писать. Я настолько привык к intelisense, что просто не могу привыкнуть писать сложные формулы самостоятельно.
@rachel с Heavy
я имею в виду хорошее решение. Не вес. На моем родном языке Heavy
означает, что на самом деле хебби, милый.
Другой вариант:
=LET(header, A1:D1,
data, A2:D15,
date,TAKE(data,,1), artist,INDEX(data,,2), song,INDEX(data,,3), notation,DROP(data,,3), unq,UNIQUE(HSTACK(artist,song)),
unqdate,TOROW(UNIQUE(date)), unqartist,TAKE(unq,,1), unqsong,DROP(unq,,1),
VSTACK(HSTACK("1ST "&{"DATE","POS"},
CHOOSECOLS(header,2,3),
unqdate),
HSTACK(XLOOKUP(unqartist&unqsong,artist&song,date),
XLOOKUP(unqartist&unqsong&1,artist&song¬ation,date,""),
unq,
WRAPCOLS(TOCOL(BYCOL(--REPT(notation,date&artist&song=TOROW(unqdate&unqartist&unqsong,,1)),LAMBDA(b,IFERROR(TOCOL(b,2),"")))),ROWS(unq),1))))
Когда вы меняете header
и data
в соответствии со своими потребностями, остальное адаптируется к этим диапазонам.
Я попробовал использовать самообъясняющие имена внутри LET.
По сути, он ищет первое свидание комбинации исполнителя и песни, затем он ищет первую дату обозначения номер 1, если это применимо. Затем к ним добавляются уникальные комбинации исполнителя/песни, а затем следуют их поворотные обозначения с использованием BYCOL/REPT.
Хороший пример использования BYCOL()
Я прошу прощения за то, что заставил всех работать усерднее, чем следовало бы. Я изменил свой вопрос, чтобы лучше объяснить ситуацию (надеюсь).