Excel vba сумма произведений

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#1

05.12.2015 20:08:04

Уважаемые профи форума, подскажите как можно заменить правильно считающую функцию СУММЕСЛИМН на СУММПРОИЗВ в том же месте кода. Ситуация такая. Имеется следующий код:

Код
...
.List(x, 1) = "дата"
.List(x, 2) = "поставщик"
.List(x, 3) = "номер документа прихода"
.List(x, 4) = Format(Application.SumIfs([Summa_prihoda_rozn], [Data_dokumenta_prihoda], CDate(.List(x, 1)), [Nomer_dokumenta_prihoda], .List(x, 3), [Postav], .List(x, 2)), "0.00") 'сумма по приходному документу

Код работает правильно, данные в  .List(x, 1) , .List(x, 2), .List(x, 3) разумеется не фиксированные, а вычисляемые (не привожу кода, чтобы не загромождать сообщение, но считается все правильно). Возник вопрос, можно ли заменить в коде SumIfs на SumProduct. Формулой, в ячейке листа, получилось без проблем:

Код
=СУММПРОИЗВ((Nomer_dokumenta_prihoda=F2)*(Data_dokumenta_prihoda=D2)*(Section_prihoda=C2)*Col_prihoda*Cena_rozn)

разумеется, в ячейке F2 находится номер документа, в ячейке D2 находится дата, в ячейке С2 — указана секция, имена и размеры диапазонов правильные. Повторюсь, формула считает правильно. А вот как сделать то же самое в в приведенном коде, я пока не знаю. Как должна выглядеть функция SumProduct в коде VBA? Заранее спасибо всем откликнувшимся.  

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

WorksheetFunction.SumProduct

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

Kuzmich

, когда я пробовал сваять конструкцию, используя Аpplication, то excel ругался на несовпадение типов, а когда пытался применить WorksheetFunction код выпадал с ошибкой о невозможности получить свойство (или как-то так). А как по Вашему мнению должна выглядеть строка моего кода для  .List(x, 4), при условии что в .List(x, 1), .List(x, 2), .List(x, 3) находятся соответственно дата, поставщик и номер документа (уже правильно вычисленные к этому моменту), а в диапазонах Nomer_dokumenta_prihoda, Data_dokumenta_prihoda, Section_prihoda, Col_prihoda и Cena_r на листе находятся соответствующие данные?

Изменено: Алексей05.12.2015 21:12:47

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

Попробуйте так
=Evaluate(«SumProduct( здесь вставьте то, что у вас в формуле СУММПРОИЗВ) «)

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#5

06.12.2015 12:04:13

Пока не получается, excel ругается на несовпадение типов. Уважаемые форумчане, покажите (причем желательно на работающем примере)  синтаксис SumProduct в коде VBA. Поясню. В ячейке синтаксис выглядит так (по моему представлению: («диапазон = некое значение) * (диапазон)). А как это должно выглядеть в коде VBA? Пишем Application.SumProduct, а далее? Как правильно указать, что диапазон должен сверяться с вычисленным значением (например .List(x, 1)), следует ли заключать диапазон в квадратные скобки, следует ли заключать эту проверку в круглые скобки и наконец разделяться аргументы функции должны знаком умножения или запятой?

Вот например текущий вариант:

Код
.List(x, 4) = Application.SumProduct(([Nomer_dokumenta_prihoda] = .List(x, 3)), ([Data_dokumenta_prihoda] = CDate(.List(x, 1))), [Col_prihoda], [Cena_rozn])

выпадает с ошибкой 13 Type mismatch, при этом .List(x, 1) и .List(x, 3) имеют правильные значения. Где и что написано неправильно?

Изменено: Алексей06.12.2015 12:16:14

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

Вы бы привели свой пример и где не получается, а то долго можно гадать о несовпадении типов

 

Johny

Пользователь

Сообщений: 2737
Регистрация: 21.12.2012

Запомните раз и навсегда: когда вы переносите текст РУССКОЙ формулы в VBA, то она работать не будет. Для VBA нужен АНГЛИЙСКИЙ формат данных! То есть вместо точки с запятой (разделитель параметров) ставится запятая, а для разделения целой и дробной частей ставится не запятая, а точка.

There is no knowledge that is not power

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#8

06.12.2015 12:32:20

Цитата
Kuzmich написал:
Вы бы привели свой пример и где не получается, а то долго можно гадать о несовпадении типов

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

Прикрепленные файлы

  • реестры.xlsm (78.78 КБ)

 

Johny

Пользователь

Сообщений: 2737
Регистрация: 21.12.2012

#9

06.12.2015 13:02:13

А что означает это в SumProduct?  8-0

Код
[Nomer_dokumenta_prihoda] = .List(x, 3)

There is no knowledge that is not power

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

Это моя попытка написать код по аналогии с текстом формулы — проверить диапазон с «контрольным» значением

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

А мой вопрос вообще реализуем? Можно ли вообще задействовать SumProduct в коде VBA? Как ни пытаюсь написать эту строчку результат прежний — несовпадение тиров, при этом при проверке через Add Watch… диапазоны (например Nomer_dokumenta_prihoda) имеют значение Empty.

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#12

06.12.2015 18:22:03

Прошу пояснить следующее. На просторах сети нашел код, если я правильно понимаю типа аналог этой самой функции SumProduct:

Код
Function xxx(x,y)
Dim a, b, c As Range
a = Range("a4:a14") ' contains text
b = Range("b4:b14") ' contains text
c = Range("c4:c14") ' contains values
Range("a20") = Application.SumProduct((a = x) * (b = y) * c)
End Function

правда попробовав функцию в действии результата не увидел. Т.е. заполнил ячейки в указанных диапазонах для a, b. c выбрал функцию в определенных пользователем, указал результаты для x и y, но результата нет — #ЗНАЧ. Может с помощью этого кода можно решить мой вопрос?

 

B.Key

Пользователь

Сообщений: 633
Регистрация: 26.02.2014

#13

06.12.2015 19:37:04

Аргументом  функции Application.SumProduct является одномерный массив, и даже преобразовав массив в одномерный

Код
c = Application.Transpose([c1..c4].Value)

Вы не получите результат для сравнения значений.
Все дело в сравнении a=x

Код
b = Application.Transpose([b1..b4="x"])

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

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

B.Key

, я так понял что правильнее всего плюнуть на идею замены СУММЕСЛИМН на СУММПРОИЗВ и оставить все как было, так? В конце концов все это задумывалось всего лишь для возможности убрать 2 колонки на листе прихода :cry:

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

Вот нашел пример использования SumProduct

 

B.Key

Пользователь

Сообщений: 633
Регистрация: 26.02.2014

Зачем вообще делать дополнительные вычисления на листе, если Вы используете VBA? Хотя и через одно

место

 

B.Key

Пользователь

Сообщений: 633
Регистрация: 26.02.2014

#17

06.12.2015 21:40:42

Цитата
Kuzmich написал:
пример использования SumProduct

Это пример использования функции Evaluate
———
Но возможно Алексей и подойдет.

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

#18

06.12.2015 22:04:28

Цитата
пример использования функции Evaluate

Evaluate — это метод для расчета значений формул листа и генерации ссылок на объекты Range

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#19

07.12.2015 06:36:25

Цитата
B.Key написал:
Зачем вообще делать дополнительные вычисления на листе

B.Key, вычисления на листе используются для отчета на другом листе (чисто формулами), код VBA — для заполнения Listbox на форме.

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#20

07.12.2015 07:39:58

Благодаря файлу от

Kuzmich

частичный прогресс есть. Если в искомой строчке написать: (приведен только 1 уровень проверки)

Код
 .List(x, 4) = Evaluate("SUMPRODUCT((F2:F" & LastRow_p & "=""348"")*(J2:J" & LastRow_p & ")*(L2:L" & LastRow_p & "))")

то результат верен, но если вместо вручную указанного числа 348 поставить .List(x,3):

Код
.List(x, 4) = Evaluate("SUMPRODUCT((F2:F" & LastRow_p & "="".List(x, 3)"")*(J2:J" & LastRow_p & ")*(L2:L" & LastRow_p & "))")

дающее это значение (я имею ввиду что к моменту выполнения этой строки кода значение .List(x,3) =348), то код выполняется далее, но результат будет равным 0. Это происходит из-за особенностей функции, указанной

B.Key

, верно? Если это так, то можно ли это поправить? Попытался ввести переменную перед этой строкой, значение которой равно  .List(x,3), но результат тот-же.

 

B.Key

Пользователь

Сообщений: 633
Регистрация: 26.02.2014

#21

07.12.2015 09:33:18

Цитата
Алексей написал:
о можно ли это поправить

Бинарное отрицание Вам в помощь

Тынц

 

B.Key

Пользователь

Сообщений: 633
Регистрация: 26.02.2014

Kuzmich, Метод это функция принадлежащая классу, в данном случае Excel.Application

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#23

07.12.2015 11:55:41

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

Код
.List(x, 4) = Evaluate("SUMPRODUCT((F2:F" & LastRow_p & "=348)*(J2:J" & LastRow_p & ")*(L2:L" & LastRow_p & "))")

все считается правильно (для первой строки в listbox разумеется, но ведь и число 348 верно только для первого прихода). Далее .List(x, 3) к этому моменту уже имеет значение (как раз 348), но почему-то при попытке подставить его в качестве сравнения, выдает ошибку. Причем, если не заключать .List(x, 3) в кавычки выпадает ошибка несоответствия типов, если заключить в одинарные кавычки — List separator or, если кавычки двойные — код отрабатывает правильно но результат =0. Получается что каким-либо образом значение  .List(x, 3) надо преобразовать в число? Это имел ввиду

B.Key

, говоря о преобразовании? А как это сделать? Или я неправ и мои предположения неверны?

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

Вручную 348 — число, а .List(x, 3) — это текст, вам писали про бинарное отрицание, попробуйте

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#25

07.12.2015 18:41:10

Наверно совсем туплю к концу дня, никак не пойму в какое место ставить это бинарное отрицание. По крайне мере вариант:

Код
.List(x, 4) = Evaluate("SUMPRODUCT(--(F2:F" & LastRow_p & "= .List(x, 3))*(J2:J" & LastRow_p & ")*(L2:L" & LastRow_p & "))")

не проходит — несовпадение типов. Может подскажет кто правильное место?

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

Попробуйте Val(.List(x, 3))

 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

Не помогло, увы. Или = 0 (в варианте с двойными кавычками), либо — несовпадение типов.

 

Kuzmich

Пользователь

Сообщений: 7998
Регистрация: 21.12.2012

#28

07.12.2015 21:24:09

А так попробуйте

Код
 = Evaluate("SUMPRODUCT((F2:F" & LastRow_p & "=" & .List(x, 3) & ")*(J2:J" & LastRow_p & ")*(L2:L" & LastRow_p & "))")
 

Алексей

Пользователь

Сообщений: 250
Регистрация: 18.01.2013

#29

08.12.2015 05:48:47

УРА!!! Наконец-то получилось. Огромное спасибо

Kuzmich

за его помощь. Принцип вроде понятен, сейчас буду к реальному файлу примерять. Еще раз огромное спасибо!

Это особенность применения данной функции. При расчете SUMPRODUCT в VBA конструкция Range(cells(),cells())не работает. Но диапазон можно записать по-другому:

Range(столбец & строка & ":" & столбец & строка)

В этом случае функция отработает корректно:

Sub СуммПроизв()
    Dim i As Long

    For i = 4 To 60
        Cells(i, 7) = Application.SumProduct(Range("Q" & i & ":CB" & i), Range("Q" & i & ":CB" & i))
    Next i
End Sub

Но в целом подход неправильный. Вызов функций листа в коде — процесс медленный. Если уж применяется VBA, то и считать можно только своими средствами:

Sub SumProduct_()
    Dim aData(), aResult()
    Dim i As Long, j As Long

    aData = Range("Q4:CB60").Value
    ReDim aResult(1 To UBound(aData), 1 To 1)

    For i = 1 To UBound(aData)
        For j = 1 To UBound(aData, 2)
            aResult(i, 1) = aResult(i, 1) + aData(i, j) ^ 2
        Next j
    Next i

    Range("G4").Resize(UBound(aData), 1).Value = aResult
End Sub

На небольших диапазонах выигрыш по времени при замене функции листа на обработку в массиве практически незаметен.

Скачать пример рабочей книги

Загрузите образец книги

В этом руководстве показано, как использовать Функция СУММПРОИЗВ в Excel в Excel.

Обзор функции СУММПРОИЗВ

Функция СУММПРОИЗВ умножает массивы чисел и суммирует результирующий массив.

Чтобы использовать функцию SUMPRODUCT Excel Worksheet, выберите ячейку и введите:

(Обратите внимание, как появляются входные данные формулы)

Функция СУММПРОИЗВ Синтаксис и входные данные:

1 = СУММПРОИЗВ (массив1; массив2; массив3)

array1 — Массивы чисел.

Что такое функция СУММПРОИЗВ?

Функция СУММПРОИЗВ — одна из наиболее мощных функций Excel. Это название может заставить вас поверить, что оно предназначено только для основных математических вычислений, но его можно использовать для гораздо большего.

Массивы

SUMPRODUCT требует ввода массивов.

Итак, во-первых, что мы подразумеваем под «массивом»? Массив — это просто группа элементов (например, чисел), расположенных в определенном порядке, как и диапазон ячеек. Итак, если бы у вас были числа 1, 2, 3 в ячейках A1: A3, Excel прочитал бы это как массив {1,2,3}. Фактически, вы можете ввести {1,2,3} непосредственно в формулы Excel, и он распознает массив.

Подробнее о массивах мы поговорим ниже, но сначала рассмотрим простой пример.

Основы математики

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

У нас есть таблица продуктов, и мы хотим подсчитать общий объем продаж. У вас может возникнуть соблазн просто добавить новый столбец, взять количество проданного * цена и затем суммировать новый столбец. Однако вместо этого вы можете просто использовать функцию СУММПРОИЗВ. Давайте рассмотрим формулу:

1 = СУММПРОИЗВ (A2: A4; B2: B4)

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

1234 = СУММПРОИЗВ ({100, 50, 10}, {6, 7, 5})= СУММПРОИЗВ ({100 * 6, 50 * 7, 10 * 5})= СУММПРОИЗВ ({600, 350, 50}= 1000

Функция SUMPRODUCT смогла перемножить все числа и произвести суммирование.

Средневзвешенное

Другой случай, когда полезно использовать СУММПРОИЗВ, — это когда вам нужно рассчитать средневзвешенное значение. Чаще всего это происходит при выполнении школьных заданий, поэтому давайте рассмотрим следующую таблицу.

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

1 = СУММПРОИЗВ (B2: B4; C2: C4)

Наша функция снова умножает каждый элемент в массивах перед суммированием итога. Это работает так

123 = СУММПРОИЗВ ({30%, 50%, 20%}, {73%, 90%, 95%})= СУММПРОИЗВ ({22%, 45%, 19%})= 86%

Несколько столбцов

Еще одно место, где мы могли бы использовать SUMPRODUCT, — это еще больше столбцов, которые нужно умножить друг на друга. Рассмотрим пример, в котором нам нужно рассчитать объем в кусках пиломатериалов.

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

1 = СУММПРОИЗВ (B2: B5; C2: C5; D2: D5)

Первые элементы каждого массива будут умножаться друг на друга (например, 4 * 2 * 1 = 8). Затем 2-й (4 * 2 * 2 = 16) и 3-йrdи т. д. В целом, это произведет набор продуктов, которые выглядят как {8, 16, 16, 32). Тогда общий объем будет суммой этого массива, 72.

Один критерий

Хорошо, давайте добавим еще один уровень сложности. Мы видели, что SUMPRODUCT может обрабатывать массивы чисел, но как насчет того, чтобы проверить критерии? Ну, вы также можете создавать массивы для логических значений (логические значения — это значения ИСТИНА или ЛОЖЬ).

Например, возьмем базовый массив {1, 2, 3}. Давайте создадим соответствующий массив, который указывает, больше ли каждое число 1. Этот массив будет выглядеть как {FALSE, TRUE, TRUE}.

Это очень полезно в формулах, потому что мы можем легко преобразовать ИСТИНА / ЛОЖЬ в 1/0. Давайте рассмотрим пример.

Используя приведенную ниже таблицу, мы хотим рассчитать «Сколько единиц было продано в красном цвете?»

Мы можем сделать это с помощью этой формулы:

1 = СУММПРОИЗВ (A2: A4; — (B2: B4 = «Красный»))

«Подожди! Что там с двойным минусом? » ты говоришь. Помните, как я сказал, что мы можем преобразовать True / False в 1/0? Мы делаем это, заставляя компьютер выполнять математическую операцию. В этом случае мы говорим «возьмите отрицательное значение, а затем снова возьмите отрицательное». Записав это, наш массив изменится следующим образом:

123 {Верно, Верно, Ложно}{-1, -1, 0}{1, 1, 0}

Итак, возвращаясь к полной формуле СУММПРОИЗВ, она загружается в наши массивы, а затем умножается, как это

123 = СУММПРОИЗВ ({100, 50, 10}, {1, 1, 0})= СУММПРОИЗВ ({100, 50, 0})= 150

Обратите внимание, как 3rd item стал 0, потому что все, что умножено на 0, становится нулем.

Несколько критериев

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

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

1 = СУММПРОИЗВ (A2: A4; — (B2: B4 = «Красный»), — (C2: C4 = «Фев»))

Затем компьютер оценит наши массивы и умножит их. Мы уже рассмотрели, как массивы True / False превращаются в 1/0, поэтому я пока пропущу этот шаг.

123 = СУММПРОИЗВ ({100, 50, 10}, {1, 1, 0}, {0, 1, 1})= СУММПРОИЗВ ({0, 50, 0})= 50

В нашем примере у нас была только одна строка, которая соответствовала всем критериям, но с реальными данными у вас могло быть несколько строк, которые вам нужно было сложить вместе.

Комплексные критерии

Хорошо, до этого момента вы могли не быть впечатлены, потому что все наши примеры могли быть выполнены с использованием других функций, таких как СУММЕСЛИ или СЧЁТЕСЛИ. Теперь мы собираемся сделать что-то, что другие функции не могу делать. Раньше в нашем столбце «Месяц» были фактические названия месяцев. Что, если бы вместо этого были даты?

Мы не можем сделать СУММЕСЛИ сейчас, потому что СУММЕСЛИ не может обрабатывать необходимые нам критерии. Однако SUMPRODUCT может справиться с манипулированием массивом и выполнением более глубокого теста. Мы уже работали с массивами, когда переводили True / False в 1/0. Мы собираемся манипулировать этим массивом с помощью функции МЕСЯЦ. Вот полная формула, которую мы собираемся использовать

1 = СУММПРОИЗВ (A2: A4; — (B2: B4 = «Красный»), — (МЕСЯЦ (C2: C4) = 2))

Давайте посмотрим на 3rd массив более внимательно. Во-первых, наша формула извлечет номер месяца из каждой даты в C2: C4. Это даст нам {1, 2, 2}. Затем мы проверяем, равно ли это значение 2. Теперь наш массив выглядит как {False, True, True}. Мы снова делаем двойной минус, и у нас есть {0, 1, 1}. Теперь мы снова находимся в том же месте, что и в примере 3, и наша формула сможет сказать нам, что в феврале было продано 50 единиц, которые были красными.

Двойной минус против умножения

Если вы раньше видели использование функции СУММПРОИЗВ, возможно, вы видели немного другое обозначение. Вместо двойного минуса можно написать

1 = СУММПРОИЗВ (A2: A4 * (B2: B4 = «Красный») * (МЕСЯЦ (C2: C4) = 2))

Формула по-прежнему будет работать так же, мы просто вручную сообщаем компьютеру, что хотим умножить массивы. SUMPRODUCT все равно собирался это сделать, поэтому в том, как работает математика, нет никаких изменений. Выполнение математической операции преобразует наши True / False в 1/0 того же самого. Итак, в чем разница?

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

Когда вы используете SUMPRODUCT, компьютер ожидает, что все аргументы (array1, array2 и т. Д.) Будут одного размера. Это означает, что у них одинаковое количество строк или столбцов. Однако вы можете выполнять так называемое вычисление двухмерного массива с помощью SUMPRODUCT, что мы увидим в следующем примере. Когда вы это сделаете, массивы будут разных размеров, поэтому нам нужно обойти проверку «все одинакового размера».

Два измерения

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

Вот наша таблица проданных единиц, но данные перегруппированы так, чтобы категории располагались вверху. Если мы хотим узнать, сколько предметов было красным и относилось к категории A, мы можем написать

1 = СУММПРОИЗВ ((A2: A4 = «Красный») * (B1: C1 = «A») * B2: C4)

Что здесь происходит?? Оказывается, мы собираемся размножаться в двух разных направлениях. Визуализировать это сложнее с помощью простого письменного предложения, поэтому у нас есть несколько изображений, которые нам помогут. Во-первых, наш критерий строки (красный?) Будет умножаться на каждую строку в массиве.

1 = СУММПРОИЗВ ((A2: A4 = «КРАСНЫЙ») * B2: C4)

Затем критерии столбца (это категория A?) Будут умножаться на каждый столбец.

1 = СУММПРОИЗВ ((A2: A4 = «Красный») * (B1: C1 = «A») * B2: C4)

После того, как оба этих критерия выполнят свою работу, останутся только 5 и 10. СУММПРОИЗВ даст нам в качестве нашего ответа общую сумму 15.

Помните, как мы говорили о том, что массивы должны быть одинакового размера, если вы не работаете с двумя измерениями? Частично это было правильно. Снова посмотрим на массивы, которые мы использовали в нашей формуле. В рост двух наших массивов одинаковы, а ширина двух наших массивов одинаковы. Итак, вам все равно нужно убедиться, что все будет правильно, но вы можете сделать это в разных измерениях.

Двухмерный и сложный

Часто нам представляются данные, которые не имеют наилучшего формата, подходящего для наших формул. Мы могли бы попытаться переставить его вручную, или мы можем быть умнее с нашими формулами. Рассмотрим следующую таблицу.

Здесь у нас есть смешанные данные по нашим товарам и продажам за каждый месяц. Как нам узнать, сколько товаров Боб продал за весь год?

Для этого мы будем использовать две дополнительные функции: SEARCH и ISNUMBER. Функция ПОИСК позволит нам искать наше ключевое слово «элементы» в ячейках заголовка. На выходе этой функции будет либо число, либо ошибка (если ключевое слово не найдено). Затем мы будем использовать ISNUMBER для преобразования что вывод в наши логические значения. Наша формула будет выглядеть, как показано ниже.

К настоящему времени вы должны быть хорошо знакомы с первым массивом. Будет создан результат вроде {0, 1, 0, 1}. Следующий массив критериев, о котором мы только что говорили. Он создаст номер для всех ячеек с «Items» в них и ошибку для остальных {5, # N / A !, 5, # N / A!}. ISNUMBER затем преобразует это в логическое значение {True, False, True, False}. Затем при умножении сохранятся только значения из первого и третьего столбца. После того, как все массивы умножатся друг на друга, единственные ненулевые числа, которые у нас будут, — это те, которые выделены здесь:

1 = СУММПРОИЗВ ((A2: A5 = «Боб») * (ISNUMBER (ПОИСК («Элементы»; B1: E1)) * B2: E5))

СУММПРОИЗВ затем суммирует их, и мы получим окончательный результат 29.

СУММПРОИЗВ или

Возникает много ситуаций, когда мы хотели бы иметь возможность суммировать значения, если в нашем столбце критериев есть одно значение ИЛИ другое значение. Вы можете сделать это в SUMPRODUCT, добавив два массива критериев друг против друга.

В этом примере мы хотим сложить единицы, проданные как за красный, так и за синий.

Наша формула будет выглядеть так

1 = СУММПРОИЗВ (A2: A7; (B2: B7 = «Красный») + (B2: B7 = «Синий»))

Давайте посмотрим на массив критериев Red. В результате будет получен массив, который выглядит следующим образом: {1, 1, 0, 0, 0, 0}. Массив критериев Blue будет иметь вид {0, 0, 1, 0, 1, 0}. Когда вы сложите их вместе, новый массив будет выглядеть как {1, 1, 1, 0, 1, 0}. Мы видим, как два массива объединились в единый массив критериев. Затем функция умножит это на наш первый массив, и мы получим {100, 50, 10, 0, 75, 0}. Обратите внимание, что значения для зеленого были обнулены. Последний шаг СУММПРОИЗА — это сложение всех чисел вместе, чтобы получить решение 235.

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

1 = СУММПРОИЗВ (A2: A7; (A2: A7> = 50) + (B2: B7 = «Синий»))

Наша цель — найти синие предметы, которые были проданы или были в количестве более 50. Однако эти условия не являются исключительными, поскольку в одной строке может быть как больше 50 в столбце A. а также будь синим. Это приведет к тому, что первый массив критериев будет выглядеть как {1, 1, 0, 1, 1, 0}, а второй массив критериев будет иметь вид {0, 0, 1, 0, 1, 0}. Их сложение дает {1, 1, 1, 1, 2, 0}. Вы видите, что у нас там сейчас 2? Если оставить в покое, СУММПРОИЗВ в конечном итоге удвоит значение в этой строке, изменив 75 на 150, и мы получим неправильный результат. Чтобы исправить это, мы помещаем проверку внешних критериев в наш массив, например:

1 = СУММПРОИЗВ (A2: A7; — ((A2: A7> = 50) + (B2: B7 = «Синий»)> 0))

Теперь, после того, как два внутренних массива критериев были сложены вместе, мы проверим, больше ли результат, чем 0. Это избавляет от 2, которые у нас были раньше, и вместо этого у нас будет такой массив, как {1, 1, 1 , 1, 1, 0}, что даст правильный результат.

СУММПРОИЗВ Точный

Большинство функций в Excel не чувствительны к регистру, но иногда нам нужно иметь возможность выполнять поиск с учетом регистра. Когда желаемый результат числовой, мы можем добиться этого, используя EXACT внутри функции СУММПРОИЗВ. Рассмотрим следующую таблицу:

Мы хотим найти оценку для пункта «ABC123». Обычно функция EXACT сравнивает два элемента и возвращает логический вывод, указывающий, являются ли эти два элемента точно такой же. Однако, поскольку мы находимся внутри СУММПРОИЗВ, наш компьютер будет знать, что мы имеем дело с массивами, и сможет сравнивать один элемент с каждым элементом в массиве. Наша формула будет выглядеть так

1 = СУММПРОИЗВ (- ТОЧНЫЙ («ABC123»; A2: A5), B2: B5)

Затем функция EXACT проверит каждый элемент в A2: A5, чтобы убедиться, что он соответствует значению и регистру. В результате будет получен массив, который выглядит как {0, 1, 0, 0}. При умножении на B2: B5 массив становится {0, 2, 0, 0}. После окончательного суммирования получаем решение 2.

СУММПРОИЗВ в Google Таблицах

Функция СУММПРОИЗВ работает в Google Таблицах точно так же, как и в Excel:

Примеры SUMPRODUCT в VBA

Вы также можете использовать функцию СУММПРОИЗВ в VBA. Тип: application.worksheetfunction.sumproduct (массив1, массив2, массив3)

Выполнение следующих операторов VBA

1 Диапазон («B10») = Application.WorksheetFunction.SumProduct (Range («A2: A7»), Range («B2: B7»))

даст следующие результаты

Для аргументов функции (array1 и т. Д.) Вы можете либо ввести их непосредственно в функцию, либо определить переменные, которые будут использоваться вместо них.

In Excel, you can use VBA to calculate the sum of values from a range of cells or multiple ranges. And, in this tutorial, we are going to learn the different ways that we can use this.

Sum in VBA using WorksheetFunction

In VBA, there are multiple functions that you can use, but there’s no specific function for this purpose. That does not mean we can’t do a sum. In VBA, there’s a property called WorksheetFunction that can help you to call functions into a VBA code.

sum-in-vba-using-worksheet

Let sum values from the range A1:A10.

  1. First, enter the worksheet function property and then select the SUM function from the list.
    2-enter-worksheet-function
  2. Next, you need to enter starting parenthesis as you do while entering a function in the worksheet.
    3-starting-parenthesis
  3. After that, we need to use the range object to refer to the range for which we want to calculate the sum.
    4-use-the-range-object
  4. In the end, type closing parenthesis and assign the function’s returning value to cell B1.
    5-closing-parenthesis
Range("B1") = Application.WorksheetFunction.Sum(Range("A1:A10"))

Now when you run this code, it will calculate the sum for the values that you have in the range A1:A10 and enter the value in cell B1.

run-the-code-to-calculate

Sum Values from an Entire Column or a Row

In that just need to specify a row or column instead of the range that we have used in the earlier example.

'for the entire column A
Range("B1") = Application.WorksheetFunction.Sum(Range("A:A"))

'for entire row 1
Range("B1") = Application.WorksheetFunction.Sum(Range("1:1"))

Use VBA to Sum Values from the Selection

Now let’s say you want to sum value from the selected cells only in that you can use a code just like the following.

Sub vba_sum_selection()

Dim sRange As Range
Dim iSum As Long

On Error GoTo errorHandler

Set sRange = Selection

iSum = WorksheetFunction.Sum(Range(sRange.Address))
MsgBox iSum

errorHandler:
MsgBox "make sure to select a valid range of cells"

End Sub

In the above code, we have used the selection and then specified it to the variable “sRange” and then use that range variable’s address to get the sum.

The following code takes all the cells and sum values from them and enters the result in the selected cell.

Sub vba_auto_sum()

Dim iFirst As String
Dim iLast As String
Dim iRange As Range

On Error GoTo errorHandler

iFirst = Selection.End(xlUp).End(xlUp).Address
iLast = Selection.End(xlUp).Address

Set iRange = Range(iFirst & ":" & iLast)
ActiveCell = WorksheetFunction.Sum(iRange)

Exit Sub

errorHandler:
MsgBox "make sure to select a valid range of cells"

End Sub

Sum a Dynamic Range using VBA

And in the same way, you can use a dynamic range while using VBA to sum values.

Sub vba_dynamic_range_sum()

Dim iFirst As String
Dim iLast As String
Dim iRange As Range

On Error GoTo errorHandler

iFirst = Selection.Offset(1, 1).Address
iLast = Selection.Offset(5, 5).Address

Set iRange = Range(iFirst & ":" & iLast)
ActiveCell = WorksheetFunction.Sum(iRange)

Exit Sub

errorHandler:
MsgBox "make sure to select a valid range of cells"

End Sub

Sum a Dynamic Column or a Row

In the same way, if you want to use a dynamic column you can use the following code where it will take the column of the active cell and sum for all the values that you have in it.

Sub vba_dynamic_column()

Dim iCol As Long

On Error GoTo errorHandler

iCol = ActiveCell.Column
MsgBox WorksheetFunction.Sum(Columns(iCol))

Exit Sub

errorHandler:
MsgBox "make sure to select a valid range of cells"

End Sub

And for a row.

Sub vba_dynamic_row()

Dim iRow As Long

On Error GoTo errorHandler

iRow = ActiveCell.Row

MsgBox WorksheetFunction.Sum(Rows(iCol))

Exit Sub

errorHandler:
MsgBox "make sure to select a valid range of cells"

End Sub

Using SUMIF with VBA

Just like sum you can use the SUMIF function to sum values with criteria just like the following example.

sumif-with-vba
Sub vba_sumif()

Dim cRange As Range
Dim sRange As Range

Set cRange = Range("A2:A13")
Set sRange = Range("B2:B13")

Range("C2") = _
WorksheetFunction.SumIf(cRange, "Product B", sRange)

End Sub

Формулу =СУММПРОИЗВ(ПРОМЕЖУТОЧНЫЕ.ИТОГИ(3;….. в макрос

Gjlhzl

Дата: Пятница, 03.02.2023, 15:42 |
Сообщение № 1

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

При создании листов макросом, требуется вставка формулы в B2:B5

Код

=СУММПРОИЗВ(ПРОМЕЖУТОЧНЫЕ.ИТОГИ(3;СМЕЩ($B$7;СТРОКА(ДВССЫЛ(«1:»&ЧСТРОК($B$7:$B$20)))-1;))*$B$7:$B$20*($D$7:$D$20=$A2))

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

К сообщению приложен файл:

9189897.xlsb
(14.6 Kb)

 

Ответить

Gjlhzl

Дата: Пятница, 03.02.2023, 21:33 |
Сообщение № 2

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

то есть к любой такой таблице что бы макросом вставлялась и все верно считало

 

Ответить

cmivadwot

Дата: Пятница, 03.02.2023, 21:49 |
Сообщение № 3

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 145


Репутация:

45

±

Замечаний:
0% ±


Gjlhzl, а точно не работает? вроде умная таблица сама там все меняет при добавлении строк.

 

Ответить

Nic70y

Дата: Суббота, 04.02.2023, 08:47 |
Сообщение № 4

Группа: Друзья

Ранг: Экселист

Сообщений: 8132


Репутация:

1998

±

Замечаний:
0% ±


Excel 2010

[vba]

Код

    u = Cells(Rows.Count, «b»).End(xlUp).Row
    v = u — 6
    Range(«b2:b5»).FormulaR1C1 = «=SUMPRODUCT(SUBTOTAL(3,OFFSET(R7C2,ROW(R1:R» & v & «)-1,))*R7C2:R» & u & «C2*(R7C4:R» & u & «C4=RC1))»

[/vba]


ЮMoney 41001841029809

 

Ответить

Gjlhzl

Дата: Суббота, 04.02.2023, 09:26 |
Сообщение № 5

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

Nic70y, спасибо
только если протянуть формулу потом ошибка НД. формула не работает при изменении диапазона…кол-ва строк

 

Ответить

Nic70y

Дата: Суббота, 04.02.2023, 09:29 |
Сообщение № 6

Группа: Друзья

Ранг: Экселист

Сообщений: 8132


Репутация:

1998

±

Замечаний:
0% ±


Excel 2010


[vba]

Код

=СУММПРОИЗВ(ПРОМЕЖУТОЧНЫЕ.ИТОГИ(3;СМЕЩ($B$7;СТРОКА(Табл[Сумма])-7;))*Табл[Сумма]*(Табл[Валюта]=$A2))

[/vba]
Gjlhzl, не понял Вас.
куда протягиваете формулу?

формула не работает при изменении диапазона

в создаваемых файлах отличается кол-вом строк


ЮMoney 41001841029809

Сообщение отредактировал Nic70yСуббота, 04.02.2023, 09:36

 

Ответить

Gjlhzl

Дата: Суббота, 04.02.2023, 09:54 |
Сообщение № 7

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

Nic70y, неправильно выразился, имел ввиду если добавлять в таблицу строки…..то не пашет

 

Ответить

Nic70y

Дата: Суббота, 04.02.2023, 09:56 |
Сообщение № 8

Группа: Друзья

Ранг: Экселист

Сообщений: 8132


Репутация:

1998

±

Замечаний:
0% ±


Excel 2010

Gjlhzl, повесить макрос на событие — изменение ячеек
или использовать формулу с ссылками на умную таблицу

=СУММПРОИЗВ(ПРОМЕЖУТОЧНЫЕ.ИТОГИ(3;СМЕЩ($B$7;СТРОКА(Табл[Сумма])-7;))*Табл[Сумма]*(Табл[Валюта]=$A2))


ЮMoney 41001841029809

 

Ответить

Gjlhzl

Дата: Суббота, 04.02.2023, 10:06 |
Сообщение № 9

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

Nic70y, так а макросом если формулу вставлять…как код будет выглядеть?

 

Ответить

Gjlhzl

Дата: Суббота, 04.02.2023, 10:24 |
Сообщение № 10

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

создается файл в него подставляются формулы, после с этим файлом работают добавляют данные

 

Ответить

Nic70y

Дата: Суббота, 04.02.2023, 10:40 |
Сообщение № 11

Группа: Друзья

Ранг: Экселист

Сообщений: 8132


Репутация:

1998

±

Замечаний:
0% ±


Excel 2010

[vba]

Код

    a = Range(«a6»).ListObject.Name
    Range(«b2:b5»).FormulaR1C1 = «=SUMPRODUCT(SUBTOTAL(3,OFFSET(R7C2,ROW(» & a & «[Сумма])-7,))*» & a & «[Сумма]*(» & a & «[Валюта]=RC1))»

[/vba]


ЮMoney 41001841029809

Сообщение отредактировал Nic70yСуббота, 04.02.2023, 10:41

 

Ответить

cmivadwot

Дата: Суббота, 04.02.2023, 13:22 |
Сообщение № 12

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 145


Репутация:

45

±

Замечаний:
0% ±


Gjlhzl, у меня при добавлении данных ниже таблицы(в сдедующую строку после завершения таблицы), автоматом умная таблица протягивается ниже и формулы автоматом учитывают добавившиеся строки.

 

Ответить

Gjlhzl

Дата: Суббота, 04.02.2023, 16:57 |
Сообщение № 13

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

cmivadwot, при первом макросе — при изменении строк табл — ошибк НД
при втором вар от Nic70y, ошибка на сам макрос
попробуйте в пример вставить…

 

Ответить

cmivadwot

Дата: Суббота, 04.02.2023, 17:41 |
Сообщение № 14

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 145


Репутация:

45

±

Замечаний:
0% ±


Gjlhzl, у меня все работает, как написал выше, на файле выложенном вами в первом сообщении…. Без макросов…при добавлении строк таблица их захватывает ….и корректируюца формулы. Если копировать формулы и вставлять на чистый лист…формулы беруд данные с листа, откуда они скопированы(чудеса умной таблицы). Я зажал контрл+лев клавиша мыши.. стрелка на листе и делаю копию вашего листа…вот тогда в копии все работает как и на первом листе….все добавляется и формулы ……

 

Ответить

Gjlhzl

Дата: Суббота, 04.02.2023, 17:55 |
Сообщение № 15

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

cmivadwot, так весь смысл в том что сначала создаются файлы запросами с PQ потом вставляются формулы в нужные ячейки макросом…а уж потом работают с файлами.
попробуйте вставив формулы макросом , изменить умную табл ..

 

Ответить

cmivadwot

Дата: Воскресенье, 05.02.2023, 19:40 |
Сообщение № 16

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 145


Репутация:

45

±

Замечаний:
0% ±


Gjlhzl, я наверно чет не понимаю….вот для 200 строк. формула считает только то, что заполнено и совпадает с условием, и наверно нет смысла подстраивать ее под количество строк

Сообщение отредактировал cmivadwotВоскресенье, 05.02.2023, 21:27

 

Ответить

Nic70y

Дата: Понедельник, 06.02.2023, 08:47 |
Сообщение № 17

Группа: Друзья

Ранг: Экселист

Сообщений: 8132


Репутация:

1998

±

Замечаний:
0% ±


Excel 2010

попробуйте в пример вставить…

ну я на примере его (макрос) и писал, см. файл

К сообщению приложен файл:

0470371.xlsb
(17.0 Kb)


ЮMoney 41001841029809

 

Ответить

Gjlhzl

Дата: Понедельник, 06.02.2023, 12:57 |
Сообщение № 18

Группа: Пользователи

Ранг: Новичок

Сообщений: 49

Nic70y, спасибо…че то я сам напутал

 

Ответить

Понравилась статья? Поделить с друзьями:
  • Excel vba сумма значений в столбце
  • Excel vba сумма диапазона ячеек
  • Excel vba строки с объединенной ячейкой
  • Excel vba строки регистр
  • Excel vba строки по формату