Как создать массив для последовательности месяцев между двумя датами?

У меня есть 2 столбца; дата начала и дата окончания, и я хотел бы создать последовательность месяцев между двумя датами.

Я могу сделать это, используя формулу, а затем скопировав формулу по всему столбцу.

=TEXTJOIN(",",TRUE,SEQUENCE(1,MONTH(B2)-MONTH(A2)+1,MONTH(A2),1))

Однако я бы хотел, чтобы это было создано как массив. Я пробовал следующее, но, похоже, это не работает:

=BYROW(A2:B4,LAMBDA(a,TEXTJOIN(",",TRUE,SEQUENCE(1,MONTH(CHOOSECOLS(a,2))-MONTH(CHOOSECOLS(a,1))+1,MONTH(CHOOSECOLS(a,1)),1))))

Что я здесь делаю не так?

Каков ваш ожидаемый результат для [Start Date]='01/11/2023' и [End Date]='31/03/2024'?

Chronocidal 08.07.2024 14:39

Привет @Chronocidal, почему бы тебе не опубликовать ответ? По вопросу, который вы задали ОП?

Mayukh Bhattacharya 08.07.2024 15:27

@MayukhBhattacharya Я не опубликовал ответ на этот вопрос отчасти потому, что, в зависимости от варианта использования, ОП может захотеть 11,12,1,2,3; или ОП может потребовать 11,12,13,14,15. Все зависит от того, как они используют данные и как это влияет на перенос лет. Вот почему я изначально просто попросил разъяснений

Chronocidal 09.07.2024 09:11
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
3
97
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Попробуйте использовать следующую формулу:


=BYROW(MONTH(A2:B4),LAMBDA(α, LET(δ, INDEX(α,1), TEXTJOIN(",",,SEQUENCE(INDEX(α,2)-δ+1,,δ)))))

Обновлено: использование CHOOSECOLS() также возможно, только если это функция массива, вам нужно будет использовать неявный оператор пересечения, чтобы Excel осознал, что пользовательский LAMBDA() должен применяться к каждой строке, а при использовании INDEX() это не требуется, поскольку он принимает строку ссылка на столбцы. Кроме того, при использовании @ требуется один дополнительный ключ, а при использовании INDEX() — нет!


=BYROW(MONTH(A2:B4),LAMBDA(α,
 LET(δ,@CHOOSECOLS(α,1),TEXTJOIN(",",,
 SEQUENCE(@CHOOSECOLS(α,2)-δ+1,,δ)))))

Приложение: если у вас есть более старые даты, которые не относятся к одному и тому же году, то приведенное выше значение обязательно вернет ошибку, поэтому используйте следующее:


• Использование INDEX():

=BYROW(A6:B12,LAMBDA(α, LET(δ, INDEX(α,1), 
 TEXTJOIN(",",,MONTH(UNIQUE(TEXT(SEQUENCE(INDEX(α,2)-δ+1,,δ),"mmm e")))))))

• Использование CHOOSECOLS():

=BYROW(A6:B12,LAMBDA(α, LET(δ, @CHOOSECOLS(α,1), 
TEXTJOIN(",",,MONTH(UNIQUE(TEXT(SEQUENCE(@CHOOSECOLS(α,2)-δ+1,,δ),"mmm e")))))))

Обходной путь путем принуждения к одиночному (значению)

Я еще не до конца это понял, но при использовании CHOOSECOLS, TAKE и т. д. с некоторыми функциями, такими как SEQUENCE, TEXTJOIN и т. д., обрабатывайте входные данные как столбцы и возвращайте только первый столбец. Самый простой обходной путь — преобразовать параметр в одно значение. Например, в вашем случае мы могли бы использовать SUM(....

Вот несколько вариантов, для интереса :)

С вашим оригиналом:

=BYROW(
    A2:B4,
    LAMBDA(a,
        TEXTJOIN(
            ",",
            TRUE,
            SEQUENCE(
                1,
                SUM(
                    MONTH(CHOOSECOLS(a, 2)) -
                        MONTH(CHOOSECOLS(a, 1)) + 1
                ),
                SUM(MONTH(CHOOSECOLS(a, 1))),
                1
            )
        )
    )
)

Или

=BYROW(
    MONTH(A2:B4),
    LAMBDA(a,
        LET(
            start, SUM(TAKE(a, , 1)),
            end, SUM(TAKE(a, , -1)),
            ARRAYTOTEXT(SEQUENCE(end - start + 1, , start))
        )
    )
)

Функция MAP обычно больше подходит для подобных ситуаций, поскольку она может перебирать несколько столбцов одновременно, устраняя необходимость в дополнительных функциях, таких как CHOOSECOLS или INDEX.

=MAP(MONTH(A2:A4), MONTH(B2:B4), LAMBDA(ms,me, TEXTJOIN(",",, SEQUENCE(, me-ms+1, ms))))

Кроме того, если ваши даты начала и окончания охватывают несколько лет, вы можете изменить формулу следующим образом:

=MAP(MONTH(A2:A4), YEAR(A2:A4), MONTH(B2:B4), YEAR(B2:B4),
   LAMBDA(ms,ys,me,ye, TEXTJOIN(",",, MONTH(DATE(ys, SEQUENCE(, me-ms+(ye-ys)*12+1, ms), 1)))))

Для получения дополнительной информации о различиях между BYROW или BYCOL и MAP см.:

Вот версия, в которой не используются LAMBDA или SEQUENCE (но используется TEXTJOIN), что может сделать ее совместимой с другими версиями Excel.

Это также будет работать в разные годы, но для января месяц будет установлен на 1:

=LET(dStart, A1, dEnd, B1, yDiff,YEAR(dEnd)-YEAR(dStart),mStart,MONTH(dStart),mEnd,MONTH(dEnd)+(yDiff*12),TEXTJOIN(",",TRUE,1+MOD(ROW(INDEX($A:$A,mStart):INDEX($A:$A,mEnd))-1,12)))

Однако, удалив все MOD части кода, вы можете сохранить месяц как 13 для января при переносе месяца:

=LET(dStart, A1, dEnd, B1, yDiff,YEAR(dEnd)-YEAR(dStart),mStart,MONTH(dStart),mEnd,MONTH(dEnd)+(yDiff*12),TEXTJOIN(",",TRUE,ROW(INDEX($A:$A,mStart):INDEX($A:$A,mEnd))))

Другие вопросы по теме