Soma de custos hierárquica🔗

Problema. Um orçamento em que cada fase soma seus itens e o total geral soma as fases, sem recalcular nada à mão.

Solução. Atributo custo nas folhas e fórmula de soma nos nós internos.

Antes de começar

O que você vai aprender

  • Montar um orçamento em que cada nível soma o nível abaixo
  • Usar num0 para tratar texto de atributo como número
  • Escolher entre somar filhos diretos e somar o ramo inteiro

Estrutura🔗

Orçamento do projeto
├── Infraestrutura
│   ├── Servidores      custo: 24000
│   ├── Rede            custo: 8000
│   └── Licenças        custo: 12000
├── Equipe
│   ├── Desenvolvimento custo: 180000
│   └── Design          custo: 45000
└── Contingência        custo: 25000

Passos🔗

  1. Registre a chave custo em Editar → Atributos → Gerenciar atributos do mapa. Isso evita variações de escrita.

  2. Preencha custo nas folhas, com números puros — sem R$, sem separador de milhar, ponto como decimal.

  3. Nos nós de fase, crie o atributo subtotal:

    =node.children.sum { it['custo'].num0 }
  4. Na raiz do ramo, crie total somando o ramo inteiro:

    =node.branch.sum { it['custo'].num0 }

    Atenção: branch inclui o próprio nó. Se a raiz não tiver custo próprio, não há dupla contagem.

Formatando como moeda🔗

Números crus são difíceis de ler. Duas opções:

=def v = node.children.sum { it['custo'].num0 }
 String.format('R$ %,.2f', v)

Ou, com separador brasileiro explícito:

=def v = node.children.sum { it['custo'].num0 }
 'R$ ' + String.format('%,.2f', v).replace(',', '§').replace('.', ',').replace('§', '.')

Extensões úteis🔗

Percentual do total. Em cada fase:

=def meu = node.branch.sum { it['custo'].num0 }
 def tudo = node.map.root.branch.sum { it['custo'].num0 }
 tudo ? "${(meu*100/tudo).round(1)}%" : '—'

Custo médio por item:

=node.leaves ? (node.leaves.sum { it['custo'].num0 } / node.leaves.size()).round(2) : 0

Só o que foi aprovado, marcado com check:

=node.branch.findAll { it.icons.icons.contains('button_ok') }.sum { it['custo'].num0 } ?: 0

Destaque do maior item:

=node.leaves.max { it['custo'].num0 }?.text

Cuidados🔗

  • Use num0, não num. Uma folha sem custo derruba a soma com num e é tratada como zero com num0.
  • sum sobre lista vazia devolve null; o ?: 0 no fim resolve.
  • Formate a moeda só na exibição. Se o valor formatado virar entrada de outra fórmula, a conversão falha.
  • Datas e valores em formato único — restrinja pelos atributos registrados.

Erros comuns

  • Digitar R$ 24.000,00 no atributo: a conversão numérica falha e a soma vira zero
  • Somar node.children quando a estrutura tem níveis intermediários — o certo é node.leaves
  • Não registrar a chave custo e acabar com custo, Custo e valor no mesmo mapa
  • Pôr a fórmula no texto do nó, substituindo o rótulo pelo número

Você aprendeu

  • Números puros no atributo; formatação é assunto de exibição, não de dado
  • num0 converte texto em número tratando vazio como zero
  • node.children soma um nível; node.leaves soma o ramo inteiro
  • Registrar a chave é o que impede a soma de mentir

Perguntas para reflexão

  1. Por que valores de atributo precisam de num0 antes de somar?
  2. Quando usar node.leaves em vez de node.children?
  3. Que problema o registro de atributos resolve nesta receita?
  4. Por que a fórmula fica melhor no atributo do que no texto do nó?

Artigos relacionados

Referências🔗

  1. Freeplane — Formulas
  2. Freeplane — Data recognition and data formats