Самый простой способ запросить несколько листов, названных по годам, за все время? - PullRequest
1 голос
/ 19 июня 2020

Я использую большую неприятную формулу для запроса нескольких листов в одном документе Google Sheet с указанием года (2020, 2019, 2018, и т. Д. c ...), чтобы подвести итоги. Поскольку мне нужно запросить отфильтрованный диапазон сложным способом, я выяснил, что лучший способ сделать это, не сталкиваясь с другими проблемами устранения неполадок, - это СУММ нескольких запросов, например:

= СУММ ( ЕСЛИОШИБКА (QUERY (FILTER ({EOMONTH (INDIRECT ("'" & ** TO_TEXT (YEAR (TODAY ())) & "'! A1: A" & ROWS (INDIRECT ("'" & TO_TEXT ( ГОД (СЕГОДНЯ ())) & "'! K2: K"))), 0), КОСВЕННО ("'" & TO_TEXT (ГОД (СЕГОДНЯ ())) & "'! K2: K ")}, [условия фильтрации])," выберите Col2 label Col2 '' ")), IFERROR (QUERY (FILTER ({EOMONTH (INDIRECT (" '"& TO_TEXT (YEAR (TODAY () - 365)) & "'! A1: A" & ROWS (INDIRECT ("'" & TO_TEXT (YEAR (TODAY () - 365)) & "'! K2: K"))) , 0), INDIRECT ("'" & TO_TEXT (YEAR (TODAY () - 365)) ** & "'! K2: K")}, [условия фильтра]), "выберите Col2 label Col2 '' ")) )

Для некоторого контекста вы можете увидеть гораздо более крупную формулу ЕСЛИ, в которую должна быть вложена эта СУММ, на вкладке «Пример матрицы» листа. Мое внимание в этом вопросе уделяется КОСВЕННЫМ ссылкам, которые я использовал для динамических ссылок на лист за текущий год и за предыдущий год. Проблема в том, что если я хочу продолжать делать это для каждого листа в течение go лет, мне придется вручную добавить целый другой запрос в мою СУММ, используя INDIRECT ("'" & TO_TEXT (YEAR (TODAY () - 730 )) & «'! K2: K») и INDIRECT («'» & TO_TEXT (YEAR (TODAY () - 1095 )) & «'! K2: K») и т. Д. включен, и это просто не вариант, учитывая, сколько из них мне нужно было бы добавить в несколько формул на нескольких листах.

Есть ли способ адаптировать это для простоты или, возможно, превратить его в сценарий, выполнено sh суммирование запросов для всех листов, которые названы по годам за все время?

Вот копия моего примера листа: https://docs.google.com/spreadsheets/d/1b29gyEgCDwor_KJ6ACP2rxdvauOzacDI9FL2K-jgg5E/edit#gid = 1652431688

Спасибо Любая помощь приветствуется.

1 Ответ

2 голосов
/ 19 июня 2020

Обычно формула массива может быть способом go в таком случае, но INDIRECT не работает внутри формул массива.

Есть несколько подходов с использованием сценариев, таких как this .

Здесь я опишу другой подход: генерация формулы . Получим строку с формулой и вручную поместим ее в ячейку. Было бы неплохо поместить его в инвертированную функцию FORMULATEXT, но, к сожалению, на данный момент такой функции нет, поэтому мы просто вставим ее вручную.

Шаг 1

Установите ограничения по годам (названия листов) в некоторых ячейках. Первый год периода будет в K22, а последний - в M22.

Я установил период с 2005 по 2040 год.

Все номера года будут e легко генерируется с помощью SEQUENCE. Если бы были произвольные имена, потребовался бы диапазон этих имен, заданных вручную.

Шаг 2

Напишите генератор формул для того, что вам нужно. Здесь мы просто генерируем строку, в которой будет формула, которую вы обычно вводите вручную. Это несложно, но повторений много, и было бы утомительно писать его вручную.

Вот генератор:

=ARRAYFORMULA(
  "=SUM(
  FILTER(
    {
      " & JOIN(
            ";" & CHAR(10) & "      ",
            "IFERROR('" & SEQUENCE(M22 - K22 + 1, 1, K22, 1) & "'!D2:D, 0)"
          ) & "
    },
    ISNUMBER(
      {
        " & JOIN(
              ";" & CHAR(10) & "        ",
              "IFERROR('" & SEQUENCE(M22 - K22 + 1, 1, K22, 1) & "'!D2:D, 0)"
            ) & "
      }
    ),
    REGEXMATCH(
      {
        " & JOIN(
              ";" & CHAR(10) & "        ",
              "IFERROR('" & SEQUENCE(M22 - K22 + 1, 1, K22, 1) & "'!A2:A, 0)"
            ) & "
      },
      ""(?i)^TOTAL$""
    ),
    REGEXMATCH(
      {
        " & JOIN(
              ";" & CHAR(10) & "        ",
              "IFERROR('" & SEQUENCE(M22 - K22 + 1, 1, K22, 1) & "'!C2:C, 0)"
            ) & "
      },
      ""(?i)^"" & IF(F19 = ""Condition 1 Count"", ""Condition 1"", ""Condition 2"") & ""$""
    )
  )
)"
)

По сравнению с исходной формулой полученная формула сильно изменен, упрощен. Например, при этом подходе нет реальной необходимости в INDIRECT, EOMONTH нигде не использовалось и т. Д.

Шаг 3

Скопируйте этот результат как текст, удалите заключительные кавычки замените двойные двойные кавычки на одинарные двойные кавычки: "" -> ".

Теперь у нас есть формула, которую нужно вставить куда-нибудь, как мы могли бы ввести вручную. Вот его часть:

=SUM(
  FILTER(
    {
      IFERROR('2005'!F2:F, 0);
      IFERROR('2006'!F2:F, 0);
      ...
      IFERROR('2039'!F2:F, 0);
      IFERROR('2040'!F2:F, 0)
    },
    ISNUMBER(
      {
        IFERROR('2005'!F2:F, 0);
        IFERROR('2006'!F2:F, 0);
        ...
        IFERROR('2039'!F2:F, 0);
        IFERROR('2040'!F2:F, 0)
      }
    ),
    REGEXMATCH(
      {
        IFERROR('2005'!C2:C, 0);
        IFERROR('2006'!C2:C, 0);
        ...
        IFERROR('2039'!C2:C, 0);
        IFERROR('2040'!C2:C, 0)
      },
      "(?i)^TOTAL$"
    ),
    REGEXMATCH(
      {
        IFERROR('2005'!E2:E, 0);
        IFERROR('2006'!E2:E, 0);
        ...
        IFERROR('2039'!E2:E, 0);
        IFERROR('2040'!E2:E, 0)
      },
      "(?i)^" & IF(F19 = "Condition 1 Count", "Condition 1", "Condition 2") & "$"
    )
  )
)

Шаг 4

Вручную поместите полученную формулу в какую-нибудь ячейку.

Он делает то, что должен делать, выпадающие ссылки работают, несуществующие листы допускаются.

Например, 2021 листа нет, но когда он будет в ящике нет необходимости изменять формулу, будут использоваться данные из этого нового листа.

Вам нужно будет повторить процесс в двух случаях: формулу нужно изменить в logi c или почти 2040 год, и вы хотите добавить к этому периоду еще 50 лет. Тем не менее, этот процесс генерации быстрее, чем внесение изменений в получившегося монстра вручную.


Несколько примечаний к исходной формуле:

  • YEAR(TODAY() - 365)YEAR(TODAY()) - 1. При вашем подходе будет ошибка из-за високосных лет. Зависит от числа лет, но в начале года обязательно появится.
  • "select Col2 label Col2' ' ""select Col2 label Col2 ''". Вам действительно нужен столбец с названием заголовка ' ' (просто пробел)? Я предполагаю, что это должно было быть пустым.
  • Не нужно TO_TEXT.
...