Ler SD1 por filial e documento, com lock correto¶
Não avaliada
Código gerado e não testado. Não foi compilado nem executado num ambiente Protheus real. Leia como ponto de partida, não como receita validada — e registre o teste quando fizer.
- Tipo:
exemplo - Estado:
nao-avaliada - Autor:
jarvis - Criado:
2026-10-22T14:00:00Z - Tabelas:
SD1 - Skills:
query-builder
Varredura de itens de nota fiscal de entrada por filial e documento, seguindo o padrão
de leitura que a própria TOTVS documenta: salvar a área, selecionar o alias, posicionar
por xFilial() + chave, iterar com DbSkip e restaurar a área.
Código¶
#Include "PROTHEUS.CH"
/*/{Protheus.doc} LerSD1PorDoc
Varre itens de NF de entrada da filial corrente, de um documento/serie.
@param cDoc , character , Numero do documento
@param cSerie , character , Serie do documento
@return Array, Vetor de itens { codigo, quantidade, valor }
@author jarvis
@since 22/10/2026
/*/
User Function LerSD1PorDoc(cDoc, cSerie)
Local aItens := {}
Local nArea := GetArea()
Local cChave := ""
Default cDoc := ""
Default cSerie := ""
DbSelectArea("SD1")
SD1->(DbSetOrder(1)) // D1_FILIAL + D1_DOC + D1_SERIE + ...
cChave := xFilial("SD1") + cDoc + cSerie
If SD1->(DbSeek(cChave))
While !SD1->(Eof()) .And. SD1->D1_FILIAL == xFilial("SD1") ;
.And. SD1->D1_DOC == cDoc .And. SD1->D1_SERIE == cSerie
If SD1->D1_COD <> ""
aAdd(aItens, { SD1->D1_COD, SD1->D1_QUANT, SD1->D1_VUNIT })
EndIf
SD1->(DbSkip())
EndDo
EndIf
RestArea(nArea)
Return aItens
Por que está escrito assim¶
GetArea()/RestArea()— a workarea é restaurada mesmo comReturnno meio.[31]xFilial("SD1")e não uma filial de outra tabela.[28]- A varredura é ISAM/
DbSkipporque o padrão documentado para este caso é esse;[54] em volume, a orientação da TOTVS é preferir SQL.[28] - A comparação de filial por extenso dentro do laço cobre o caso de
DbSeekcair no meio de um bloco de filial diferente.
Como testar¶
- Escolha um documento de NF de entrada com mais de um item na sua base.
- Rode
u_LerSD1PorDoc(cNumero, cSerie)pelo SmartClient ou por um job. - Confronte o array devolvido com o que a rotina padrão mostra para o mesmo documento.
- Teste o caso de borda: documento inexistente deve devolver um array vazio, não uma posição errada da workarea.
- Registre aqui o resultado e mude o estado para
avaliada.
Pendências conhecidas: não cobre SD1 de itens excluídos (expurgo por
D_E_L_E_T_ = ' ') — a varredura ISAM não devolve linhas excluídas logicamente, mas vale confirmar; e não trata o caso de duas filiais compartilhando documento.
Fonte¶
- Arquivo canônico:
examples/ler-sd1-por-filial.md - Voltar para Exemplos e templates