четверг, 27 августа 2015 г.

Сумма, автосумма и некоторые другие секреты LibreOffice Calc

Когда я начинал писать эту статью, я думал она будет коротенькой заметкой для начинающих. Но в процессе написания, я нашёл довольно много информации, которую стоит осветить в пределах данной темы. В итоге, статья выросла до достаточно больших размеров. И я надеюсь, что материал, изложенный здесь, будет полезен не только людям начинающим свой путь в применении Calc, но и для людей, которые уже давно пользуются электронными таблицами.

О чем будем говорить


Файл с примерами

Прикидка суммы

Если вам нужно просто «прикинуть» сумму какого-то диапазона, то в LibreOffice Calc можно воспользоваться встроенной возможностью. В строке состояния программы есть поле, в котором по умолчанию написано «Сумма=0». Если выбрать ячейки на листе с числовыми значениями, то вместо ноля, в этом поле будет отражаться сумма этих чисел. Для того чтобы выбрать ячейки отстоящие друг от друга, или диапазоны ячеек, можно их выделять зажав клавишу Ctrl. Минус этого способа в том, что он считает сумму только с текущего листа. Щёлкнув на поле правой кнопкой мыши, вы увидите список, представленный на скриншоте.

Скриншот меню в LibreOffice Calc

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

Сумма

В LibreOffice Calc функция сумма имеет тот же вид, что и в других электронных таблицах, таких как Excel или Apache OpenOffice. Её синтаксис выглядит следующим образом:

SUM(Число1; Число2; ...; ЧислоN)

В этом случае мы просто перечисляем числа через точку с запятой. Перечисления чисел может быть явным (1;2;3;...), может быть ссылками на ячейки (A1;C6;AZ190), а может быть смешанным (1; A1; C6;3). Функция будет «вынимать» числовое значение и использовать его.
Можно использовать функцию так:

SUM(Начало_диапазона:Конец_диапазона)

В этом случае мы должны указать первую и последнюю ячейку диапазона. Хочу заметить, для людей начинающих свой путь в электронных таблицах, если у нас диапазон занимает больше одной строки и одного столбца, то началом будет верхняя левая ячейка, а концом нижняя правая. Формула самостоятельно определит прямоугольник диапазона и рассчитает сумму.
Можно использовать даже так:

SUM(Название_именованного_диапазона)

Третий способ я вижу очень редко, однако он часто удобен. Выделите диапазон, пройдите в главном меню Данные → Задать диапазон… В поле название введите название нового диапазона. Обратите внимание на флажки «Заголовки в первой строке» и «Содержит строку итогов», первый из них установлен по умолчанию. Не забудьте снять или проставить их соответственно вашей ситуации. Нажмите OK. Теперь можно подставлять это название в формулы как аргумент вместо того, чтобы выделять диапазон мышкой.
Ещё один способ это использование заголовков столбцов или строк:

SUM(Заголовок_столбца)

Этот способ я вижу ещё реже, может потому, что по умолчанию эта возможность отключена. Если вы хотите использовать её, пройдите в главном меню Сервис → Параметры и в разделе LibreOffice Calc → Вычисления поставьте галочку «Автоматически определять заголовки столбцов и строк». Этот способ удобно использовать, когда диапазон занимает один столбец или строку, но вы не знаете насколько большим он будет. Но нужно помнить, что диапазон не должен прерываться, для LibreOffice Calc пустой ряд на всю ширину или высоту диапазона показывает, что диапазон закончился, и всё что дальше следует — это уже другой диапазон. На сегодняшний день (версия 5.0.0) функционал поиска заголовков не разработан до конца, например, он не переносит перетаскивания диапазона.
Хотя способов много, никто не запрещает использовать все способы одновременно, только не забывайте, что при указании диапазона между ссылкой на первую и последнюю ячейку в русской локализации по умолчанию ставится двоеточие, а между аргументами функции ставится точка с запятой. И я думаю, нет смысла напоминать о том, что ссылки могут быть не только на диапазоны в текущем листе, но и на другие листы, и даже на другие файлы, не важно на локальном компьютере они находятся или где-нибудь в сети.

Автосумма в LibreOffice Calc

Автосумма в LibreOffice Calc может выполнять автоматическое суммирование только непрерывного диапазона столбца или строки. При этом она будет искать диапазон по вертикали вверх и по горизонтали влево. Но так как, по существу, она просто вставляет формулу SUM с диапазоном как аргумент и оставляет её открытой для редактирования, то эта функция довольно часто бывает удобной, особенно, если вы предпочитаете работать мышкой. Использование её такое же, как и в других современных программах электронных таблиц. На панели формул есть значок с изображением греческой буквы сигма (Σ). Нажатие на этот значок активизирует автосумму.
Давайте разберём пример с вертикальным диапазоном из двух столбцов:

Автосумма в LibreOffice Calc

Выделив ячейку под вторым столбцом и нажав кнопку суммы мы видим, что функция нашла непрерывный диапазон в столбце, но не определила полный диапазон, и осталась в состоянии редактирования. На скриншоте видны маленькие синие квадратики по углам рамки диапазона. Если тянуть за эти квадратики мышкой, то можно изменить диапазон значений, участвующий в подсчетах формулы. То есть если нам нужно сделать так, чтобы в подсчетах участвовало два столбца, то мы можем потянув за левый верхний или нижний квадратик влево, включить второй столбец. Так же, мы можем сократить диапазон по вертикали, в том случае если у нас в подсчетах должен участвовать не весь вертикальный диапазон. Естественно, мы можем редактировать формулу напрямую, так, как это делали раньше, никто нам этого не запретит. Для горизонтальных диапазонов всё будет выглядеть точно также. Когда вас начнёт удовлетворять диапазон, нажмите на клавиатуре Enter, или зелёную галочку на панели формул.

SUM как формула массива и суммирование по условию

В справке к программе (пройдите в главном меню Справка → Справка по LibreOffice, или нажмите клавишу F1) или на сайте онлайн справки вы можете найти пример нестандартного использования функции SUM. На мой взгляд это очень удачный пример, и я хотел бы вам его пересказать своими словами.
Допустим у нас есть таблица: в первом её столбце идут даты, а во втором — наши расходы за этот день, ведь мы можем сделать такую таблицу, нам её хватит на 2845 лет :). Но мы хотим узнать сколько мы потратили за какой-то конкретный месяц, или неделю, или год. То есть нам нужно просуммировать расходы за определённый период. Я прилагаю файл с примером, чтобы вы смогли посмотреть как это всё устроено. А здесь я объясню всё словами. Так выглядит таблица:

Sum как формула массива и поиск по условию в LibreOffice Calc

В ячейке I2 написана формула

=SUM((A3:A300>=F1)*(A3:A300<=F2)*B3:B300)

Первая часть A3:A300>=F1 — это условие выше какой даты будут суммироваться числа, вторая часть A3:A300<=F2 — ниже какой даты. A3 — это начало диапазона дат, A300 — это конец диапазона, для примера 300 даже много, в реальности это будет предполагаемая ячейка, докуда вы хотите вести свой диапазон. Перемножая эти две части мы получаем матрицу истинности, где те числа, которые соответствуют необходимым датам будут равны 1, а остальные 0. В третьей части мы имеем массив с расходами и естественно, если мы умножаем на ноль, то в ответе будет ноль, а если на единицу, то значение будет равно значению ячейки. Таким образом мы получаем матрицу с нулями и необходимыми значениям. То есть, если это всё представить в развернутом виде, то будет примерно так SUM(0;0;…;0;отобранные значения; 0; 0; …; 0). Для того чтобы эта формула начала работать, мы должны её сделать формулой массива, для этого, вместо обычного нажатия Enter нам нужно нажать сочетание Ctrl+Shift+Enter. Знаком, что вы всё сделали правильно, будет заключение формулы в фигурные скобки
{=SUM((A3:A300>=F1)*(A3:A300<=F2)*B3:B300)}

Не выставляйте скобки сами своими руками — это не поможет, необходимо правильно завершить ввод формулы. Если вы используете автоматический поиск заголовков в столбцах и строках, то эту формулу можно переписать следующим образом:

=SUM((('Дата')>=F1)*(('Дата')<=F2)*('Расходы'))

Завершив введение Ctrl+Shift+Enter, мы получим тот же результат, но нам не придётся заботиться о величине диапазона, а главное легко его менять и автоматически получать обновленный результат. Эффекта этого примера, поиска по нескольким условиям, можно также достичь при помощи формулы SUMIFS. Приведу ещё один пример. В начале 2011 года был открыт отчет об ошибке 35636, связанный с тем, что формула SUMIF не принимала как условие пусто (""). Исправили эту ошибку только в апреле 2015 года. Одним из способов обхода этой проблемы было использование формулы SUM как формулы массива в таком виде:

=SUM((Диапазон_для_суммирования)*(Диапазон_для_проверки=""))

Я думаю, понятно, что во втором параметре будет создаваться матрица истинности, умножение на которую все ненужные значения превращает в ноль, и, в итоге, мы получаем сумму значений, соответствующих пустым ячейкам.

Автоматическое расширение диапазона при добавлении ячейки в конец

LibreOffice Calc при добавлении ячейки в середину диапазона, автоматически расширяет его в параметре формулы. Но если мы сделаем сумму этих ячеек в конце диапазона, например, используя атосумму, а затем попытаемся в конец суммируемого диапазона добавить ячейку, то Calc не включит её в сумму. Чтобы обойти это ограничение можно использовать ссылку на конец диапазона функцией OFFSET. Я не буду останавливаться на этой функции подробно, приведу только её синтаксис и объяснения, необходимые для этого примера.

OFFSET(Ссылка; Строки; Столбцы; Высота; Ширина)

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

Автоматическое расширение диапазона формулой OFFSET в LibreOffice Calc

=SUM(A2:OFFSET(A6;-1;0))

Использование автоматического поиска по заголовкам столбцов или строк, работает не совсем так как ожидается. Ставить формулу вплотную к диапазону нельзя. Кроме того, добавлять строку или ячейку необходимо не со строки формулы, а с пустой ячейки между формулой и диапазоном. Как вы понимаете, это недоработка, которая не приносит ожидаемый результат и не позволяет использовать инструмент интуитивно. Для нашего примера формула будет выглядеть так:

=SUM('Сумма')

Сумма накопленным итогом

Сумма накопленным итогом — это одна из самых частых решаемых задач, особенно в моделях инвестиционных проектов. Сделать её можно по разному, но на мой взгляд самый удобный способ — закрепить часть диапазона в функции SUM и протянуть её. Допустим у нас есть денежный поток — деньги, выданные на карманные расходы ребёнку (незапланированные операционные затраты :)

Сумма накопленным итогом в LibreOffice Calc

В ячейку B4 вписываем формулу, указывая границы диапазона B3:B3, и закрепляем первую часть, нажав Shift+F4 на клавиатуре (когда курсор установлен на первой части): =SUM($B$3:B3) При протягивании, первая ячейка, указывающая на начало диапазона, останется на месте, а вторая (конец диапазона) будет автоматически изменяться, в каждой новой ячейке образуя сумму всех предыдущих значений.

Суммирование трехмерных диапазонов (сквозное суммирование)

Когда ряд листов нашей книги электронных таблиц имеет одинаковую разметку, мы можем использовать трёхмерный диапазон для суммирования, иногда на форумах эту операцию называют «сквозное суммирование». Для трёх листов сложение 3 ячеек A1 выглядит следующим образом:

=SUM(Лист1.A1:Лист3.A1)

Если же мы складываем диапазоны, то это будет выглядеть так:

=SUM(Лист10.A1:B2:Лист11.A1:B2)
Обратите внимание, что листы, для которых проводится суммирование, должны стоять рядом. Первым в формуле должен быть указан крайний левый лист, а последним крайний правый из диапазона листов для суммирования.

SUMIF — суммирование по условию

Если нам необходимо сложить числа, отвечающие какому-то одному заданному условию, то самый простой способ — это использовать функцию SUMIF(). Синтаксис функции следующий:

SUMIF(Диапазон_для_условия; Условие; Диапазон_суммирования)

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

=SUMIF('Денежный поток';">0";'Денежный поток')

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

=SUMIF(Диапазон для поиска;"";Диапазон суммирования)

Как вы понимаете, диапазон мы можем задавать всеми возможными способами: поиск по заголовку, именованный диапазон, просто указав границы диапазона, даже если диапазон находится в другом файле где-нибудь в сети интернет.

Использование регулярных выражений в условии

Поиск по условию в LibreOffice Calc поддерживает регулярные выражения. Запись регулярных выражений отличается от записи их в Excel и немного отличается от привычной записи их в shell. Подробно о регулярных выражениях рассказано на странице справки, также я касался их, когда рассказывал о применении функций VLOOKUP и HLOOKUP.
Чаще всего приходится считать сумму чего-либо одного вида (например, остатки, приход или продажи карандашей, тетрадок). Сделаем простую таблицу, с заголовками Товар и Количество, для названия товаров и их количества соответственно.


Регулярные выражения в формуле в LibreOffice Calc

Задача посчитать карандаши (27 штук, но в уме не считаем, считаем формулами :). Итак, из выше изложенного понятно, что нам нужно использовать регулярные выражения в условии. Общим фрагментом текста для всех названий карандашей является слово карандаш. И так как у нас есть символы до общего фрагмента и после, то мы должны это указать. Регулярное выражение будет выглядеть так: ".*карандаш.*". Точка (.) тут будет означать любой символ, звёздочка (*) любое количество символов. Порядок точка-звёздочка обязательный, если вы забудете поставить точку, то будет выдана ошибка, такова специфика регулярных выражений в Calc. Формула для такой таблицы будет выглядеть:

=SUMIF(A2:A6;".*карандаш.*";B2:B6)

Более продвинутым способом будет регулярное выражение со ссылкой на ячейку, в которой будет задаваться ключевое слово (вводится руками, или выбирается из списка). Допустим что искомое значение задаётся в ячейке D1:

=SUMIF(A2:A6;".*"&D1&".*";B2:B6)

Одно замечание. На сегодняшний день существует ошибка 93510, которая не позволяет использовать регулярные выражения совместно с функцией автоматического поиска заголовков в столбцах и строках, если диапазон состоит из слов. Независимо от значений в диапазоне суммирования, функция всегда возвращает 0. Скорее всего эта ситуация возникает из-за того, что LibreOffice Calc не правильно расставляет приоритеты для заголовков. Обойти эту ошибку можно, если между заголовком и началом значений будет пустая строка, или более элегантный метод, использовать для заголовков объединённые ячейки.

SUMIFS — поиск по многим условиям

В отличии от функции SUMIF функция SUMIFS позволяет задавать от одного до 30 условий. Её синтаксис:

SUMIFS(Диапазон_суммирования;Диапазон_для_условия1; Условие1;…;Диапазон_для_условия30; Условие30)

Я думаю вы понимаете, что в диапазоне суммирования будет стоять диапазон значений, из которого мы хотим складывать числа. Диапазон условия — это там, где мы будем искать. Диапазоны условия и суммирования могут быть одинаковые или разные. Условие — это то, что мы ищем (не забывайте заключать выражение в прямые кавычки(""). Формула предоставляет возможность избыточного количества условий, думаю, 30 диапазонов и условий, хватит на все случаи жизни. Пример, который я давал, когда рассказывал про SUM как формулу массива, можно переписать так:

=SUMIFS('Расходы';'Дата';">="&F1;'Дата';"<="&F2)

SUBTOTAL — сумма видимых ячеек или промежуточные итоги

Иногда возникает необходимость посчитать сумму отобранных (видимых) ячеек автофильтром. Самый простой способ в LibreOffice Calc, на мой взгляд, использовать функцию SUBTOTAL(). Эта функция позволяет сделать намного больше, но в рамках этой статьи я покажу только сумму. Остальной функционал её можно посмотреть в справке. Допустим у нас есть большая таблица, в которой мы делаем выборку и хотим получить сумму. Для примера мы возьмём довольно простой вариант:

Сумма видимых ячеек в LibreOffice Calc

Конечно мы может воспользоваться SUMIF, SUMIFS или даже формулой массива, но если мы используем фильтры, то самый простой способ использовать SUBTOTAL. Её синтаксис выглядит так:

SUBTOTAL(Номер_функции; Диапазон)

Номер функции — это номер, за которым закреплена функция используемая для диапазона. Для нашего случая, это 9. Диапазон — это диапазон, к которому нужно применить функцию. В нашем случае, это диапазон для суммирования. В итоге формула, вписанная в ячейку B10, будет выглядеть так:

=SUBTOTAL(9;B2:B9)

Если вы добавляете строки в диапазон, то для автоматического расширения диапазона при добавлении ячейки в конец, можно воспользоваться советом приведённом выше для формулы SUM. Теперь, когда мы будем фильтровать необходимые строки, в ячейке с формулой будет появляться их сумма. Единственное замечание: не забывайте оставлять галочку на пункте «пусто», а то скроется и сам результат.
В справке не указано, но на самом деле это работает: когда мы используем SUBTOTAL без фильтра, то функция с кодами, указанными в справке, не исключает скрытые строки из расчета. Чтобы исключить их, добавьте перед кодом функции 10. То есть для суммы код 9 не будет исключать скрытые строки, а 109 будет. После скрытия пересчитайте результат нажатием Ctrl+Shift+F9. Обратите внимание, функция SUBTOTAL не включает в расчет ячейки, содержащие предварительные итоги (эту же функцию). Другим способом для решения этих задач может быть использование функции AGGREGATE.

AGGREGATE — суммирование с пропуском скрытых ячеек и ячеек с ошибками

В прошлом примере было показано как суммировать диапазон, исключая скрытые ячейки, но бывают ситуации, когда нужно исключить ещё и ячейки с ошибками или с функциями SUBTOTAL и самой AGGREGATE. Функция AGGREGATE имеет ещё больше возможностей чем SUBTOTAL. Ниже я даю описание её, но так как некоторые параметры этой функции к теме этой статьи не относится, я их не буду касаться. И так как она, к сожалению, до сих пор не описана в справке, если вам нужно уточнить что-то по ней, то лучше пока будет воспользоваться справкой Excel (ну, должны же мы хоть что-то полезное получать от корпорации MS :).
В рамках этой статьи нам интересен следующий синтаксис функции:

AGGREGATE(Номер_функции; Параметры; Диапазон)

Номер_функции — это номер, за которым закреплена функция, использующаяся для диапазона. Для задач этой статьи это номер 9 — сумма.
Параметр — числовое значение, определяющее какие значения при вычислении следует пропускать. Все параметры пронумерованы от 1 до 7. Следующий список показывает номер и краткое описание функции:
  • 0 или опущен — пропускать вложенные функции SUBTOTAL и AGGREGATE.
  • 1 — пропускать скрытые строки и вложенные функции SUBTOTAL и AGGREGATE.
  • 2 — пропускать значение ошибок и вложенные функции SUBTOTAL и AGGREGATE.
  • 3 — пропускать скрытые строки, значения ошибок и вложенные функции SUBTOTAL и AGGREGATE.
  • 4 — ничего не пропускать.
  • 5 — пропускать только скрытые строки.
  • 6 — пропускать только значения ошибок.
  • 7 — пропускать скрытые строки и значения ошибок.
Диапазон — это диапазон ячеек, к которым нужно применить функцию.
Как вы видите, эту функцию можно настроить как нам нравится, но есть и один недостаток. Она умеет работать только со скрытыми строками, и не умеет со скрытыми столбцами. Функции и коды ошибок она позволяет игнорировать как в строках, так и в столбцах.

Файл с примерами

Дополнительная литература и источники: