Как просуммировать данные с нескольких листов, в том числе по условию
Достаточно распространенная ситуация: в книге ведутся данные по продажам, разбивая каждый месяц на отдельный лист с именем месяца. Т.е. в листах
- вбиваем в итоговую ячейку функцию
СУММ (SUM) - для указания аргументов переходим на первый лист, данные которого необходимо суммировать
- далее зажимаем клавишу
Shift и выделяем последний лист(если необходимо выделить несмежные листы – зажимаем клавишуCtrl ) - указываем адрес ячейки для суммирования и жмем
Enter
Подобная ссылка на диапазоны называется трехмерной ссылкой. Если между листом
После того, как введем такую функцию в ячейку, Excel сам подставит в правильном виде имена всех листов для суммирования, даже если они идут не по порядку. Т.е. лист суммирования не обязательно должен быть в самом начале книги или в конце - он может быть и в середине - функция его автоматически уберет из суммирования в момент ввода функции.
Звездочка в данном случае является подстановочным символом, который заменяет собой любое количество любых символов. Т.е. в данном случае, как бы говорящим Excel: имя листа может быть любым. Поэтому, если надо суммировать только конкретные ячейки, но не со всех листов, а только с листов, начинающихся со слова "Отчет" - можно функцию записать так:
Зная этот прием, можно заранее подготовить книгу, чтобы имена листов имели такие названия, по которым можно будет суммировать данные только с нужных в зависимости от ситуации(например, для каждой категории листов свое обозначение: "-год-","-месяц-","-квартал-" и т.п.).
Минус такой функции в том, что таким образом можно просуммировать данные только ячеек листа, расположенных в одном и том же диапазоне(т.е. со всех листов будет взята сумма всех ячеек конкретного диапазона - в примере будут просуммированы данные из одной ячейки
А значит, если необходимо будет просуммировать данные по отдельным товарам со всех листов, а товары расположены в каждом листе в хаотичном порядке, разном для каждого листа и количество строк различается - такая формула не подойдет. Но можно воспользоваться чуть более сложной формулой:
"Январь":"Февраль":"Март":"Апрель":"Май":"Июнь" - имена листов, с которых происходит суммирование. Важно помнить, что имена листов должны быть точь-в-точь как в книге(со всеми пробелами, точками и запятыми), иначе будет ошибка. Не буду останавливаться подробно на всех вложенных функциях. ПроСУММЕСЛИ можно прочитать в этой статье.(SUMIF) ДВССЫЛ используется для создания ссылки на диапазон, состоящей из имени листа и адреса ячеек:(INDIRECT) Январь!B3:B100, Февраль!B3:B100, Март!B3:B100, Апрель!B3:B100, Май!B3:B100, Июнь!B3:B100 . Т.е. мы в формуле перебираем все указанные листы, создаем диапазоны в каждом из них и суммируем на основании критерия при помощи СУММЕСЛИ. А при помощиСУММПРОИЗВ суммируем полученные от СУММЕСЛИ результаты в единое число.(SUMPRODUCT)
Важно: если в имени листа встречается пробел, либо иной знак препинания, то имя листа необходимо заключать в апострофы:" ' Январь 2014' ":"' Февраль 2014' ":"Март":"Апрель":"Май":"Июнь"
либо ставить апострофы заранее для всех листов:
ДВССЫЛ(" ' "&{"Январь":"Февраль":"Март":"Апрель":"Май":"Июнь"}&"' !C3:C100")B3:B100 - диапазон в каждом листе, в котором искать критерий (при необходимости указать больше строк)B3 - ссылка на ячейку в итоговом листе, содержащую критерийC3:C100 - диапазон в каждом листе, ячейки из которого надо суммировать (при необходимости указать больше строк)
В чем главное неудобство - необходимо так или иначе указывать листы, с которых суммировать. Если листов много, то перечислить их все в формуле будет не так-то просто. В таком случае можно записать имена листов в отдельный диапазон и ссылаться на него в формуле(формула в данном случае получается более универсальной и короткой):
Но и она имеет свои недостатки:
- нельзя указать диапазон имен листов "с запасом". Т.е. если у нас имена листов записаны в диапазоне
, то нельзя в формуле указатьH3:H8 H3:H10 - в диапазоне с перечислением листов не должно быть пустых ячеек
- в диапазоне с перечислением листов не должно быть имен листов, которые заведомо отсутствуют в книге. Например, если имя листа записано с опечаткой
Если хоть одно из этих условий не выполняется - формула вернет ошибку
Плюс иногда именно перечисление листов напрямую в формуле удобнее. Например, если нет возможности выделить для этого отдельный диапазон.
Поэтому во вложении ниже эта формула представлена в двух вариантах: со статичным перечислением имен листов и с использованием дополнительного столбца для перечисления листов. А какую именно использовать - придется решать по ситуации.
Суммировать со всех листов.xls (134,0 KiB, 13 499 скачиваний)
Возможно, есть и иные способы суммирования формулой. Может даже есть способ суммировать, не указывая имена листов, но у меня не получилось так сделать без использования VBA. Поэтому я написал свою пользовательскую функцию:
'--------------------------------------------------------------------------------------- ' Function : СУММЕСЛИ_ВСЕ_ЛИСТЫ ' Purpose : Функция суммирует на основании критерия значения со всех листов, кроме листа с функцией ' Диапазон - ссылка на диапазон ячеек для поиска критерия ' Критерий - значение, на основании которого суммировать данные ' ДиапазонСуммирования - ссылка на диапазон ячеек, значения которых суммировать ' ВсеЛисты - 1(по умолчанию) - суммирование происходит со всех листов, кроме листа с функцией ' 0 - суммирование происходит только в листах, расположенных левее листа с функцией '--------------------------------------------------------------------------------------- Function СУММЕСЛИ_ВСЕ_ЛИСТЫ(Диапазон As Range, Критерий, ДиапазонСуммирования As Range, Optional ВсеЛисты As Boolean = True) Dim wsSh As Worksheet Dim wbFunc As Workbook Dim sRange As String, sSumRange As String Dim dblSum As Double Dim rRange As Range, rCriteria As Range, rSumRange As Range, bAllSh As Boolean Set rRange = Диапазон If IsObject(Критерий) Then Set rCriteria = Критерий Else rCriteria = Критерий End If Set rSumRange = ДиапазонСуммирования bAllSh = ВсеЛисты 'определяем книгу, в которой записана функция Set wbFunc = Application.Caller.Parent.Parent 'определяем адреса поиска критерия и суммирования sRange = rRange.Address sSumRange = rSumRange.Address 'цикл по всем листам книги с функцией For Each wsSh In wbFunc.Worksheets If bAllSh Then 'если это не лист с функцией If wsSh.Name <> Application.Caller.Parent.Name Then dblSum = dblSum + Application.SumIf(wsSh.Range(sRange), rCriteria, wsSh.Range(sSumRange)) End If Else 'если лист ДО листа с функцией If wsSh.Index < Application.Caller.Parent.Index Then dblSum = dblSum + Application.SumIf(wsSh.Range(sRange), rCriteria, wsSh.Range(sSumRange)) End If End If Next wsSh 'выводим результат СУММЕСЛИ_ВСЕ_ЛИСТЫ = dblSum End Function |
Чтобы правильно использовать приведенный код, необходимо сначала ознакомиться со статьей Что такое функция пользователя(UDF)?. Вкратце: скопировать текст кода выше, перейти в редактор VBA(
=СУММЕСЛИ_ВСЕ_ЛИСТЫ(
=СУММЕСЛИ_ВСЕ_ЛИСТЫ(
Применение всех функций вы найдете в примере к статье:
Суммировать со всех листов.xls (134,0 KiB, 13 499 скачиваний)
Дополнил статью функцией, которая суммирует данные только с указанных листов, либо со всех, кроме листа с функцией:
'--------------------------------------------------------------------------------------- ' Function : СУММЕСЛИ_ЛИСТЫ ' Purpose : Функция суммирует на основании критерия значения с указанных листов, кроме листа с функцией ' Диапазон - ссылка на диапазон ячеек для поиска критерия ' Критерий - значение, на основании которого суммировать данные ' ДиапазонСуммирования - ссылка на диапазон ячеек, значения которых суммировать ' ИмяЛистов - Имена листов, записанные через вопр.знак(?), с которых суммировать данные ' Пример: "Январь?Февраль?Май" '--------------------------------------------------------------------------------------- Function СУММЕСЛИ_ЛИСТЫ(Диапазон As Range, Критерий, ДиапазонСуммирования As Range, Optional ИмяЛистов = "") Dim asSheets, li As Long Dim wsSh As Worksheet Dim wbFunc As Workbook Dim sRange As String, sSumRange As String Dim dblSum As Double Dim rRange As Range, rCriteria As Range, rSumRange As Range, sSheets As String Set rRange = Диапазон If IsObject(Критерий) Then Set rCriteria = Критерий Else rCriteria = Критерий End If Set rSumRange = ДиапазонСуммирования sSheets = ИмяЛистов 'определяем книгу, в которой записана функция Set wbFunc = Application.Caller.Parent.Parent 'определяем адреса поиска критерия и суммирования sRange = rRange.Address sSumRange = rSumRange.Address If sSheets = "" Then For Each wsSh In wbFunc.Worksheets If wsSh.Name <> Application.Caller.Parent.Name Then sSheets = sSheets & "?" & wsSh.Name End If Next wsSh sSheets = Mid$(sSheets, 2) End If asSheets = Split(sSheets, "?") 'цикл по всем листам книги For li = LBound(asSheets) To UBound(asSheets) Set wsSh = wbFunc.Sheets(asSheets(li)) If Not wsSh Is Nothing Then dblSum = dblSum + Application.SumIf(wsSh.Range(sRange), rCriteria, wsSh.Range(sSumRange)) End If Next li 'выводим результат СУММЕСЛИ_ЛИСТЫ = dblSum End Function |
Скачать пример с кодом функции:
Суммировать со всех листов.xls (134,0 KiB, 13 499 скачиваний)
Очередное дополнение статьи - функция, в которой помимо перечисления листов можно указать книгу, в которой эти листы просматривать:
'--------------------------------------------------------------------------------------- ' Function : СУММЕСЛИ_ЛИСТЫ_В_КНИГЕ ' Purpose : Функция суммирует на основании критерия значения с указанных листов, кроме листа с функцией ' Диапазон - ссылка на диапазон ячеек для поиска критерия ' Критерий - значение, на основании которого суммировать данные ' ДиапазонСуммирования - ссылка на диапазон ячеек, значения которых суммировать ' ИмяЛистов - Имена листов, записанные через вопр.знак(?), с которых суммировать данные ' Пример: "Январь?Февраль?Май" ' ИмяКниги - имя книги, данные с которой необходимо суммировать '--------------------------------------------------------------------------------------- Function СУММЕСЛИ_ЛИСТЫ_В_КНИГЕ(Диапазон As Range, Критерий, ДиапазонСуммирования As Range, Optional ИмяЛистов = "", Optional ИмяКниги As String = "") Dim wsSh As Worksheet, sRange As String, sSumRange As String, asSheets, li As Long Dim wbB As Workbook Dim dblSum As Double Dim rRange As Range, rCriteria As Range, rSumRange As Range, sSheets As String, sWbName As String Set rRange = Диапазон If IsObject(Критерий) Then Set rCriteria = Критерий Else rCriteria = Критерий End If Set rSumRange = ДиапазонСуммирования sSheets = ИмяЛистов sWbName = ИмяКниги If sWbName = "" Then Set wbB = Application.Caller.Parent.Parent Else Set wbB = Application.Workbooks(sWbName) End If 'определяем адреса поиска критерия и суммирования sRange = rRange.Address sSumRange = rSumRange.Address If sSheets = "" Then For Each wsSh In wbB.Worksheets If wsSh.Name <> Application.Caller.Parent.Name Then sSheets = sSheets & "?" & wsSh.Name End If Next wsSh sSheets = Mid$(sSheets, 2) End If asSheets = Split(sSheets, "?") 'цикл по всем листам указанной книги On Error Resume Next For li = LBound(asSheets) To UBound(asSheets) Set wsSh = wbB.Sheets(asSheets(li)) If Not wsSh Is Nothing Then dblSum = dblSum + Application.SumIf(wsSh.Range(sRange), rCriteria, wsSh.Range(sSumRange)) End If Next li 'выводим результат СУММЕСЛИ_ЛИСТЫ_В_КНИГЕ = dblSum End Function |
Аргументы и их использование полностью совпадают с описанными выше для функции
Скачать пример с кодом функций:
Суммировать со всех листов.xls (134,0 KiB, 13 499 скачиваний)
Статья помогла? Поделись ссылкой с друзьями!

Поиск по меткам
Access apple watch Multex Power Query и Power BI VBA управление кодами Бесплатные надстройки Дата и время Записки ИП Надстройки Печать Политика Конфиденциальности Почта Программы Работа с приложениями Разработка приложений Росстат Тренинги и вебинары Финансовые Форматирование Функции Excel акции MulTEx ссылки статистикаКомментарии, не имеющие отношения к комментируемой статье, могут быть удалены без уведомления и объяснения причин. Если есть вопрос по личной проблеме - добро пожаловать на Форум
Светлана, мои контакты есть на странице "Обо мне" данного сайта(Главная-Обо мне). Я так понял, раз Вы просили разрешения скинуть, то Вы уже знаете куда. А Ваш "ап" вызывает только негатив - мы не на форуме, чтобы "апать", привлекая таким образом внимание. Я вроде не обязан Ваши личные проблемы с итоговыми подсчетами здесь решать, нет?
Виктор, такое бывает в случае с пользовательскими фукнциями.
Я прошу прощение за "ап", это произошло случайно и не имело никакого отношения к переписке с Вами. И я попросила помочь по человечески, т.к. хочу разобраться в программе, что мне поможет и в работе тоже.
Виктор - попробуйте самой первой стокой в функции записать: application.Volatile = True
Светлана - я по-человечески отозвался и написал, где взять мои контакты. Все, что далее - относится именно к Вашему "ап".
Дмитрий, добрый день,
благлдарю за пояснение - ваш совет помог!
Application.Volatile True
Здравствуйте, никак не получается задать параметр sSheets. У Вас в примере этот параметр вообще указан как С5, С6? А если поставить - 1,0. - то начитнается #ЗНАЧ!
Руслан, а Вы повнимательнее прочитайте пояснения к аргументам - я там очень четко написал как должен записываться данный аргумент. Дословно себя цитирую:
"Имена листов должны быть записаны через вопросительный знак: Февраль?Март"
Из этого следует, что
"1.0"
вполне логично ошибку вызовет.Здравствуйте! Как будет выглядеть код с двумя условиями?
Привет. Как осуществлять пересчет этой формулы при добавлении новых листов и ввода значений?
Добрый день Дмитрий,
Спасибо за идею, сочетания суммприоз и двссыл - супер
Но для меня было важным отсутствие необходимости в формуле прописывать имена листов,
Получилось так =+СУММПРОИЗВ(СУММЕСЛИ(ДВССЫЛ($N$5:$N$35&"!m1:m200");$M31;ДВССЫЛ($N$5:$N$35&"!e1:e200")))
при этом в диапазоне $N$5:$N$35&" находятся названия листов в формате Текст(01.01.1900;"дд.ММ.гг"), самое интерестное нет необходимости использовать ' для листов с разделительными знаками.
Вячеслав, в примере к статье есть подобная формула(в статье так же об этом написано) - там как раз используются ячейки для записи в них листов. А апострофы все же лучше использовать, т.к. в Вашем конкретном случае они может и не нужны, а если в имени какого либо листа будет служебный или недопустимый символ(например пробел) - то формула ДВССЫЛ вернет ошибку(#ССЫЛКА!).