Eu tive que fazer uma coisa parecida para uma matriz de decisão ponderada com Categorias que eram individualmente ponderadas. A planilha é algo parecido com isto:
emqueo"#NAME?" coisa aparece são várias fórmulas que eu vou descrever. A planilha depende de macros - assim que estiverem ativadas, a opção "#NAME?" coisa vai embora e o número correto aparece.
Cada categoria tem vários critérios com pesos. Abaixo dos critérios, os totais da categoria são calculados, mas na linha à esquerda dos totais está uma célula com a palavra "Categoria". As pontuações da categoria usam essa fórmula:
=ROUND(SUMPRODUCT(range_up($C83),range_up(D83))/SUM(range_up($C83)),1)
A fórmula acima estaria correta se fosse inserida na célula D84 e o peso da categoria estivesse em $ C84.
As pontuações finais usam essa fórmula:
=sum_categories($B4:$B98,1,2)
onde "$ B4: $ B98" é o intervalo que contém a palavra "Categoria", o "1" é quantas colunas à direita da coluna "Categoria" os pesos aparecem, e o "2" é quantos colunas à direita da coluna "Categoria" aparecem as pontuações (ou seja, esta deve ser a coluna na qual a fórmula está).
As fórmulas acima usam duas funções, range_up e sum_categories, fornecidas abaixo:
Function range_up(r As Range) As Range
Dim t As Range, b As Range
Application.Volatile
Set b = r.Cells(1, 1) 'make sure it's only one cell
If IsEmpty(b.Value) Then 'if cell is empty, start one cell up
Set b = b.offset(-1)
End If
'end(xlup) has strange behaviour if cell above is blank, so fix it manually
If IsEmpty(b.offset(-1)) Then
Set t = b
Else
Set t = b.End(xlUp)
End If
Set range_up = t.Resize(b.Row - t.Row + 1)
End Function
Function sum_categories(r As Range, offset1 As Integer, offset2 As Integer) As Variant
Dim sum As Variant
Dim c As Range
Application.Volatile
sum = 0
For Each c In r.Cells
If c.Value = "Category" Then
sum = sum + c.offset(0, offset1).Value * c.offset(0, offset2).Value
End If
Next c
sum_categories = sum
End Function
Por fim, se você quiser recalcular manualmente, inclua um botão em seu formulário que chame essa função:
Sub force_recalc()
Application.CalculateFullRebuild
End Sub