📅 Data de publicação: 19/02/2026
❓ Dúvida
Como habilitar e utilizar o Ponto de Entrada NFCWFENV para incluir campos de quaisquer tabelas no template do Workflow customizado do NFC?
🧩 Ambiente
TOTVS Backoffice – Linha Protheus
Módulo: Compras (SIGACOM)
Funcionalidade: NFC – Envio de Workflow
Rotina: Template Workflow Customizado (NFCA030)
✅ Solução
🧠 O que é o PE NFCWFENV?
O NFCWFENV é um Ponto de Entrada (PE) que permite buscar valores em tabelas do Protheus e retornar o conteúdo para ser exibido dentro do HTML/template do Workflow customizado.
Na prática, ele funciona como um “resolvedor” de campos: o template solicita um campo, informa de onde vem e qual o tipo, e o PE devolve o valor já tratado como texto, pronto para o HTML.
⚙️ Como funciona (parâmetros recebidos)
O PE recebe parâmetros via Paramixb[]. Os mais importantes são:
Vínculo do dado (
cVinc): indica o contexto do templateCAB= CabeçalhoROD= RodapéITENS= Itens
Tabela (
cTabela): tabela onde está o campo a ser lido (ex.:SB1,SA2)Campo (
cCampo): nome do campo (ex.:B1_DESC,A2_NOME)Tipo (
cTipo): tipo do campo no templateNnumérico,Llógico,Ddata,Ccaracter,Mmemo
Chaves do contexto (exemplos comuns):
Nº da cotação, fornecedor, loja, proposta
Produto (quando
cVinc = ITENS)
📌 Retorno obrigatório: sempre caracter (string) para uso direto no HTML do Workflow.
🛠️ Implementação (modelo base em AdvPL)
Abaixo vai um exemplo prático (modelo) para leitura em SB1 (Produto) quando o vínculo for ITENS e em SA2 (Fornecedor) quando o vínculo for CAB/ROD.
#INCLUDE "protheus.ch" User Function NFCWFENV() Local aAreas := { SB1->(GetArea()), SA2->(GetArea()), GetArea() } Local cVinc := Paramixb[1] // CAB | ROD | ITENS Local cTabela := Paramixb[2] // Ex.: "SB1" | "SA2" Local cCampo := Paramixb[3] // Ex.: "B1_DESC" | "A2_NOME" Local cTipo := Paramixb[4] // N | L | D | C | M Local cForn := Paramixb[6] Local cLoja := Paramixb[7] Local cProd := Paramixb[9] // somente no ITENS Local cRet := "" Local aTamSx3 := {} If cVinc == "ITENS" .And. cTabela $ "SB1" DbSelectArea("SB1") SB1->(DbSetOrder(1)) If SB1->(DbSeek(xFilial("SB1") + cProd)) aTamSx3 := TamSX3(cCampo) cRet := __FmtWFValue(SB1->&(cCampo), cTipo, aTamSx3) EndIf ElseIf (cVinc $ "CAB/ROD") .And. cTabela $ "SA2" DbSelectArea("SA2") SA2->(DbSetOrder(1)) If SA2->(DbSeek(xFilial("SA2") + cForn + cLoja)) aTamSx3 := TamSX3(cCampo) cRet := __FmtWFValue(SA2->&(cCampo), cTipo, aTamSx3) EndIf EndIf aEval(aAreas, {|x| RestArea(x), FwFreeArray(x)} ) Return cRet Static Function __FmtWFValue(uVal, cTipo, aTamSx3) Local cOut := "" Do Case Case cTipo == "N" cOut := AllTrim( Str(uVal, aTamSx3[1], aTamSx3[2]) ) Case cTipo == "L" cOut := Iif(uVal, "true", "false") Case cTipo == "D" cOut := Iif( Empty(uVal), "", SubStr(FWTimeStamp(3, uVal), 1, 10) ) Otherwise cOut := AllTrim( cValToChar(uVal) ) EndCase Return cOut
🧪 Testes recomendados
✅ Para validar rapidamente:
Selecione um template customizado na rotina NFCA030
Configure o template para solicitar campos (CAB/ROD/ITENS)
Gere/execute o envio do Workflow NFC e confira:
Campo numérico renderiza corretamente (sem zeros indevidos)
Campo lógico retorna
true/falseCampo data sai no padrão esperado (AAAA-MM-DD no exemplo)
Campo caracter/memo aparece sem lixo/espaços desnecessários
⚠️ Pontos de atenção
Ordem/índice: garanta que a
DbSetOrder()utilizada atende oDbSeek()com a chave correta.Filial: normalmente a chave inclui
xFilial("TABELA").Segurança do template: o PE deve retornar apenas o necessário (evite expor campos sensíveis).
Performance: se o template solicitar muitos campos por item, evite operações pesadas e, se necessário, aplique cache/estratégia de leitura.
❓ FAQ
1) O PE NFCWFENV serve para quais rotinas?
Ele é utilizado no Workflow do NFC especificamente no contexto de Template Workflow Customizado (NFCA030).
2) Posso buscar campos de “qualquer tabela”?
Sim, desde que você implemente no PE a lógica de leitura (área, índice e DbSeek) para a tabela desejada.
3) Por que o retorno é sempre texto?
Porque o destino final é o HTML do Workflow. Mesmo número, data e lógico são convertidos para string para renderização.
4) Como tratar campo lógico no HTML?
O padrão comum é retornar true/false, facilitando uso em condicionais e exibição em templates.
5) O que acontece se não encontrar o registro?
O retorno normalmente fica vazio (""). Você pode evoluir o PE para retornar um texto padrão (ex.: “não informado”), se fizer sentido no template.
👤 Autor
Fabrizio Augusto Ventavolo
Consultor Especialista TOTVS — Mastersiga Consultoria