Pesquisas & Curiosidades Tech + Ciência

Explore o futuro com
Mentes Codificadas

Mergulhe em descobertas fascinantes da tecnologia e das ciências. Pesquisas, curiosidades e tendências que moldam o mundo digital e científico.

120+ Artigos
8 Categorias
5k+ Leitores
Rolar
◆ Inteligência Artificial  ◆ Física Quântica  ◆ Biotecnologia  ◆ Exploração Espacial  ◆ Machine Learning  ◆ Neurociência  ◆ Computação Quântica  ◆ Genômica  ◆ Robótica  ◆ Cibersegurança  

Últimas Descobertas

Os conteúdos mais relevantes e instigantes da semana

Atualizado ao vivo

Categorias

Encontre conteúdos organizados por área do conhecimento

Mundo Tech

Inovações, tendências e o que vem por aí no universo tecnológico

LLMs e o Futuro da Programação: O Fim dos Devs?

Modelos de linguagem de grande escala estão automatizando tarefas de código, mas a criatividade humana ainda é insubstituível...

Criptografia Pós-Quântica: Protegendo os Dados do Futuro

Com o avanço dos computadores quânticos, os algoritmos de criptografia atuais estão com os dias contados...

6G: A Próxima Revolução das Telecomunicações já Está Sendo Construída

Enquanto o 5G ainda se expande, laboratórios ao redor do mundo já desenvolvem o padrão que o sucederá...

Processamento de IA na Borda: Inteligência sem a Nuvem

Dispositivos cada vez mais potentes permitem rodar modelos de IA diretamente no hardware local, sem internet...

Curiosidades Incríveis

Fatos surpreendentes que vão mudar a forma como você vê o mundo

01

O DNA humano contém ~3 bilhões de pares de bases

Se esticado, o DNA de uma única célula mediria cerca de 2 metros. Multiplicado por todas as células do corpo, daria para ir até Plutão e voltar várias vezes.

02

A internet pesa cerca de 50 gramas

Se somarmos a massa de todos os elétrons em movimento transmitindo dados pela internet simultaneamente, o resultado é aproximadamente 50 gramas.

03

Buracos negros emitem radiação

A Radiação de Hawking prevê que buracos negros lentamente "evaporam" ao longo de tempo astronomicamente longo, perdendo massa e energia.

04

Algoritmos já compõem músicas indistinguíveis

Em testes duplo-cegos, ouvintes não conseguem diferenciar composições de IA de músicas criadas por humanos em mais de 60% dos casos.

05

Neurônios e transistores têm velocidades similares

Um neurônio dispara a cerca de 200 Hz, enquanto transistores modernos operam a GHz — mas a eficiência energética do cérebro ainda é imbatível.

06

Existem mais átomos em um grão de areia que estrelas no universo observável

Um grão de areia contém cerca de 10²³ átomos, enquanto o universo observável tem estimados 10²² estrelas.

Fronteiras da Ciência

Pesquisas e descobertas que expandem os limites do conhecimento humano

CRISPR 3.0: Edição de Base Abre Novas Fronteiras na Medicina

A nova geração de ferramentas de edição genética permite corrigir mutações pontuais com precisão sem precedentes...

James Webb Revela Galáxias Mais Antigas que o Esperado pelo Modelo Padrão

Imagens do telescópio espacial contradizem previsões cosmológicas e provocam revisão de teorias sobre a formação do universo...

Mapeamento Completo do Conectoma: O Projeto que Quer Decifrar a Mente

Cientistas avançam no mapeamento de todas as conexões neurais de organismos, em busca de compreender consciência e memória...

Matéria Escura: Novas Evidências Empurram os Limites da Física Moderna

Experimentos subterrâneos detectam sinais que podem finalmente revelar a natureza do componente mais abundante do universo...

Dev Toolkit na Prática

SQL, ADVPL, Power BI, n8n e Protheus — dicas e exemplos reais para o seu dia a dia

Básico

Evite SELECT * em produção

Selecionar todas as colunas desperdiça banda e memória. Sempre especifique apenas as colunas necessárias.

SQL
-- Ruim
SELECT * FROM clientes

-- Bom
SELECT id, nome, email
FROM clientes
WHERE ativo = 1
Intermediário

Use CTE para queries complexas

Common Table Expressions (WITH) tornam queries longas muito mais legíveis e fáceis de manter.

SQL
WITH VendasMensais AS (
  SELECT vendedor_id,
         SUM(valor) AS total,
         MONTH(data_venda) AS mes
  FROM vendas
  GROUP BY vendedor_id, MONTH(data_venda)
)
SELECT v.nome, vm.total, vm.mes
FROM VendasMensais vm
JOIN vendedores v ON v.id = vm.vendedor_id
ORDER BY vm.total DESC
Avançado

Window Functions: RANK e ROW_NUMBER

Funções de janela permitem calcular rankings e numerações sem agrupamentos, mantendo todas as linhas.

SQL
SELECT nome, departamento, salario,
  RANK() OVER (
    PARTITION BY departamento
    ORDER BY salario DESC
  ) AS rank_depto,
  ROW_NUMBER() OVER (
    ORDER BY salario DESC
  ) AS rank_geral
FROM funcionarios
Básico

INDEX: acelere suas consultas

Crie índices nas colunas mais usadas em WHERE, JOIN e ORDER BY. Um índice bem posicionado pode reduzir tempo de query em 100x.

SQL
-- Criar índice simples
CREATE INDEX idx_cliente_email
ON clientes (email);

-- Índice composto (ordem importa!)
CREATE INDEX idx_pedido_data_status
ON pedidos (data_pedido, status);
Intermediário

CASE WHEN: lógica dentro do SELECT

Use CASE WHEN para criar colunas calculadas e categorizar dados diretamente na query, sem precisar de código na aplicação.

SQL
SELECT nome, salario,
  CASE
    WHEN salario < 2000  THEN 'Júnior'
    WHEN salario < 5000  THEN 'Pleno'
    WHEN salario < 10000 THEN 'Sênior'
    ELSE 'Especialista'
  END AS nivel
FROM funcionarios
Avançado

Detecte e elimine registros duplicados

Use ROW_NUMBER() para identificar e remover duplicatas de forma segura, sem apagar dados por acidente.

SQL
-- Identificar e remover duplicatas
WITH Duplicatas AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY email
      ORDER BY id
    ) AS rn
  FROM clientes
)
DELETE FROM Duplicatas WHERE rn > 1
Básico

JOINs: qual usar em cada situação

INNER JOIN retorna só registros com correspondência. LEFT JOIN retorna todos da esquerda mesmo sem correspondência. Use o tipo certo para evitar perder ou duplicar registros.

SQL
-- INNER: apenas pedidos com cliente
SELECT p.id, c.nome
FROM pedidos p
INNER JOIN clientes c ON c.id = p.cliente_id

-- LEFT: todos clientes, mesmo sem pedido
SELECT c.nome, COUNT(p.id) AS total
FROM clientes c
LEFT JOIN pedidos p ON p.cliente_id = c.id
GROUP BY c.nome
Intermediário

PIVOT: transforme linhas em colunas

PIVOT (SQL Server) ou CASE WHEN + GROUP BY transformam dados verticais em horizontais — útil para relatórios mensais, comparativos e dashboards.

SQL
SELECT vendedor,
  SUM(CASE WHEN mes = 1 THEN valor ELSE 0 END) AS Jan,
  SUM(CASE WHEN mes = 2 THEN valor ELSE 0 END) AS Fev,
  SUM(CASE WHEN mes = 3 THEN valor ELSE 0 END) AS Mar
FROM vendas
GROUP BY vendedor
Intermediário

STORED PROCEDURE com parâmetros

Procedures encapsulam lógica no banco, melhoram performance por reutilizar plano de execução e centralizam regras de negócio que envolvem múltiplas tabelas.

SQL
CREATE PROCEDURE sp_VendasPorPeriodo
  @dInicio DATE,
  @dFim    DATE,
  @cFilial VARCHAR(4) = '0101'
AS BEGIN
  SELECT v.id, c.nome, v.valor
  FROM vendas v
  INNER JOIN clientes c ON c.id = v.cliente_id
  WHERE v.data_venda BETWEEN @dInicio AND @dFim
  ORDER BY v.data_venda DESC
END
Avançado

EXPLAIN / Execution Plan: encontre gargalos

Use o plano de execução para identificar Table Scans caros, índices faltantes e operações desnecessárias antes de colocar uma query em produção.

SQL
-- Ver plano de execução estimado
SET SHOWPLAN_TEXT ON; GO
SELECT * FROM pedidos WHERE status = 'P'
GO; SET SHOWPLAN_TEXT OFF

-- Estatísticas de I/O e tempo
SET STATISTICS IO ON
SET STATISTICS TIME ON

-- Forçar uso de índice (hint)
SELECT * FROM pedidos WITH (INDEX(idx_status))
WHERE status = 'P'
Básico

Estrutura básica de uma função ADVPL

Todo programa ADVPL começa com uma declaração de função. Variáveis locais são declaradas com Local, e a função retorna valor com Return.

ADVPL
User Function MinhaFuncao()
  Local cNome  := Space(40)
  Local nValor := 0
  Local lAtivo := .T.

  cNome  := AllTrim(SA1->A1_NOME)
  nValor := SA1->A1_SALARIO

  If lAtivo
    MsgInfo('Cliente: ' + cNome)
  EndIf

Return NIL
Básico

Consulta SQL com TCQuery no ADVPL

Use TCQuery para executar SQL direto no banco via Protheus. Sempre feche o alias ao terminar para liberar recursos.

ADVPL
Local cQuery := ''
Local cAlias := 'QRY' + DToS(Date())

cQuery := 'SELECT A1_COD, A1_NOME, A1_CGC '
cQuery += 'FROM ' + RetSQLName('SA1') + ' SA1 '
cQuery += 'WHERE SA1.D_E_L_E_T_ = ' '
cQuery += 'AND SA1.A1_FILIAL = ''' + xFilial('SA1') + ''''

TCQuery cQuery New Alias cAlias

While !(cAlias)->(Eof())
  MsgInfo((cAlias)->A1_NOME)
  (cAlias)->(DbSkip())
EndDo

(cAlias)->(DbCloseArea())
Intermediário

RecLock: edite registros com segurança

Nunca altere campos diretamente sem travar o registro. Use RecLock para garantir integridade em ambientes multi-usuário.

ADVPL
DbSelectArea('SA1')
DbSetOrder(1)

If DbSeek(xFilial('SA1') + cCodCliente)
  If RecLock('SA1', .F.)
    SA1->A1_EMAIL := '[email protected]'
    SA1->A1_DDD   := '11'
    MsUnlock()
  Else
    MsgAlert('Registro em uso!')
  EndIf
EndIf
Intermediário

Trabalhando com Arrays no ADVPL

Arrays são amplamente usados no ADVPL para listas, parâmetros de tela e estruturas de dados. Conheça as funções essenciais.

ADVPL
Local aItens := {}

aAdd(aItens, {'001', 'Produto A', 100.00})
aAdd(aItens, {'002', 'Produto B', 250.50})

Local nI
For nI := 1 To Len(aItens)
  MsgInfo(aItens[nI][2])
Next nI

Local nPos := AScan(aItens, {|x| x[1] == '002'})
If nPos > 0
  MsgInfo('Encontrado: ' + aItens[nPos][2])
EndIf
Avançado

Gravação em lote com BeginTran / CommitTran

Para gravar múltiplos registros com segurança, use transações. Se qualquer etapa falhar, o RollBackTran desfaz tudo.

ADVPL
Local lOk := .T.

BeginTran()

If !GrvCabecalho()
  lOk := .F.
EndIf

If lOk .And. !GrvItens()
  lOk := .F.
EndIf

If lOk
  CommitTran()
  MsgInfo('Gravação concluída!')
Else
  RollBackTran()
  MsgAlert('Erro. Operação cancelada.')
EndIf
Avançado

Criando relatório com SetPrint no ADVPL

O SetPrint é a forma padrão de configurar impressão no Protheus. Combine com o TReport para relatórios modernos.

ADVPL
Local aRet  := {}
Local wnrel := 'MEUREL'

aRet := SetPrint(wnrel, wnrel,, 'Relatório de Clientes', .T.)

If Empty(aRet)
  Return
EndIf

SetDefault(aRet, wnrel)

If aRet[1] == 'V'
  Set Printer To
Else
  Set Printer To (aRet[2])
EndIf

Set Device To Printer
// ... corpo do relatório ...
Set Device To Screen
Básico

Funções de string essenciais

Manipulação de strings é rotina no ADVPL. Conheça as funções mais usadas para limpar, formatar e comparar textos nos campos do Protheus.

ADVPL
Local cTexto := '  Joao Silva  '

AllTrim(cTexto)            // 'Joao Silva'
Upper(cTexto)              // '  JOAO SILVA  '
SubStr(cTexto, 3, 4)       // 'Joao'
StrTran(cTexto,' ','-')    // '--Joao-Silva--'
At('Silva', cTexto)       // 8 (posicao)
PadR(AllTrim(cTexto),20)  // padded a direita
Intermediário

Enviar e-mail pelo Protheus (TMailMsg)

Use a classe TMailMsg para enviar e-mails com HTML, anexos e múltiplos destinatários diretamente do ADVPL via SMTP configurado no Protheus.

ADVPL
Local oMail := TMailMsg():New()
oMail:SetFrom('[email protected]','ERP')
oMail:AddTo('[email protected]')
oMail:SetSubject('Relatorio de Vendas')
oMail:SetBody('Total: R$ 15.000,00',.F.)
oMail:AddAttachment('
elatendas.pdf')
oMail:Send('smtp.empresa.com',587,'user','senha',.T.)
oMail:End()
Intermediário

Parâmetros SX6 com SuperGetMV

Os parâmetros do Protheus (SX6) armazenam configurações por empresa e filial. Use SuperGetMV para leitura com valor default e PutMV para gravação.

ADVPL
// Ler com default
Local cEmail := SuperGetMV('MV_EMAILENV',.F.,'[email protected]')
Local nLim   := SuperGetMV('MV_LIMDESC',.F.,10)

// Gravar
PutMV('MV_EMAILENV', '[email protected]')

// Checar existencia
If ExistMV('MV_LIMDESC')
  MsgInfo(cValToChar(nLim) + '%')
EndIf
Avançado

REST API com FWRest: consuma serviços externos

Use FWRest para consumir APIs REST externas direto do Protheus, com suporte a GET, POST, headers customizados e autenticação Bearer.

ADVPL
Local oRest := FWRest():New('https://api.empresa.com')
oRest:setPath('/v1/pedidos')
oRest:setChaveHeader('Authorization','Bearer '+cToken)
oRest:setChaveHeader('Content-Type','application/json')

If oRest:Post(cBody)
  Local oRet := JsonObject():New()
  oRet:fromJson(oRest:GetResult())
  MsgInfo(oRet['mensagem'])
Else
  MsgAlert('Erro: '+cValToChar(oRest:GetStatus()))
EndIf
oRest:End()
🔍
Tabela Módulo Descrição Chave Principal
SA1CadastroCadastro de ClientesA1_FILIAL + A1_COD + A1_LOJA
SA2CadastroCadastro de FornecedoresA2_FILIAL + A2_COD + A2_LOJA
SA3CadastroCadastro de VendedoresA3_FILIAL + A3_COD
SA4CadastroCadastro de TransportadorasA4_FILIAL + A4_COD
SA5CadastroProduto x Cliente (tabela de preços por cliente)A5_FILIAL + A5_CODPRO + A5_CLIENTE + A5_LOJA
SA6CadastroBancosA6_FILIAL + A6_COD
SA7CadastroRelação de Cobrança (formas de pagamento)A7_FILIAL + A7_COD
SABCadastroContas BancáriasAB_FILIAL + AB_BANCO + AB_AGENCIA + AB_CONTA
SB1EstoqueCadastro de ProdutosB1_FILIAL + B1_COD
SB2EstoqueSaldo em Estoque por ArmazémB2_FILIAL + B2_COD + B2_LOCAL
SB3EstoqueRastreabilidade (lotes/sublotes)B3_FILIAL + B3_COD + B3_LOCAL + B3_LOTECTL
SB4EstoqueGrupo de ProdutoB4_FILIAL + B4_GRUPO
SB5EstoqueComplemento do ProdutoB5_FILIAL + B5_COD
SB6EstoqueCurva ABC de ProdutosB6_FILIAL + B6_COD
SB7EstoqueSaldo de Lotes em EstoqueB7_FILIAL + B7_COD + B7_LOCAL + B7_LOTE
SB8EstoqueSaldo por Número de SérieB8_FILIAL + B8_COD + B8_LOCAL + B8_NUMSERI
SB9EstoqueEndereçamento de Estoque (WMS)B9_FILIAL + B9_COD + B9_LOCAL + B9_LOTECTL
SD3EstoqueMovimentos Internos de EstoqueD3_FILIAL + D3_COD + D3_DOC
SC1ComprasSolicitações de CompraC1_FILIAL + C1_NUM + C1_ITEM + C1_PRODUTO
SC2ComprasOrdens de CompraC2_FILIAL + C2_NUM + C2_ITEM + C2_PRODUTO
SC7ComprasPedidos de CompraC7_FILIAL + C7_NUM + C7_ITEM
SD1ComprasItens das Notas Fiscais de EntradaD1_FILIAL + D1_DOC + D1_SERIE + D1_FORNECE + D1_LOJA
SF1ComprasCabeçalho das Notas Fiscais de EntradaF1_FILIAL + F1_DOC + F1_SERIE + F1_FORNECE + F1_LOJA
SQBComprasCotações de CompraQB_FILIAL + QB_NUM + QB_FORNECE
SC5VendasCabeçalho dos Pedidos de VendaC5_FILIAL + C5_NUM
SC6VendasItens dos Pedidos de VendaC6_FILIAL + C6_NUM + C6_ITEM
SD2VendasItens das Notas Fiscais de SaídaD2_FILIAL + D2_DOC + D2_SERIE + D2_CLIENTE + D2_LOJA
SF2VendasCabeçalho das Notas Fiscais de SaídaF2_FILIAL + F2_DOC + F2_SERIE + F2_CLIENTE + F2_LOJA
SCJVendasTabela de Preços de VendaCJ_FILIAL + CJ_TABELA + CJ_PRODUTO
SDAVendasDevoluções de VendaDA_FILIAL + DA_DOC + DA_SERIE
SE1FinanceiroContas a Receber (títulos)E1_FILIAL + E1_PREFIXO + E1_NUM + E1_PARCELA + E1_TIPO + E1_CLIENTE + E1_LOJA
SE2FinanceiroContas a Pagar (títulos)E2_FILIAL + E2_PREFIXO + E2_NUM + E2_PARCELA + E2_TIPO + E2_FORNECE + E2_LOJA
SE5FinanceiroMovimentação Bancária (extrato)E5_FILIAL + E5_BANCO + E5_AGENCIA + E5_CONTA + E5_PREFIXO + E5_NUM
SEAFinanceiroAdiantamentos de ClientesEA_FILIAL + EA_CLIENTE + EA_LOJA
SEBFinanceiroAdiantamentos de FornecedoresEB_FILIAL + EB_FORNECE + EB_LOJA
SEFFinanceiroSaldos BancáriosEF_FILIAL + EF_BANCO + EF_AGENCIA + EF_CONTA
SEGFinanceiroNaturezas FinanceirasEG_FILIAL + EG_CODIGO
CT1ContábilPlano de Contas ContábilCT1_FILIAL + CT1_CONTA
CT2ContábilLançamentos Contábeis (partidas)CT2_FILIAL + CT2_LOTE + CT2_SEQUEN
CT5ContábilCentro de CustoCT5_FILIAL + CT5_CLVL
CTDContábilSaldos ContábeisCTD_FILIAL + CTD_CONTA + CTD_CLVL + CTD_MES + CTD_ANO
CTGContábilGrupos de Lançamento ContábilCTG_FILIAL + CTG_GRPCTA
SF3FiscalLivro Fiscal (SPED / registros fiscais)F3_FILIAL + F3_DOC + F3_SERIE + F3_FORNECE
SFBFiscalTributações por UF (ICMS)FB_FILIAL + FB_EST + FB_TIPO + FB_TRIB
SFCFiscalTabela de IPIFC_FILIAL + FC_CODIGO
SFDFiscalClassificações Fiscais (NCM / TIPI)FD_FILIAL + FD_CODIGO
SFPFiscalApuração de ICMS/IPIFP_FILIAL + FP_ESTAB + FP_MESREF
SFFFiscalOperações Fiscais (CFOP)FF_FILIAL + FF_CODIGO
SC4ProduçãoOrdens de Produção (cabeçalho)C4_FILIAL + C4_NUM
SG1ProduçãoEstrutura do Produto (BOM)G1_FILIAL + G1_COD + G1_COMP + G1_TRT + G1_REVINI
SG2ProduçãoCentro de Trabalho (Recursos)G2_FILIAL + G2_COD
SH1ProduçãoRoteiros de Fabricação (cabeçalho)H1_FILIAL + H1_COD + H1_ROTEIRO
SH2ProduçãoRoteiros de Fabricação (operações)H2_FILIAL + H2_ROTEIRO + H2_OPERAC
SH6ProduçãoApontamento de ProduçãoH6_FILIAL + H6_OP + H6_ITEM
SRARHCadastro de FuncionáriosRA_FILIAL + RA_MAT
SRBRHHistórico de Cargos e SaláriosRB_FILIAL + RB_MAT + RB_DATAALT
SRCRHVerba / Evento da Folha de PagamentoRC_FILIAL + RC_MAT + RC_CODVER
SRDRHDependentes do FuncionárioRD_FILIAL + RD_MAT + RD_CODEP
SRHRHHistórico de FrequênciaRH_FILIAL + RH_MAT + RH_DATA
SRJRHCargos / FunçõesRJ_FILIAL + RJ_CARGO
SRVRHVerbas / Eventos da Folha (tabela mestre)RV_FILIAL + RV_COD
SX5CadastroTabelas Genéricas do Sistema (domínios)X5_FILIAL + X5_TABELA + X5_CHAVE
SX3CadastroDicionário de Dados dos Campos (SXS)X3_ARQUIVO + X3_CAMPO
SM0CadastroCadastro de Empresas / FiliaisM0_FILIAL + M0_CODFIL
SM4CadastroMoedas do SistemaM4_MOEDA
SNFCadastroSéries de Notas FiscaisNF_FILIAL + NF_SERIE + NF_TIPO

⚠ Todas as tabelas possuem os campos padrão: D_E_L_E_T_ (exclusão lógica), R_E_C_N_O_ (número do registro) e R_E_C_D_E_L_. Sempre filtre por D_E_L_E_T_ = ' ' em queries SQL.

Básico

SA1 — Clientes: campos essenciais

Tabela mais consultada do Protheus. Campos-chave para joins: A1_FILIAL + A1_COD + A1_LOJA formam a chave única do cliente.

SQL
SELECT
  A1_COD, A1_LOJA, A1_NOME,
  A1_CGC AS CNPJ,
  A1_EMAIL, A1_TEL,
  A1_END, A1_MUN, A1_EST
FROM SA1010
WHERE D_E_L_E_T_ = ' '
  AND A1_FILIAL = '0101'
ORDER BY A1_NOME
Básico

SC5/SC6 — Pedidos e Itens de Venda

SC5 é o cabeçalho do pedido de venda e SC6 os itens. O JOIN usa C5_NUM = C6_NUM + filial. Relacione com SA1 (cliente) e SB1 (produto).

SQL
SELECT
  C5.C5_NUM, C5.C5_EMISSAO,
  SA1.A1_NOME AS Cliente,
  SB1.B1_DESC AS Produto,
  C6.C6_QTDVEN * C6.C6_PRCVEN AS Total
FROM SC5010 C5
INNER JOIN SC6010 C6
  ON C6.C6_NUM = C5.C5_NUM
INNER JOIN SA1010 SA1
  ON SA1.A1_COD = C5.C5_CLIENTE
INNER JOIN SB1010 SB1
  ON SB1.B1_COD = C6.C6_PRODUTO
WHERE C5.D_E_L_E_T_ = ' '
  AND C5.C5_FILIAL = '0101'
Intermediário

SE1/SE2 — Contas a Receber e a Pagar

SE1 é contas a receber, SE2 contas a pagar. E1_SALDO > 0 indica título em aberto. Use DATEDIFF para calcular dias de atraso.

SQL
SELECT
  E1_NUM, SA1.A1_NOME AS Cliente,
  E1_VENCREA, E1_VALOR, E1_SALDO,
  DATEDIFF(DAY,
    CONVERT(DATE,E1_VENCREA,112),
    GETDATE()) AS DiasAtraso
FROM SE1010 E1
LEFT JOIN SA1010 SA1
  ON SA1.A1_COD = E1_CLIENTE
WHERE E1.D_E_L_E_T_ = ' '
  AND E1_SALDO > 0
Avançado

SF3 — Livro Fiscal: entradas e saídas

SF3 registra todos os documentos fiscais. Essencial para apuração de impostos, auditoria e conciliação contábil. F3_TIPO distingue entrada (E) de saída (S).

SQL
SELECT
  F3_DOC, F3_SERIE, F3_EMISSAO,
  CASE F3_TIPO
    WHEN 'E' THEN 'Entrada'
    WHEN 'S' THEN 'Saída'
  END AS Tipo,
  F3_VALBRUT, F3_VALIPI,
  F3_VALICM, F3_VALPIS, F3_VALCOF
FROM SF3010
WHERE D_E_L_E_T_ = ' '
  AND F3_EMISSAO BETWEEN
    '20250101' AND '20251231'
Básico

SA2 — Fornecedores: campos essenciais

Tabela de fornecedores. Chave composta por A2_FILIAL + A2_COD + A2_LOJA. Campos fiscais como A2_CGC (CNPJ), A2_INSCEST (IE) e A2_PAIS são críticos para NF de entrada e apuração fiscal.

SQL
SELECT
  A2_COD, A2_LOJA, A2_NOME,
  A2_CGC    AS CNPJ,
  A2_INSCEST AS IE,
  A2_END, A2_MUN, A2_EST,
  A2_EMAIL, A2_TEL,
  A2_TIPO  -- F=Físico J=Jurídico
FROM SA2010
WHERE D_E_L_E_T_ = ' '
  AND A2_FILIAL = '0101'
ORDER BY A2_NOME
Básico

SB1 / SB2 — Produtos e Saldos em Estoque

SB1 é o cadastro de produtos (descrição, unidade, NCM, grupo). SB2 guarda o saldo físico e financeiro por filial e armazém. Para saldo atual sempre use SB2, nunca SB1.

SQL
SELECT
  SB1.B1_COD, SB1.B1_DESC, SB1.B1_UM,
  SB1.B1_POSIPI AS NCM,
  SB2.B2_LOCAL  AS Armazem,
  SB2.B2_QATU   AS SaldoFisico,
  SB2.B2_CM1    AS CustoMedio,
  SB2.B2_QATU * SB2.B2_CM1 AS Valor
FROM SB1010 SB1
INNER JOIN SB2010 SB2
  ON SB2.B2_COD = SB1.B1_COD
WHERE SB1.D_E_L_E_T_ = ' '
  AND SB2.B2_QATU > 0
Básico

SC1 — Pedidos de Compra

SC1 armazena os pedidos de compra (solicitações). Campo C1_NUM identifica o pedido, C1_PRODUTO o item e C1_FORNECE o fornecedor. C1_DATPRF é a data de entrega prevista.

SQL
SELECT
  C1.C1_NUM, C1.C1_PRODUTO,
  SB1.B1_DESC AS Produto,
  C1.C1_QUANT - C1.C1_QUJE AS Saldo,
  C1.C1_DATPRF AS DataPrevista,
  SA2.A2_NOME  AS Fornecedor
FROM SC1010 C1
LEFT JOIN SB1010 SB1 ON SB1.B1_COD = C1.C1_PRODUTO
LEFT JOIN SA2010 SA2 ON SA2.A2_COD = C1.C1_FORNECE
WHERE C1.D_E_L_E_T_ = ' '
  AND C1.C1_QUANT > C1.C1_QUJE
Intermediário

SF2 / SD2 — NF de Saída e seus Itens

SF2 é o cabeçalho da Nota Fiscal de saída emitida pelo Protheus. SD2 contém os itens. O JOIN é por F2_DOC + F2_SERIE + F2_CLIENTE. Campos fiscais como D2_TES, D2_CF e D2_BASICO são essenciais para apuração.

SQL
SELECT
  F2.F2_DOC, F2.F2_SERIE, F2.F2_EMISSAO,
  SA1.A1_NOME AS Cliente,
  D2.D2_CF    AS CFOP,
  D2.D2_QUANT, D2.D2_TOTAL,
  D2.D2_BASICO AS BaseICMS,
  D2.D2_VALICM, D2.D2_VALIPI
FROM SF2010 F2
INNER JOIN SD2010 D2
  ON D2.D2_DOC = F2.F2_DOC
  AND D2.D2_SERIE = F2.F2_SERIE
WHERE F2.D_E_L_E_T_ = ' '
  AND F2.F2_FILIAL = '0101'
Intermediário

SD1 — Itens de NF de Entrada (Compras)

SD1 contém os itens das notas fiscais de entrada (compras). O cabeçalho fica na SF1. D1_DOC + D1_SERIE + D1_FORNECE formam o vínculo com o documento. D1_PEDIDO liga ao pedido de compra (SC7).

SQL
SELECT
  SF1.F1_DOC, SF1.F1_EMISSAO,
  SA2.A2_NOME  AS Fornecedor,
  D1.D1_COD, D1.D1_CF AS CFOP,
  D1.D1_QUANT, D1.D1_TOTAL,
  D1.D1_BASEIA AS BaseICMS,
  D1.D1_PEDIDO AS PedidoCompra
FROM SF1010 SF1
INNER JOIN SD1010 D1
  ON D1.D1_DOC = SF1.F1_DOC
  AND D1.D1_SERIE = SF1.F1_SERIE
WHERE SF1.D_E_L_E_T_ = ' '
Intermediário

SRA / SRB — Funcionários e Departamentos (RH)

SRA é o cadastro de funcionários no módulo RH/Folha. SRB contém os departamentos. Campos como RA_MAT (matrícula), RA_NOME, RA_SALARIO e RA_CODFUNC são os mais utilizados em relatórios gerenciais de RH.

SQL
SELECT
  SRA.RA_MAT    AS Matricula,
  SRA.RA_NOME   AS Funcionario,
  SRB.RB_DESC   AS Departamento,
  SRC.RC_DESC   AS Cargo,
  SRA.RA_SALARIO AS Salario,
  SRA.RA_ADMISSA AS Admissao
FROM SRA010 SRA
LEFT JOIN SRB010 SRB ON SRB.RB_DEPTO = SRA.RA_DEPTO
LEFT JOIN SRC010 SRC ON SRC.RC_CARGO = SRA.RA_CARGO
WHERE SRA.RA_SITFOLH = '1'
Avançado

SX5 — Tabelas de Domínio (Genéricas)

SX5 centraliza todas as tabelas de domínio do Protheus: UFs, países, grupos de produto, tipos de entrada/saída, naturezas de operação etc. X5_TABELA identifica qual tabela e X5_CHAVE + X5_DESCRI são chave/valor.

SQL
-- Tabelas de domínio do Protheus
SELECT X5_CHAVE, X5_DESCRI
FROM SX5010
WHERE D_E_L_E_T_ = ' '
  AND X5_TABELA = '12' -- UFs

-- No ADVPL:
-- Posicione('SX5', 1,
--   xFilial('SX5')+'12'+cUF,
--   'X5_DESCRI')
Avançado

SM0 — Empresas e Filiais cadastradas

SM0 contém o cadastro de todas as empresas e filiais do ambiente Protheus. Essencial para relatórios multi-empresa, validação de filial ativa e integração entre módulos em ambiente multi-filial.

SQL
-- Empresas e filiais do ambiente
SELECT
  M0_CODIGO  AS Empresa,
  M0_CODFIL  AS Filial,
  M0_NOME    AS NomeEmpresa,
  M0_CGC     AS CNPJ,
  M0_ESTADO  AS UF
FROM SM0010
WHERE D_E_L_E_T_ = ' '
ORDER BY M0_CODIGO, M0_CODFIL
Básico

Use medidas em vez de colunas calculadas

Colunas calculadas ficam salvas no modelo e aumentam o tamanho do arquivo. Medidas são calculadas em tempo de execução e são muito mais eficientes para agregações.

DAX
-- ❌ Evite: coluna calculada
Lucro = Vendas[Receita] - Vendas[Custo]

-- ✅ Prefira: medida
Lucro Total =
  SUM(Vendas[Receita]) - SUM(Vendas[Custo])
Básico

CALCULATE: o coração do DAX

CALCULATE permite modificar o contexto de filtro de uma medida. É a função mais poderosa do DAX — dominar ela é essencial para qualquer análise avançada.

DAX
-- Vendas apenas da região Sul
Vendas Sul =
CALCULATE(
    SUM(Vendas[Valor]),
    Regioes[Regiao] = "Sul"
)

-- Vendas do ano anterior
Vendas Ano Anterior =
CALCULATE(
    SUM(Vendas[Valor]),
    SAMEPERIODLASTYEAR(Calendario[Data])
)
Intermediário

Tabela calendário é obrigatória

Para usar funções de inteligência de tempo (YTD, MTD, ano anterior) você precisa de uma tabela calendário marcada como "tabela de data" com uma linha para cada dia.

DAX
Calendario =
ADDCOLUMNS(
    CALENDAR(DATE(2020,1,1), DATE(2030,12,31)),
    "Ano",        YEAR([Date]),
    "Mes",        MONTH([Date]),
    "NomeMes",   FORMAT([Date], "MMMM"),
    "Trimestre", "T" & ROUNDUP(MONTH([Date])/3,0),
    "DiaSemana", WEEKDAY([Date], 2)
)
Intermediário

YTD, QTD e MTD prontos

Use as funções de inteligência temporal nativas do DAX para acumular valores no ano, trimestre ou mês. Exigem tabela calendário corretamente configurada.

DAX
Vendas YTD =
TOTALYTD(SUM(Vendas[Valor]), Calendario[Data])

Vendas MTD =
TOTALMTD(SUM(Vendas[Valor]), Calendario[Data])

Crescimento % =
DIVIDE(
    [Vendas YTD] - [Vendas Ano Anterior],
    [Vendas Ano Anterior],
    0
)
Avançado

RANKX para ranking dinâmico

RANKX cria rankings que se atualizam automaticamente conforme os filtros do relatório, sem precisar ordenar tabelas manualmente.

DAX
Ranking Vendedores =
RANKX(
    ALL(Vendedores[Nome]),
    [Vendas Total],
    ,
    DESC,
    DENSE
)

-- Filtrar top 5 em visuals:
Top 5 =
IF([Ranking Vendedores] <= 5, [Vendas Total])
Avançado

Otimize com agregações e modo Direct Query

Para datasets grandes, defina tabelas de agregação pré-calculadas. O Power BI usa automaticamente a agregação quando possível, caindo para o detalhe só quando necessário.

Power Query (M)
// Tabela de agregação por mês
let
    Fonte = Vendas,
    Agrupado = Table.Group(
        Fonte,
        {"AnoMes", "Regiao"},
        {
            {"TotalVendas", each List.Sum([Valor]), type number},
            {"QtdPedidos",  each Table.RowCount(_), type number}
        }
    )
in
    Agrupado
Básico

RELATED e RELATEDTABLE

RELATED busca um valor da tabela relacionada (lado 1). RELATEDTABLE retorna a tabela filtrada (lado N). Essenciais em modelos estrela.

DAX
-- Busca campo da tabela pai
Segmento = RELATED(Clientes[Segmento])

-- Conta linhas relacionadas
Total Pedidos =
COUNTROWS(RELATEDTABLE(Pedidos))

-- Com filtro:
Concluidos =
CALCULATE(
    COUNTROWS(RELATEDTABLE(Pedidos)),
    Pedidos[Status] = "Concluido"
)
Intermediário

SWITCH: substitua IFs aninhados

SWITCH substitui múltiplos IFs e é muito mais legível. Use SWITCH(TRUE()) para condições por faixa — equivalente ao CASE WHEN do SQL.

DAX
Classificacao =
SWITCH(TRUE(),
    [Vendas Total] >= 100000, "Diamante",
    [Vendas Total] >=  50000, "Ouro",
    [Vendas Total] >=  20000, "Prata",
    [Vendas Total] >=   5000, "Bronze",
    "Iniciante"
)

Status Desc =
SWITCH(Pedidos[Status],
    "A", "Aberto",
    "F", "Faturado",
    "C", "Cancelado",
    "Desconhecido"
)
Intermediário

Parâmetros What-If para simulações

Tabelas What-If criam sliders para simular cenários (ex: % desconto, meta de crescimento) sem alterar os dados reais do modelo.

DAX
-- Medida do What-If:
Desconto Valor =
    'Desconto'[Desconto] / 100

-- Usar o parametro:
Receita Simulada =
SUM(Vendas[Valor]) * (1 - [Desconto Valor])

Lucro Simulado =
[Receita Simulada] - SUM(Vendas[Custo])
Avançado

Power Query M: transforme na origem

Limpeza de dados deve ser feita no Power Query, não em DAX. Renomeie colunas, ajuste tipos e filtre registros antes de carregar no modelo.

Power Query (M)
let
    Fonte   = Sql.Database("srv","banco"),
    Tabela  = Fonte{[Item="Vendas"]}[Data],
    Filtrado = Table.SelectRows(Tabela,
        each [Status] = "A"),
    Renomeado = Table.RenameColumns(Filtrado,{
        {"C5_NUM",     "NrPedido"},
        {"C5_EMISSAO", "DataEmissao"}
    }),
    Tipado = Table.TransformColumnTypes(
        Renomeado,{{"DataEmissao",type date}}
    )
in Tipado
Básico

Estrutura de um workflow n8n

Todo workflow n8n tem um nó de gatilho (Trigger) que inicia a execução, seguido de nós de ação conectados. Dados fluem como JSON de nó em nó através de "items".

JSON (estrutura de item)
// Cada nó recebe e passa arrays de items
[
  {
    "json": {
      "id": 1,
      "nome": "João Silva",
      "email": "[email protected]"
    }
  }
]
Básico

Expressões: acesse dados com $json

Use expressões entre {{ }} para acessar dados do nó anterior. $json acessa o item atual, $('NomeDoNó').item.json acessa dados de um nó específico.

n8n Expression
// Item atual
{{ $json.nome }}
{{ $json.email }}

// Nó específico pelo nome
{{ $('HTTP Request').item.json.status }}

// Operações na expressão
{{ $json.preco * $json.quantidade }}
{{ new Date($json.data).toLocaleDateString('pt-BR') }}
Intermediário

Nó Code: JavaScript para lógica customizada

O nó Code permite escrever JavaScript puro para transformar dados de forma avançada. Ideal quando os nós nativos não cobrem o caso de uso.

JavaScript (nó Code)
// Processar e transformar items
const resultado = items.map(item => {
  const d = item.json;
  return {
    json: {
      nome:       d.nome.trim(),
      email:      d.email.toLowerCase(),
      valor:      `R$ ${d.valor.toFixed(2)}`,
      data:       new Date(d.data)
                    .toLocaleDateString('pt-BR'),
      ativo:      d.status === 'A'
    }
  };
});
return resultado;
Intermediário

Webhook: receba dados externos

Use o nó Webhook como trigger para que sistemas externos (ERPs, e-commerce, formulários) disparem seu workflow via HTTP POST. Ideal para integrações em tempo real.

Exemplo de payload recebido
// Payload recebido no Webhook
{
  "evento":  "pedido_criado",
  "pedido": {
    "id":      "PED-001",
    "cliente": "João Silva",
    "valor":   1500.00
  }
}

// Acessar no próximo nó:
{{ $json.body.pedido.cliente }}
{{ $json.body.pedido.valor }}
Avançado

Split in Batches para grandes volumes

Ao processar listas grandes (ex: enviar e-mail para 1000 contatos), use o nó "Split in Batches" para processar em grupos e evitar timeout ou limite de APIs.

Fluxo recomendado
// Fluxo para grandes volumes:
//
// [Buscar dados] → lista completa
//      ↓
// [Split in Batches] → tamanho: 50
//      ↓
// [Processar cada item]
//      ↓
// [Wait] → 1s entre batches

// Verificar último batch (nó Code):
if ($input.context.noItemsLeft) {
  // todos processados!
}
Avançado

Error Workflow: trate falhas globalmente

Configure um "Error Workflow" nas configurações do n8n para capturar falhas de qualquer workflow automaticamente. Ideal para enviar alertas no Slack, Teams ou e-mail quando algo quebrar.

JavaScript (Error Workflow)
// Dados no Error Workflow:
// $json.workflow.name   → nome do workflow
// $json.error.message   → mensagem do erro
// $json.execution.url   → link no n8n

// Montar alerta para Slack:
const msg = [
  `❌ *Erro:* ${$json.workflow.name}`,
  `📋 ${$json.error.message}`,
  `🔗 ${$json.execution.url}`
].join('
');

return [{ json: { text: msg } }];
Básico

IF Node: condicionais no fluxo

O nó IF divide o fluxo em dois caminhos: "true" e "false". Use expressões para comparar valores e rotear os dados para o nó correto.

n8n Expression
// Condições no nó IF:

// Campo existe e não está vazio
{{ $json.email !== '' && $json.email !== undefined }}

// Comparar número
{{ $json.valor > 1000 }}

// Array tem itens
{{ $json.itens.length > 0 }}

// Múltiplas condições
{{ $json.tipo === 'PJ' && $json.cnpj !== '' }}
Intermediário

HTTP Request: consuma qualquer API

O nó HTTP Request é o canivete suíço do n8n. Com ele você consome qualquer API REST, envia dados, autentica com Bearer Token ou API Key e trata a resposta.

Configuração HTTP Request
// URL com variável de ambiente:
https://api.empresa.com/v1/pedidos

// Header de autenticação:
Authorization: Bearer {{ $env.API_TOKEN }}

// Body dinâmico:
{
  "cliente": "{{ $json.codCliente }}",
  "itens": {{ JSON.stringify($json.itens) }},
  "total": {{ $json.valorTotal }}
}
Intermediário

Schedule Trigger: automatize por horário

Use o Schedule Trigger para executar workflows automaticamente em horários fixos. Suporta expressões cron para agendamentos avançados como "segunda às 8h" ou "todo dia 1 do mês".

Cron expressions
// Todo dia às 8h
0 8 * * *

// Seg–Sex às 7h30
30 7 * * 1-5

// Dia 1 de cada mês às 6h
0 6 1 * *

// A cada 30min em horário comercial
*/30 8-18 * * 1-5

// Toda segunda às 9h
0 9 * * 1
Avançado

Merge Node: combine dados de branches paralelos

O nó Merge une dados de dois ramos do workflow. No modo "Combine by Field" faz um JOIN entre os dois fluxos por uma chave comum — como juntar dados de duas APIs diferentes pelo ID do registro.

JavaScript (pós-Merge)
// Após Merge (Combine by Field: id)
const merged = items.map(item => {
  const d = item.json;
  return {
    json: {
      id:          d.id,
      // Do CRM:
      nomeCliente: d.nome,
      // Do ERP:
      saldoERP:    d.saldo,
      // Calculado:
      utilizacao:
        ((d.saldo / d.limite) * 100)
          .toFixed(1) + '%'
    }
  };
});
return merged;
Básico

O que muda com a Reforma Tributária

A Reforma (EC 132/2023 + PLP 68/2024) extingue PIS, COFINS, ICMS, ISS e IPI, substituindo por CBS (federal), IBS (estados/municípios) e IS (seletivo). Transição entre 2026 e 2032.

Resumo
Extintos:
  PIS+COFINS → CBS (federal)
  ICMS+ISS   → IBS (est.+mun.)
  IPI        → IS (seletivo)

Cronograma:
  2026 → testes 0,1%
  2027 → CBS plena
  2029-2032 → IBS gradual
  2033 → regime pleno
Básico

CBS vs IBS — diferenças essenciais

CBS é federal (substitui PIS+COFINS, alíquota ~8,8%). IBS é subnacional (substitui ICMS+ISS, alíquota ~17,7%). Ambos têm não-cumulatividade plena e mesmo mecanismo de crédito.

Comparativo
          CBS          IBS
Esfera    Federal      Est.+Mun.
Substitui PIS+COFINS   ICMS+ISS
Alíquota  ~8,8%        ~17,7%
Crédito   Pleno        Pleno
Início    2027         2029
Básico

Nota Fiscal na transição

Durante a transição a NF-e continuará com campos atuais. A SEFAZ publicará versão 4.x com campos CBS/IBS/IS. No Protheus, aguardar pacotes TOTVS Legislação com novos campos em SF2/SD2.

NF-e / Protheus
NF-e 4.x (previsto):
  <CBS> alíquota + valor
  <IBS> alíquota + valor
  <IS>  alíquota + valor

Protheus — aguardar TOTVS:
  MV_CBSALIQ, MV_IBSALIQ
  SF2/SD2 → novos campos
  Pacote TOTVS Legislação
Intermediário

Split payment — pagamento fracionado

No split payment o imposto é recolhido automaticamente no ato do pagamento pelo banco/adquirente. O vendedor recebe o valor líquido. Acaba o "float tributário". Impacto direto no fluxo de caixa.

Fluxo
Hoje:
  Venda R$ 1.000 → recebe R$ 1.000
  Imposto: recolhe mês seguinte

Split Payment (2027+):
  Venda R$ 1.000
  Banco → R$ 270 ao fisco
  Empresa recebe → R$ 730

Fim do "float tributário"
Intermediário

Crédito amplo de CBS e IBS

Crédito pleno e imediato sobre todas as aquisições usadas na atividade — insumos, serviços, energia, ativo imobilizado, aluguel. Fim das restrições atuais do PIS/COFINS não-cumulativo.

Créditos
Geram crédito:
  Mercadorias para revenda
  Insumos, energia, fretes
  Servicos contratados
  Aluguel (atividade)
  Ativo imobilizado

Sem crédito:
  Simples Nacional / MEI
  Uso pessoal
Intermediário

Imposto Seletivo (IS) — produtos afetados

O IS incide sobre bens e serviços prejudiciais à saúde ou ao meio ambiente. Não gera crédito CBS/IBS para o comprador. Incide antes do CBS/IBS (integra a base de cálculo deles).

Produtos com IS
Sujeitos ao IS:
  Tabaco, álcool, refrigerantes
  Veículos (exceto elétricos)
  Agrotóxicos, armas
  Minérios

Regras:
  IS não gera crédito
  Base CBS/IBS inclui IS
Intermediário

Cashback para baixa renda

Famílias do CadÚnico recebem devolução de parte do CBS/IBS pago em compras do dia a dia. O CPF na NF-e é obrigatório para que o fisco rastreie as compras e calcule o benefício automaticamente.

Mecanismo
Quem recebe:
  CadÚnico + CPF na NF-e

Devolução:
  CBS: 20%  IBS: 20%
  Cesta básica: 100%

Para o ERP:
  CPF na NF-e é obrigatório
Avançado

Regimes diferenciados — Simples, Imune, MEI

Simples Nacional recolhe CBS/IBS dentro do DAS (alíquota reduzida) mas quem compra recebe apenas crédito presumido. Entidades imunes e MEI não recolhem e não geram crédito para o comprador.

Regimes
Simples Nacional:
  CBS/IBS no DAS
  Comprador: crédito presumido

Imunes + MEI:
  Não recolhem → sem crédito

Lucro Presumido:
  Regime geral → crédito normal
Avançado

Checklist — o que preparar no Protheus agora

Ainda estamos no período pré-transição (2026 é o ano-teste). Mas há ações concretas que podem ser feitas já para minimizar o impacto quando os pacotes TOTVS chegarem.

Checklist
Fazer AGORA:
  1. Atualizar pacotes TOTVS
  2. Revisar NCM (SB1.B1_POSIPI)
  3. CPF/CNPJ em todas as NF-e
  4. Revisar CFOP por operação
  5. Documentar pontos de entrada

Aguardar TOTVS 2026+:
  NF-e 4.x, MV_CBS*, MV_IBS*
  Split Payment, SIGAFIS novo
Básico

Arquitetura do ambiente Protheus

O Protheus tem arquitetura 3 camadas: SmartClient/Web, Application Server (AppServer) e banco de dados. O DBAccess faz a ponte entre AppServer e banco (SQL Server, Oracle ou Progress).

Arquitetura
[SmartClient / WebApp]
      TCP/IP
[TOTVS AppServer]
      DBAccess
[DBAccess Server]
      ODBC / driver
[SQL Server / Oracle]

Portas: AppServer 1234
        DBAccess  7890
        REST      8080
Básico

Estrutura de pastas do Protheus

Conhecer a estrutura de pastas é essencial para instalar RPOs, incluir fontes customizados, configurar o appserver.ini e separar ambientes de produção e desenvolvimento.

Pastas
Protheus  Apo    tttm120.rpo   (RPO padrão)
    custom.rpo    (customizações)
  Bin\AppServer  Bin\SmartClient  Protheus_Data    Systemload\   (fontes .prw)
  appserver.ini
  dbaccess.ini
Básico

appserver.ini — configurações essenciais

O appserver.ini controla porta, RPO, empresa, licenças e ambientes. Erros aqui impedem o servidor de subir. Mantenha sempre backup antes de qualquer alteração.

appserver.ini
[TCP]
Port=1234

[ENVIRONMENT]
sourcepath=...\Systemload
RootPath=...\Protheus_Data
RpoDb=Top
RpoVersion=120

[TOP]
Server=localhost
Port=7890
Database=MSSQL

; RpoCustom=...\custom.rpo
Básico

IDE ADVPL — TDS no VS Code

O TDS (TOTVS Developer Studio) para VS Code é a IDE oficial e gratuita para ADVPL/TLPP. Substitui o TDS Eclipse. Permite compilar, depurar e navegar nos fontes diretamente do editor.

Setup TDS
1. VS Code + extensão TOTVS
2. Add Server:
   Host: IP do AppServer
   Porta: 1234
   Ambiente: SEU_AMBIENTE
3. Compilar:
   Ctrl+F9      → arquivo
   Ctrl+Shift+F9 → pasta
4. Debug: F5 → Launch ADVPL
Intermediário

RPO — compilação e boas práticas

RPO (Repository Object) é o arquivo binário com todos os fontes compilados. Separe customizações em RPO próprio (custom.rpo). Nunca compile direto no RPO padrão da TOTVS.

ADVPL
// RPO separado:
// RpoCustom=...\custom.rpo

// Prefixo: Z + módulo + seq
// ZFIN001.PRW, ZVEN002.TLPP

/*/{Protheus.doc}
Funcao    : ZFIN001
Descricao : Relatorio X
Autor     : Dev
Data      : 01/01/2026
/{*/

// Versionar com Git
Intermediário

Ambientes DEV, HML e PRD separados

Nunca desenvolva em produção. Configure DEV, HML e PRD como environments distintos no mesmo appserver.ini, cada um apontando para um banco diferente.

appserver.ini
; Um AppServer → 3 ambientes

[DESENV]
RootPath=...\Protheus_Data_DEV

[HOMOLOG]
RootPath=...\Protheus_Data_HML

[PRODUCAO]
RootPath=...\Protheus_Data_PRD

; SmartClient → escolher no login
Intermediário

Depuração ADVPL — técnicas práticas

O TDS permite depurar em tempo real com breakpoints condicionais. Para ambientes sem debug disponível, use log em arquivo com MemoWrite() ou ConOut() para saída no console do AppServer.

ADVPL
// Breakpoint condicional TDS:
// Right-click → Conditional
// Ex: nValor > 1000

// Log em arquivo:
MemoWrite(GetTempPath()+'debug.log',
  DToS(Date())+' '+cValToChar(nValor),
  .T.)

// Console AppServer:
ConOut('nValor: '+cValToChar(nValor))
Avançado

REST API no AppServer com TLPP

Configure o HTTP no appserver.ini e use anotações @Get/@Post no TLPP para expor endpoints REST nativos. Suporte a JWT e TOTVS RAC para autenticação.

appserver.ini + TLPP
; appserver.ini:
[HTTPSERVER]
Enable=1
Ports=8080

; TLPP:
#include 'tlpp-rest.th'

@Get('/api/pedidos')
Function getPedidos() As Object
  Local oBody := JsonObject():New()
  oBody['status'] := 'ok'
  oRest:getResponse():setStatus(200)
Return oRest:getResponse()
Avançado

Git + TDS-CLI — controle de versão

Versione fontes ADVPL com Git. Configure .gitignore para excluir binários. Use TDS-CLI para compilação automática em pipelines CI/CD, eliminando dependência de abrir o VS Code manualmente.

.gitignore + TDS-CLI
# .gitignore ADVPL:
*.rpo *.err *.ind
*.dbf *.log

# Versionar:
# *.prw *.tlpp *.ch *.th

# TDS-CLI (pipeline CI/CD):
tdscli compile   --server=localhost --port=1234   --env=DESENV   --program=ZFIN001.PRW   --rpoCustom=custom.rpo

Pesquisas em Andamento

Investigações ativas sobre tecnologia, dados e automação — acompanhe o progresso em tempo real

IA & Dados Em andamento

LLMs aplicados à análise de contratos jurídicos em português

Investigação sobre o desempenho de modelos de linguagem (GPT-4o, Claude, Gemini) na extração de cláusulas e identificação de riscos em contratos brasileiros, comparando acurácia e custo por token.

LLM NLP Python RAG
Progresso 68%
Revisão bibliográfica Coleta de dados Experimentos Análise Publicação
Automação Em andamento

Automação de processos financeiros com n8n + integração Protheus

Mapeamento e automação do fluxo de contas a pagar e receber integrando o n8n ao Protheus via REST API, com notificações automáticas e geração de relatórios no Power BI.

n8n REST API Protheus Power BI
Progresso 45%
Revisão bibliográfica Coleta de dados Experimentos Análise Publicação
Business Intelligence Em revisão

Modelo de predição de churn com DAX avançado e ML no Power BI

Desenvolvimento de um modelo preditivo de abandono de clientes integrado diretamente no Power BI, combinando medidas DAX complexas com modelos de machine learning via Python visual.

Power BI DAX Python ML
Progresso 90%
Revisão bibliográfica Coleta de dados Experimentos Análise Publicação
ERP & Protheus Em andamento

Análise de performance de queries SQL em ambientes Protheus de grande porte

Estudo comparativo de estratégias de otimização de queries nas tabelas SF2, SD1, SC5 e SE1 em instâncias com mais de 10 anos de dados, avaliando índices, planos de execução e uso de CTEs.

SQL Server Protheus ADVPL Performance
Progresso 30%
Revisão bibliográfica Coleta de dados Experimentos Análise Publicação
IA & Dados Concluída

Classificação automática de tickets de suporte com transformers fine-tuned

Fine-tuning de BERTimbau para classificação de tickets de suporte em português, atingindo 94% de acurácia em produção com latência média de 120ms por requisição.

BERT HuggingFace Python Fine-tuning
Progresso 100%
Revisão bibliográfica Coleta de dados Experimentos Análise Publicação
Automação Pausada

Pipeline de ETL automatizado para consolidação de dados multi-filial

Construção de pipeline ETL usando Python e Airflow para consolidar dados de múltiplas filiais Protheus em um data warehouse centralizado para análise no Power BI.

Python Airflow ETL Data Warehouse
Progresso 55%
Revisão bibliográfica Coleta de dados Experimentos Análise Publicação

Sugira uma Pesquisa

Tem uma ideia que merece ser investigada? Compartilhe aqui — as melhores sugestões viram pesquisas reais publicadas no site.

  • Sua sugestão é lida e avaliada pessoalmente
  • Se aprovada, você é notificado quando publicada
  • Contribuidores recebem crédito na publicação
47 sugestões recebidas
8 viradas em pesquisa
~3d tempo de resposta
Em alta agora:
IA Generativa n8n + ERP RAG DAX avançado LLM local CRISPR
0 / 120
0 / 800