Sebenta · Desenvolver algoritmos e rotinas de otimização para desenho automático (UC02915)
- Introdução
- 1. Analisar requisitos e avaliar a viabilidade de automatizar
- 2. Fluxogramas e algoritmia
- 3. Tipos de variáveis em VBA
- 4. Operações com variáveis e ciclos de programação
- 5. Algoritmos de otimização para desenho automático
- 6. Interfaces VBA com softwares de CAD e folhas de cálculo
- 7. Rotinas para o desenho automático
- 8. Rotinas para a inquirição de dados de modelos CAD 2D e 3D
- 9. Exportação de informação: de CAD para documentos texto ou folhas de cálculo
- 10. Importação de informação: de documentos de texto e folhas de cálculo para documentos de CAD
- 11. Normas de segurança e saúde no trabalho
- Erros comuns
- Glossário
- Síntese
- Exercícios resolvidos
Introdução
Um técnico de desenho e projeto/design industrial passa boa parte do tempo a repetir operações: desenhar a mesma família de furos em dezenas de flanges, gerar a mesma vista em série, preencher a mesma lista de materiais peça a peça. Esta sebenta ensina a deixar de fazer isso à mão e a construir rotinas que o próprio software de CAD executa por nós, escritas sobretudo em VBA (Visual Basic for Applications), a linguagem de automação mais comum nos CAD do mercado (também referimos as macros e o AutoLISP de alguns ambientes CAD, como alternativas com a mesma lógica).
O percurso segue a ordem em que um técnico enfrenta o problema na prática: primeiro analisar se vale a pena automatizar e desenhar a lógica num fluxograma; depois dominar os tipos de variáveis, as operações e os ciclos que qualquer rotina usa; a seguir otimizar (por exemplo, o corte de material) e ligar o VBA ao CAD e ao Excel; por fim, montar rotinas de desenho automático, inquirir dados de modelos 2D e 3D, e exportar e importar informação entre o CAD e ficheiros externos, sempre com as normas de segurança presentes.
Objetivos de aprendizagem (referencial): analisar os requisitos e especificações do desenho a automatizar; preparar e executar algoritmos e rotinas de otimização; e transferir informações entre sistemas CAD e outros documentos.
Todo o código desta sebenta foi corrido de facto: os números que aparecem (poupanças, contagens, custos) são resultados reais de execução, não estimativas. Sempre que um exemplo depende da interface do CAD (que só existe dentro do próprio software), isso está identificado como referência, e a lógica de cálculo por trás dele foi isolada e testada à parte, em Python.
1. Analisar requisitos e avaliar a viabilidade de automatizar
Antes de escrever uma única linha de rotina, um técnico faz duas perguntas: o que o desenho tem de ter, e vale a pena automatizá-lo?
Requisitos e especificações
- Requisito: a exigência genérica do desenho (ex.: "a flange tem furos de fixação normalizados").
- Especificação: o valor concreto de cada requisito (ex.: "8 furos M6, círculo de furação Ø100 mm").
Sem esta distinção, a rotina automatiza depressa uma coisa errada. É por isso que a primeira realização do referencial desta UC é analisar os requisitos e especificações do desenho a automatizar, antes de "preparar e executar".
Exemplo resolvido: vale a pena automatizar esta tarefa?
O critério é comparar o tempo poupado ao longo de um ano com o custo de desenvolver a rotina, que só se paga uma vez:
def vale_a_pena_automatizar(frequencia_semana, tempo_manual_min, tempo_dev_min, semanas=52):
"""
Decide se compensa desenvolver uma rotina para uma tarefa de desenho repetitiva.
Otimiza: tempo total humano gasto num ano.
Restrição: o tempo de desenvolvimento da rotina é um custo fixo, pago uma
só vez; o tempo manual poupado escala com o número de ocorrências.
Caso limite: sem ocorrências (frequência ou tempo manual a 0), nunca compensa.
Como se sabe que é melhor: compara-se o tempo manual acumulado num ano
contra o custo de desenvolver a rotina; só compensa se a poupança for positiva.
"""
if frequencia_semana <= 0 or tempo_manual_min <= 0:
return False, 0.0, 0, "sem ocorrências, nada para automatizar"
ocorrencias = round(frequencia_semana * semanas)
tempo_manual_total = ocorrencias * tempo_manual_min
poupanca = tempo_manual_total - tempo_dev_min
compensa = poupanca > 0
motivo = "poupa tempo ao longo do ano" if compensa else "o desenvolvimento custa mais do que poupa"
return compensa, poupanca, ocorrencias, motivo
Corrido com quatro casos:
| Caso | Frequência/semana | Tempo à mão | Tempo a programar | Compensa? | Poupança |
|---|---|---|---|---|---|
| Furos em série | 3 | 8 min | 90 min | Sim | 1158 min/ano |
| Tarefa rara (~1×/ano) | 1/52 | 15 min | 90 min | Não | −75 min |
| Tarefa que nunca acontece | 0 | 10 min | 90 min | Não | 0 min |
| Tarefa demorada e frequente | 10 | 20 min | 120 min | Sim | 10 280 min/ano |
Estes quatro resultados vieram de correr mesmo a função, não de uma estimativa: é a prova de que o mesmo critério (poupança acumulada versus custo de desenvolvimento) muda de conclusão consoante a frequência real da tarefa.
Uma oficina de mobiliário técnico desenha, em média, 3 estantes por semana com o mesmo padrão de furos de fixação. Cada estante demora 8 minutos a furar manualmente no CAD. Desenvolver a rotina demorou 90 minutos. Ao fim de um ano, a rotina já poupou quase 20 horas de trabalho manual repetitivo.
2. Fluxogramas e algoritmia
Um fluxograma representa a lógica de uma rotina em símbolos normalizados, antes de se escrever uma única linha de código VBA. É o critério de desempenho "garantir a estrutura e a sequência de operações a automatizar com recurso a fluxogramas", aplicado.
Símbolos normalizados
| Símbolo | Significado |
|---|---|
| Oval | início ou fim da rotina |
| Retângulo | uma ação (calcular, desenhar, guardar) |
| Losango | uma decisão (verdadeiro/falso) |
| Seta | o sentido do fluxo de execução |
Exemplo resolvido: fluxograma de uma rotina de furação
(Início)
│
▼
[Ler N, diâmetro, x0, y0]
│
▼
<N > 0?> ──não──► (Fim, sem furos)
│ sim
▼
[i = 0]
│
▼
<i < N?> ──não──► (Fim)
│ sim
▼
[calcular ângulo, x, y]
│
[desenhar furo em (x, y)]
│
[i = i + 1] ──► volta a <i < N?>
O losango logo após a leitura dos dados é o caso limite: sem ele, N = 0 tentaria desenhar um furo que não devia existir. Este fluxograma é a base literal do código do capítulo 7.
Erro comum ao desenhar fluxogramas
Esquecer a condição de paragem de um ciclo (o losango "i < N?") é o erro mais frequente: sem ela, a rotina entra num ciclo infinito e trava o CAD. Todo o ciclo tem de ter, no fluxograma, uma seta que sai do losango de decisão para o "Fim".
3. Tipos de variáveis em VBA
Em VBA (Visual Basic for Applications), cada variável guarda um tipo de dado. O critério de desempenho "adequar os diferentes tipos de variáveis dinâmicas à tipologia de rotinas" exige escolher o tipo certo para cada uso.
| Tipo VBA | Guarda | Exemplo de uso numa rotina de desenho |
|---|---|---|
Integer |
inteiro pequeno (−32 768 a 32 767) | número de furos de uma peça |
Long |
inteiro grande | contador de um ciclo com muitas iterações |
Double |
número real, dupla precisão | uma coordenada em milímetros |
String |
texto | a referência da peça, "PC-001" |
Boolean |
verdadeiro ou falso | "a peça está conforme?" |
Variant |
qualquer tipo, decidido em execução | um valor lido de uma célula Excel |
Object |
referência a um objeto do CAD ou do Excel | ThisDrawing, Worksheet |
Dim nFuros As Integer
Dim diametro As Double
Dim referencia As String
Dim conforme As Boolean
Dim oDoc As Object ' referência a um objeto do CAD
Variáveis dinâmicas e âmbito (scope)
Uma variável dinâmica é a que muda de valor ao longo da execução (um contador, uma coordenada atual), ao contrário de uma constante fixa.
- Âmbito local (
Dimdentro de umaSub): só existe enquanto essa rotina corre. - Âmbito de módulo (
Dimno topo do módulo): partilhada por várias rotinas do mesmo ficheiro.
Uma referência de peça como "007" tem de ser String, nunca um tipo numérico: como número, perderia o zero à esquerda e passaria a 7. É um erro comum em rotinas que leem códigos de peça de uma folha de cálculo.
4. Operações com variáveis e ciclos de programação
Divisão real vs divisão inteira
O erro clássico ao operar variáveis numa rotina de corte é confundir divisão real com divisão inteira ao contar quantas peças cabem num comprimento disponível.
comprimento_disponivel_mm = 2500
comprimento_peca_mm = 400
kerf_mm = 3
# ERRADO como contagem de peças (divisão real):
n_pecas_errado = comprimento_disponivel_mm / (comprimento_peca_mm + kerf_mm)
print(n_pecas_errado)
# → 6.20347394540943 (uma peça "meia" não existe fisicamente)
# CORRETO: divisão inteira (piso), o operador `\` em VBA
n_pecas_certo = comprimento_disponivel_mm // (comprimento_peca_mm + kerf_mm)
sobra_mm = comprimento_disponivel_mm - n_pecas_certo * (comprimento_peca_mm + kerf_mm)
print(n_pecas_certo, sobra_mm)
# → 6 82
Executado: o resultado correto é 6 peças inteiras, com 82 mm de sobra, confirmado por assert n_pecas_certo == 6 e assert sobra_mm == 82 no código de origem. Em VBA, a divisão inteira usa-se com n = disponivel \ (peca + kerf), com uma barra invertida, diferente de /.
Ciclos: For, Do While e Do Until
' For: usa-se quando se sabe à partida quantas vezes repetir
For i = 0 To nFuros - 1
' desenhar furo i
Next i
' Do While: repete enquanto a condição for verdadeira
i = 0
Do While i < nFuros
i = i + 1
Loop
' Do Until: repete até a condição se tornar verdadeira
i = 0
Do Until i = nFuros
i = i + 1
Loop
A mesma lógica, testada em Python, gerando furos alinhados com espaçamento fixo:
def furos_em_linha(n_furos, espaco_mm, x0=0.0):
"""Caso limite: n_furos <= 0 devolve lista vazia; n_furos == 1 fica só
em x0 (não há espaçamento a aplicar a um único ponto)."""
if n_furos <= 0:
return []
return [round(x0 + i * espaco_mm, 2) for i in range(n_furos)]
Executado: furos_em_linha(5, 40, x0=10) devolve [10, 50, 90, 130, 170]; furos_em_linha(0, 40) devolve []; furos_em_linha(1, 40, x0=10) devolve [10.0]. Os três casos foram confirmados por assert no ficheiro de origem.
5. Algoritmos de otimização para desenho automático
Otimizar é escolher, de entre várias soluções válidas, a que minimiza (ou maximiza) uma medida concreta, sob uma restrição, e provar que é de facto melhor comparando com uma alternativa nos mesmos dados.
Numa rotina de corte de barras de stock:
- O que se otimiza: o número de barras consumidas (menos barras = menos desperdício e menos custo de material).
- A restrição: nenhuma peça pode exceder o comprimento da barra, e cada corte perde uma folga de serra (kerf).
- A estratégia: First Fit Decreasing (FFD), ordenar as peças da maior para a menor antes de as encaixar na primeira barra onde caibam. É sabido que o FFD nunca piora o resultado de uma ordem arbitrária e, tipicamente, aproxima-se bastante do ótimo teórico.
Exemplo resolvido: cortar barras de alumínio
Uma estrutura de mobiliário técnico precisa de 6 reforços horizontais de 831 mm e 4 reforços verticais de 1597 mm, cortados de barras de stock de 2500 mm, com folga de serra (kerf) de 3 mm.
def cortar_barras(pecas_mm, barra_mm, kerf_mm=3):
"""
Algoritmo guloso (First Fit): percorre as peças pela ordem dada e
coloca cada uma na primeira barra aberta onde caiba; se não couber
em nenhuma, abre uma barra nova.
Otimiza: número de barras de stock consumidas.
Restrição: cada peça cortada consome ainda o kerf (folga de corte).
Caso limite: uma peça maior do que a barra é impossível de cortar,
e tem de ser sinalizada em vez de entrar num ciclo sem fim.
"""
barras = []
impossiveis = []
for p in pecas_mm:
if p > barra_mm:
impossiveis.append(p)
continue
necessario = p + kerf_mm
colocado = False
for i, livre in enumerate(barras):
if necessario <= livre:
barras[i] -= necessario
colocado = True
break
if not colocado:
barras.append(barra_mm - necessario)
return barras, impossiveis
Corrido com a mesma lista de peças, em duas ordens diferentes de entrada:
| Ordem das peças à entrada | Barras usadas | Stock consumido | Desperdício |
|---|---|---|---|
| Ordem de produção (as 6 prateleiras chegam primeiro, depois os 4 montantes) | 7 | 17 500 mm | 6096 mm |
| FFD, do maior para o menor | 5 | 12 500 mm | 1096 mm |
Poupança real: (7 − 5) / 7 = 28,6% menos barras, calculada a partir dos números da execução (7 e 5 barras), no sentido correto da comparação: a base é a estratégia pior (ordem de produção), e o ganho é o que a FFD poupa sobre essa base.
O ganho da FFD não vem de "cortar melhor" cada peça, vem de decidir a ordem em que as peças entram no algoritmo guloso. Peças grandes colocadas primeiro deixam menos espaço morto do que peças pequenas que enchem uma barra e obrigam a próxima peça grande a abrir barra nova.
Testar e validar o algoritmo
Antes de confiar num algoritmo de otimização, testam-se os casos limite:
assert cortar_barras([], 2500) == ([], []) # lista vazia
assert cortar_barras([3000], 2500) == ([], [3000]) # peça maior que a barra
b_uma, _ = cortar_barras([100], 2500)
assert b_uma == [2500 - 100 - 3] # uma só peça
Os três assert correram sem falhar: lista vazia devolve zero barras sem erro, uma peça maior do que o stock é sinalizada em vez de travar a rotina, e uma peça única ocupa uma barra com o desperdício esperado.
6. Interfaces VBA com softwares de CAD e folhas de cálculo
O VBA corre dentro do software de CAD e acede aos seus objetos através de uma interface de automação (a API do CAD). É pseudocódigo de referência, porque só corre com o CAD instalado:
' VBA (referência, depende da aplicação de CAD instalada)
Sub DesenharFuroExemplo()
Dim oDoc As Object
Set oDoc = ThisDrawing
Dim centro(2) As Double
centro(0) = 50: centro(1) = 0: centro(2) = 0
oDoc.ModelSpace.AddCircle centro, 3 ' furo Ø6 mm
End Sub
A parte que é testável sem CAD é a lógica de cálculo (as coordenadas do centro), que já vimos nos capítulos 2 e 7; a chamada AddCircle é a única linha específica da API.
Funções de interface com o Excel
' VBA (referência)
Dim oExcel As Object
Set oExcel = CreateObject("Excel.Application")
oExcel.Workbooks.Open "C:\projeto\lista_materiais.xlsx"
Dim valor As Double
valor = oExcel.Sheets(1).Cells(2, 3).Value ' ler a célula C2
oExcel.Sheets(1).Cells(2, 4).Value = valor * 1.23 ' escrever com IVA
oExcel.Quit
A parte de cálculo (aplicar o IVA) testa-se sem Excel nem CAD:
preco_sem_iva = 14.50
preco_com_iva = round(preco_sem_iva * 1.23, 2)
print(preco_com_iva) # → 17.84
Executado: 17.84, confirmado por assert preco_com_iva == 17.84.
7. Rotinas para o desenho automático
Uma rotina de desenho automático junta os blocos anteriores num fluxo com seis passos:
1. Ler parâmetros de entrada (N, dimensões, material)
2. Validar (caso limite: N <= 0, dimensão negativa)
3. Calcular geometria em ciclo (For / Do)
4. Desenhar cada elemento via API do CAD
5. Aplicar regras de otimização, se aplicável (capítulo 5)
6. Confirmar (contagem de elementos criados)
Exemplo resolvido: furos num círculo de fixação
Uma tarefa muito comum em peças mecânicas e de mobiliário técnico é distribuir N furos uniformemente num círculo de fixação (bolt circle).
import math
def furos_em_circulo(n_furos, diametro_mm, x0=0.0, y0=0.0, angulo_inicial=0.0):
"""
Caso limite: n_furos <= 0 devolve lista vazia; n_furos == 1 coloca o
único furo no ângulo inicial, sem dividir 360°.
"""
if n_furos <= 0:
return []
raio = diametro_mm / 2
passo = 360 / n_furos if n_furos > 1 else 0
pontos = []
for i in range(n_furos):
ang = math.radians(angulo_inicial + i * passo)
x = round(x0 + raio * math.cos(ang), 2) + 0.0
y = round(y0 + raio * math.sin(ang), 2) + 0.0
pontos.append((x, y))
return pontos
Corrido para uma flange com 8 furos e círculo de furação Ø100 mm (furos_em_circulo(8, 100)), a rotina devolveu, entre outros pontos:
| Furo | x (mm) | y (mm) |
|---|---|---|
| 1 (0°) | 50,0 | 0,0 |
| 3 (90°) | 0,0 | 50,0 |
| 5 (180°) | −50,0 | 0,0 |
| 7 (270°) | 0,0 | −50,0 |
Estes valores foram confirmados por cálculo trigonométrico manual (assert pontos[0] == (50.0, 0.0) e assert pontos[2] == (0.0, 50.0)), e os casos limite furos_em_circulo(0, 100) == [] e furos_em_circulo(1, 100) == [(50.0, 0.0)] também passaram.
Verificação automática de regras de desenho
Depois de desenhar, uma boa rotina verifica o resultado contra as regras do gabinete de projeto, antes de o enviar para produção. Não otimiza nenhum valor: apenas classifica cada peça como conforme ou não conforme.
def verificar_regras(pecas, espessura_min_mm=2.0, furo_min_dist_borda_mm=5.0):
"""Rotina de verificação automática de regras de desenho (design rule
check). Corre depois de gerar o desenho automático, antes de o enviar
para produção."""
problemas = []
for peca in pecas:
nome = peca["nome"]
if peca["espessura_mm"] < espessura_min_mm:
problemas.append(f"{nome}: espessura {peca['espessura_mm']} mm < mínimo {espessura_min_mm} mm")
if peca["dist_furo_borda_mm"] < furo_min_dist_borda_mm:
problemas.append(f"{nome}: furo a {peca['dist_furo_borda_mm']} mm da borda < mínimo {furo_min_dist_borda_mm} mm")
return problemas
Corrido com duas peças, uma conforme e outra não: verificar_regras([{"nome": "Suporte A", "espessura_mm": 3.0, "dist_furo_borda_mm": 8.0}, {"nome": "Suporte B", "espessura_mm": 1.5, "dist_furo_borda_mm": 6.0}]) devolveu exatamente um problema, "Suporte B: espessura 1.5 mm < mínimo 2.0 mm", e nenhum para o Suporte A. Os casos limite verificar_regras([]) == [] (sem peças, sem problemas) e uma peça totalmente conforme sem nenhum problema assinalado também foram confirmados.
8. Rotinas para a inquirição de dados de modelos CAD 2D e 3D
Inquirir um modelo é ler as suas propriedades geométricas (área e perímetro em 2D; volume, massa e centro de gravidade em 3D) por rotina, em vez de as medir manualmente. Aplica-se diretamente a fabrico, orçamentação e planeamento da produção.
Em VBA, o volume vem das propriedades de massa do próprio CAD (referência):
' VBA (referência, depende do CAD instalado)
Dim volume As Double
volume = oPeca.MassProperties.Volume ' em mm3
Exemplo resolvido: orçamentar uma peça a partir do volume inquirido
DENSIDADES_KG_M3 = {"aluminio": 2700, "aco": 7850, "pla": 1240}
def orcamentar_peca(volume_cm3, material, preco_kg_eur, tempo_maquina_min, custo_hora_maquina_eur):
if material not in DENSIDADES_KG_M3:
raise ValueError(f"material desconhecido: {material}")
volume_m3 = volume_cm3 / 1_000_000
massa_kg = volume_m3 * DENSIDADES_KG_M3[material]
custo_material = massa_kg * preco_kg_eur
custo_maquina = (tempo_maquina_min / 60) * custo_hora_maquina_eur
return {
"massa_kg": round(massa_kg, 3),
"custo_material_eur": round(custo_material, 2),
"custo_maquina_eur": round(custo_maquina, 2),
"custo_total_eur": round(custo_material + custo_maquina, 2),
}
Corrido com um suporte em alumínio, volume = 145 cm³ (o valor que a rotina inquiriria do modelo 3D):
| Grandeza | Valor obtido |
|---|---|
| Massa | 0,392 kg |
| Custo de material (4,80 €/kg) | 1,88 € |
| Custo de máquina (18 min a 35 €/h) | 10,50 € |
| Custo total | 12,38 € |
Confirmado por cálculo manual: 0,000145 m³ × 2700 kg/m³ = 0,3915 kg ≈ 0,392 kg (arredondado a 3 casas). Testado também o caso limite de um material inexistente no dicionário ("titanio"): a rotina levanta ValueError em vez de devolver um número inventado.
9. Exportação de informação: de CAD para documentos texto ou folhas de cálculo
Exportar é escrever, a partir do CAD, um ficheiro que outra aplicação consegue ler. O formato mais universal é o CSV (valores separados por vírgula).
import csv
def exportar_bom(pecas, caminho):
"""Exporta a lista de materiais (BOM) extraída do modelo CAD para CSV."""
with open(caminho, "w", newline="", encoding="utf-8") as f:
campos = ["codigo", "descricao", "quantidade", "preco_unit_eur"]
w = csv.DictWriter(f, fieldnames=campos)
w.writeheader()
for p in pecas:
w.writerow(p)
Exemplo resolvido: a BOM de uma pequena estante.
| Código | Descrição | Quantidade | Preço unit. (€) |
|---|---|---|---|
| PC-001 | Painel lateral MDF 18mm | 2 | 14,50 |
| PC-002 | Prateleira MDF 18mm | 4 | 9,20 |
| PC-003 | Dobradiça oculta | 8 | 1,35 |
| PC-004 | Puxador alumínio | 2 | 3,10 |
Custo total = 2×14,50 + 4×9,20 + 8×1,35 + 2×3,10 = 29,00 + 36,80 + 10,80 + 6,20 = 82,80 € (calculado por custo_total() e confirmado à mão). Esta lista, exportada para CSV, é o que o departamento de compras usa para encomendar os materiais, sem reescrever nada manualmente.
10. Importação de informação: de documentos de texto e folhas de cálculo para documentos de CAD
Importar é o caminho inverso: ler um ficheiro externo e usar os dados para gerar ou atualizar o desenho, cumprindo o critério de desempenho "garantir a transferência bidirecional de informação entre documentos CAD e ficheiros externos".
def importar_bom(caminho):
"""Importa de volta um CSV para uma lista de dicionários, com os tipos corretos."""
pecas = []
with open(caminho, encoding="utf-8") as f:
for linha in csv.DictReader(f):
linha["quantidade"] = int(linha["quantidade"])
linha["preco_unit_eur"] = float(linha["preco_unit_eur"])
pecas.append(linha)
return pecas
Corrido em conjunto com o capítulo 9 (exportar a BOM e importá-la de volta): os 4 artigos e o custo total de 82,80 € vieram idênticos ao original, confirmado por assert abs(custo_orig - custo_lida) < 0.001. É esta viagem de ida e volta, exportar depois importar, que prova que nenhum dado se perde ou corrompe na transferência.
Sem converter explicitamente "4" (texto, como vem do CSV) para 4 (número), as contas seguintes falhariam ou dariam resultados errados. Todo o CSV chega como texto; a rotina de importação é responsável por converter cada campo para o tipo certo.
11. Normas de segurança e saúde no trabalho
Automatizar não dispensa as normas de segurança e saúde no trabalho, uma aptidão avaliada nesta UC tal como as de programação:
- Ergonomia do posto de trabalho: ecrã à altura dos olhos, pausas regulares, boa iluminação, evitar posturas fixas prolongadas em sessões longas de desenvolvimento de rotinas.
- O risco principal de uma rotina automática não é físico, é o de propagar um erro: uma rotina que corre em segundos sobre 200 peças replica um erro de lógica 200 vezes antes de alguém dar por isso.
- Validar antes de produzir: correr a rotina sobre uma única peça de teste, confirmar o resultado, e só depois aplicá-la à série completa.
- Manter plotters e impressoras de grandes formatos com a manutenção e a sinalética de segurança em dia, e seguir os planos e normas de segurança do posto de trabalho.
Antes de mandar produzir com uma rotina nova, valida sempre o resultado numa peça isolada. Um erro numa rotina de desenho automático replica-se por todas as peças de uma série de uma só vez, ao contrário de um erro manual, que fica confinado a uma peça.
Erros comuns
- Automatizar uma tarefa rara: o tempo de desenvolvimento nunca se paga se a tarefa quase não se repete (ver capítulo 1).
- Desenhar código sem fluxograma: perder-se a meio de um ciclo com uma condição mal pensada (capítulo 2).
- Tipar tudo como
Variant: funciona, mas esconde erros de tipo que só aparecem em produção (capítulo 3). - Confundir divisão real com divisão inteira: contar "6,2 peças", que não existem fisicamente (capítulo 4).
- Otimizar sem comparar com uma alternativa: mudar por mudar, sem provar que o resultado é melhor (capítulo 5).
- Misturar cálculo com chamadas à API do CAD: torna a lógica impossível de testar sem abrir o CAD (capítulo 6).
- Saltar a validação de parâmetros: uma rotina que desenha lixo perante um valor inesperado (capítulo 7).
- Orçamentar "a olho" em vez de inquirir o modelo 3D: duas peças com a mesma silhueta e espessuras diferentes têm massas muito diferentes (capítulo 8).
- Exportar números como texto com vírgula decimal para um sistema que espera ponto: erros de leitura silenciosos (capítulo 9).
- Importar sem validar o tipo de cada campo: tudo fica como texto e as contas seguintes falham (capítulo 10).
- Correr uma rotina nova diretamente sobre o ficheiro final, sem testar numa cópia (capítulo 11).
Glossário
- Rotina: um pequeno programa, escrito em VBA ou equivalente, que o CAD executa por nós.
- Fluxograma: representação gráfica normalizada da lógica de uma rotina.
- Variável dinâmica: variável cujo valor muda ao longo da execução da rotina.
Dim: instrução VBA que declara uma variável e o seu tipo.Integer/Long/Double/String/Boolean/Variant/Object: os tipos de dados mais usados em VBA.- Ciclo: bloco de instruções repetido (
For,Do While,Do Until). - Kerf: a folga de material consumida por cada corte de serra ou fresa.
- First Fit Decreasing (FFD): heurística de otimização que ordena as peças da maior para a menor antes de as encaixar.
- Verificação automática de regras de desenho (design rule check): rotina que confirma se cada peça cumpre as regras do gabinete de projeto, antes de seguir para produção.
- API (interface de automação): o conjunto de objetos e funções que o CAD ou o Excel expõem ao VBA.
- Inquirir: ler propriedades geométricas (área, volume, massa) de um modelo CAD por rotina.
- BOM (Bill of Materials): a lista de materiais de uma peça ou conjunto.
- CSV: formato de ficheiro de texto com valores separados por vírgula, lido por qualquer folha de cálculo.
- Exportar / Importar: escrever dados do CAD para um ficheiro externo, ou lê-los de volta para o CAD.
Síntese
Uma rotina de desenho automático nasce de uma análise de requisitos e de uma avaliação de viabilidade, ganha forma num fluxograma, e materializa-se em VBA com os tipos de variáveis, as operações e os ciclos certos. Quando o objetivo é reduzir desperdício, aplica-se um algoritmo de otimização testado e comparado com uma alternativa, nunca "por adivinhação". As interfaces ligam o VBA ao CAD e ao Excel, permitindo rotinas de desenho automático completas, inquirição de dados de modelos 2D e 3D para fabrico e orçamentação, e a exportação e importação de informação entre o CAD e ficheiros externos, sempre validada e sempre com as normas de segurança em mente, porque um erro numa rotina se replica por toda uma série de peças de uma só vez.
Exercícios resolvidos
1. Uma tarefa repete-se 5 vezes por semana, demora 6 minutos à mão, e a rotina levaria 200 minutos a desenvolver. Compensa automatizar?
Resolução: ocorrências/ano = 5 × 52 = 260; tempo manual total = 260 × 6 = 1560 min; poupança = 1560 − 200 = 1360 min. Como a poupança é positiva, compensa, com uma folga considerável.
2. Uma peça de 2800 mm tem de ser cortada de barras de stock de 2500 mm. O que deve fazer a rotina de corte?
Resolução: a peça é maior do que a barra, é um caso impossível, não um caso a "forçar". A rotina deve sinalizar a peça como impossível de cortar (como faz
cortar_barras, acrescentando-a à listaimpossiveis) e nunca tentar encaixá-la num ciclo sem fim.
3. Qual o tipo de variável VBA correto para guardar o código de uma peça, "A007", e porquê?
Resolução:
String. Um tipo numérico perderia o "A" e o zero à esquerda; como texto, o código mantém-se exatamente como foi definido pelo gabinete de projeto.
4. Calcula, por divisão inteira, quantas peças de 350 mm (mais 2 mm de kerf) cabem numa barra de 3000 mm, e qual a sobra.
Resolução: 3000 // (350 + 2) = 3000 // 352 = 8 peças; sobra = 3000 − 8×352 = 3000 − 2816 = 184 mm.
5. Uma rotina lê o volume de uma peça em aço, 60 cm³, ao preço de 1,20 €/kg. Qual a massa e o custo do material (sem custo de máquina)?
Resolução: volume_m3 = 60/1 000 000 = 0,00006 m³; massa = 0,00006 × 7850 = 0,471 kg; custo = 0,471 × 1,20 = 0,57 € (arredondado a 2 casas).