O objetivo desse capítulo é mostrar como resolver um problema computacional razoavelmente grande, dividindo-o em problemas menores: ao encarar um problema computacional, vamos utilizar funções e macros auxiliares que resolverão parte do problema. Em seguida, vamos criar outros programas que utilizam estas pequenas soluções para compor soluções maiores, e desta forma comporemos soluções progressivamente mais complexas.
Vamos supor que nós temos a seguinte planilha, que realiza o controle de estoque de uma empresa.
A | B | C | D | |
PRODUTO | Em Estoque | Estoque Mínimo | Pedido de Compra | |
1 | Vassoura | 12 | 100 | |
2 | Rodo | 120 | 70 | |
3 | Esfregão | 5 | 50 | |
... |
Cada produto em estoque está associado a um estoque mínimo. Vamos fazer um programa que, ao detectar um produto cuja quantidade em estoque está abaixo do mínimo, decide quantas unidades devem ser compradas para restabelecer o estoque mínimo.
Por onde começamos?
A idéia inicial é formular a solução do problema de forma esquemática, que servirá de guia para dividir este problema em problemas menores. Basicamente, o que o programa deve fazer é o seguinte:
- 0.
- Para cada linha da planilha:
- 1.
- Descobrir o quantidade de itens faltantes no estoque
- 2.
- Atualizar a coluna Pedido com o valor calculado
Esta descrição serve de ``esqueleto'' para o desenvolvimento. O item 2 nós sabemos fazer: é só usar cells(linha,coluna) = valor, onde o valor foi calculado no item 1. Então vamos supor que há uma função que, para uma dada linha, calcula o valor faltante no estoque. A nossa representação esquemática pode ser refinada para:
- 0.
- Para cada linha da planilha:
- 1.
- valor = RepoeEstoque( linha )
- 2.
- cells( linha, ``coluna do Pedido de Compra'' ) = valor
Então vamos escrever a função RepoeEstoque que calcula a quantidade de estoque que precisa ser reposta.
Const ColunaProd = 1 'cria um ``apelido'' (ColunaProd) para a Constante 1
Const ColunaEs = 2
Const ColunaMin = 3
Const ColunaPed = 4
Const ColunaUnit = 5
Const ColunaCusto = 6
Function RepoeEstoque(Linha As Integer) As Integer
'Este programa descobre qual a quantidade de produto
' necessária em um pedido de compra para que o estoque
' atual iguale o estoque mínimo na Linha da planilha
Dim emEstoque As Integer
Dim estoqueMin As Integer
Dim faltando As Integer
'Inicializações
emEstoque = Cells(Linha, ColunaEs)
estoqueMin = Cells(Linha, ColunaMin)
faltando = 0 'Assume inicialmente que estoque está OK
'Principal
If emEstoque < estoqueMin Then
faltando = estoqueMin - emEstoque
End If
RepoeEstoque = faltando
End Function
Inicialmente, note as primeiras linhas na forma
Const <NOME> = <VALOR>
Este comando declara uma Constante, que pode ser usada em qualquer parte do módulo em lugar do número. E para que usar constantes? Em primeiro lugar, porque o programa fica mais claro (ColunaMin é muito mais expressivo que o número 3 para sabermos a que este número se refere). Em segundo lugar, se houver várias ocorrências da constante no programa, para mudar seu valor basta alterar o valor associado a ela na declaração Const. Sem usar Const, teríamos que sair ``caçando'' as ocorrênicas do número e alterá-la no corpo do programa. No exemplo, usamos Const para o número das colunas, uma mudança de ordem nas colunas da planilha necessita apenas uma mudança nas declarações Const. (Dê uma olhada no programa e imagine como seria fácil cometermos um erro se não usássemos Const).
A função RepoeEstoque recebe como único parâmetro o número da linha corrente, e retorna 0 se não há estoque a repor. Ela é uma função bastante ordinária, sem nada de especial.
Especial é o fato de podermos utilizá-la como função auxiliar para resolver o problema de atualização da coluna de Pedido de compra na planilha. O resultado final almejado é uma macro que transforme a planilha inicial na seguinte planilha
A | B | C | D | |
PRODUTO | Em Estoque | Estoque Mínimo | Pedido de Compra | |
1 | Vassoura | 12 | 100 | 88 |
2 | Rodo | 120 | 70 | |
3 | Esfregão | 5 | 50 | 45 |
... |
A macro que faz esta transformação (usando RepoeEstoque) é a seguinte:
Sub PedidoCompra()
'Monta o pedido de compra para toda a planilha
Dim compra As Integer
Dim lin As Integer
'Inicialização
lin = 2 'Primeira linha de dados
'Varre toda a planilha
Do While Not IsEmpty(Cells(lin, ColunaProd))
'Descobre qtdd a comprar para o produto corrente
compra = RepoeEstoque(lin)
If compra > 0 Then
'Insere pedido de compra na planilha
Cells(lin, ColunaPed) = compra
End If
'Próxima linha
lin = lin + 1
Loop
End Sub
Suponha agora que nós queremos não apenas saber quantas unidades comprar, mas também calcular o custo do pedido de compra. Para isso precisamos de duas novas colunas na planilha, uma delas com o preço unitário do produto e a outra com o custo da compra para cada produto. No final queremos também computar o custo total do pedido de compra.
A | B | C | D | E | F | |
PRODUTO | Em Estoque | Estoque | Pedido de | Preço | Custo | |
Mínimo | Compra | Unitário | Compra | |||
1 | Vassoura | 12 | 100 | R$2,50 | ||
2 | Rodo | 120 | 70 | R$3,00 | ||
3 | Esfregão | 5 | 50 | R$1,25 |
O esquema geral da solução é o seguinte:
- 1.
- Monta Pedido de Compra
- 2.
- Calcula o Custo
O Item 1 nós já sabemos fazer, basta usar a macro PedidoCompra. O Item 2 pode ser refinado em
- 0.
- Para cada linha da planilha
- 1.
- Calcula o preço da compra
- 2.
- Atualiza a planilha
O cálculo do item 1, pode, por exemplo, ser feito por uma função auxiliar CustoCompra.
Function CustoCompra(Linha As Integer) As Double
Dim quant As Integer
Dim precoUnit As Double
quant = Cells(Linha, ColunaPed)
precoUnit = Cells(Linha, ColunaUnit)
CustoCompra = quant * precoUnit
End Function
Em seguida, podemos fazer uma macro que compõe a coluna Custo Compra utilizando a função CustoCompra:
Sub CustoPedido()
Dim custolin As Double
Dim lin As Integer
Dim total As Double 'custo total do pedido
'Inicia
lin = 2
total = 0
Do While Not IsEmpty(Cells(lin, ColunaProd))
custolin = CustoCompra(lin)
Cells(lin, ColunaCusto) = custolin
total = total + custolin
'proxima linha
lin = lin + 1
Loop
'Escreve custo total sob os custos
Cells(lin, ColunaCusto) = "Custo total: " & total
End Sub
O resultado da utilização consecutiva das macros MontaPedido e Custo Pedido é a seguinte planilha:
A | B | C | D | E | F | |
PRODUTO | Em Estoque | Estoque Mínimo | Pedido de Compra | Preço Unitário | Custo Compra | |
1 | Vassoura | 12 | 100 | 88 | R$2,50 | 220 |
2 | Rodo | 120 | 70 | R$3,00 | ||
3 | Esfregão | 5 | 50 | 45 | R$1,25 | 56,25 |
CustoTotal: 276,25 |
Agora, ao invés de chamarmos consecutivamente as duas macros, podemos ter uma macro que faça exatamente isso:
Sub MontaPedido()
PedidoCompra
CustoPedido
End Sub
Exercícios
Considere a seguinte planilha:
Aluno | Média Provas | Média EPs | Média Final | Resultado |
---|---|---|---|---|
Adalberto | 7,0 | 9,0 | ||
Belinda | 3,0 | 6,0 | ||
Clementino | 4,5 | 9,0 | ||
Danusa | 5,5 | 4,0 | ||
Eleutério | 2,0 | 4,0 |
MF = (3 * MP + MEP)/4, se MP >= 4 e MEP >= 4 MF = min( MP, MEP), caso contrário.
Quantos parâmetros esta função deve receber?