Histórico da Página
...
Para maiores informações a respeito da grade de produtos, acesse Grades de Produtos (MATA550 - SIGAEST)
...
Por se tratar de ponto de entrada de uso geral, recomenda-se que as regras de negócio sejam tratadas por rotina, separando-as com a verificação da função FWIsInCallStack.
Por ser acionada por vários campos de dentro das rotinas, recomenda-se a verificação do campo que acionou utilizando a função READVAR().
05. Parâmetros
Os parâmetros a seguir são informados pela variável Private PARAMIXB, e devem apenas ser lidos e não alterados pela customização.
...
Os parâmetros a seguir são disponibilizados por variáveis Private e podem ser lidos e alterados, entretanto, deve-se alterá-los com cautela para não comprometer o funcionamento da rotina. A alteração da estrutura dos arrays abaixo (seja excluindo ou adicionando novas posições) poderá acarretar em comportamentos imprevisíveis.
Nome | Tipo | Descrição | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
aHeadGrade | Array | aHeadGrade - Array contendo os cabeçalhos das telas de grade, uma posição por linha do grid original (tamanho do aColsAux). Acessar sempre pelo índice nLinO. Produtos diferentes podem possuir tabelas de grade diferentes. Este array é de uso interno, e não é referente ao exibido na tela para o usuário. Estrutura do array:
Recomenda-se que esta variável seja somente acessada para leitura. | ||||||||||||||||||||||||||||
oGrade:aCposCtrlGrd | Array |
05. RETORNO
...
Array com a lista de campos da rotina principal que acionam a interface de grade. Deverá ser usado apenas para consultar a posição no array aColsGrade. Veja a seguir e no exemplo. Não alterar este array. | ||||||||||||||
aColsGrade | Array | Array contendo os grids das tabelas de grade, uma posição por linha do grid original (tamanho do aColsAux). Acessar sempre pelo índice nLinO. Produtos diferentes podem possuir tabelas de grade diferentes. Este array é de uso interno, e não é referente ao exibido na tela para o usuário. Estrutura do Array:
Caso necessário, este array poderá ser alterado. | ||||||||||||
oGrade:aSumCpos | Array | Contém os totalizadores da interface de grade. Não está disponível para todos os campos. Verificar se o array existe e procurar em qual posição está o campo que está sendo alterado. | ||||||||||||
aHeader | Array | Array de cabeçalho da tela de grade a ser exibida, no padrão de array aHeader da MsGetDados. Ver a estrutura do aHeadAux acima. Contém os mesmos dados da aHeadGrade[nLinO], mas este array é específico da tela a ser exibida. | ||||||||||||
aCols | Array | Array com os dados da tela de grade a ser exibida, no padrão de array aCols da MsGetDados. Ver a estrutura do aColsAux acima. Contém os dados exibidos em tela para o usuário, e deve ser manipulado caso se deseje alterar as informações ao usuário. |
Por via de regra, deve-se alterar os arrays aCols, aColsGrade e oGrade:aSumCpos na mesma operação, para garantir a consistência dos dados. O preenchimento dos dados não dispara nenhuma validação ou regra da rotina, sendo necessário validar os dados a serem inseridos manualmente (por exemplo, no pedido de compras, ao preencher manualmente os arrays, não será disparada pergunta para criação automática do armazém do produto - SB2).
06. RETORNO
O ponto de entrada não espera retorno. A manipulação dos dados deve ocorrer nas variáveis descritas no item 05. Parâmetros, salvo restrições.
07. EXEMPLO DE UTILIZAÇÃO
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
/*/{Protheus.doc} User Function A410GRDW
Permite manipular a grade de produtos em diversas rotinas do sistema.
É possível aplicar tratamento pontual utilizando a função FWIsInCallStack
para verificar a rotina que chamou o ponto de entrada
Também é possível verificar qual campo está sendo preenchido pelo usuário
com a função ReadVar()
Verificar a documentação completa no TDN
@type Function
@author Totvs
/*/
User Function A410GRDW()
Local aHeadAux := ParamIXB[1]
Local aColsAux := ParamIXB[2]
Local nLinO := ParamIXB[3]
Local aArea := GetArea()
Local aAreaSB4 := SB4->(GetArea())
Local aAreaSBV := SBV->(GetArea())
Local aAreaSB1 := SB1->(GetArea())
Local aAreas := {aAreaSB4, aAreaSBV, aAreaSB1, aArea}
Local aCposTel := oGrade:aCposCtrlGrd
Local cCampo := StrTran(ReadVar(), 'M->', '')
Local cMask := SuperGetMV('MV_MASCGRD', .F., '')
Local aMask := StrTokArr(cMask, ',')
Local nTamProd := 0
Local nTamLin := 0
Local nTamCol := 0
Local nQtdIni := 0
Local nVIni1 := 0
Local nColGrd := 0
Local nLinGrd := 0
Local nPQINI := 0
Local nPVINI1 := 0
Local nVal := 0
Local nPSum := 0
Local nPProd := 0
Local cProduto := ''
Local nPQuant := 0
Local nQuant := 0
Local nPQntC7 := 0
Local lUsaGrad := .F.
Local cTabLin := ''
Local cTabCol := ''
Local aChvLin := {}
Local aChvCol := {}
Local cChvLin := ''
Local aProd := {}
Local nProd := 0
If Len(aMask) < 3
Return
EndIf
nTamProd := Val(aMask[1])
nTamLin := Val(aMask[2])
nTamCol := Val(aMask[3])
//Exemplo: Tratamento para o saldo inicial
If FWIsInCallStack('MATA220')
//Distribui o valor inicial na mesma proporção da quantidade inicial
If AllTrim(cCampo) == 'B9_VINI1'
nQtdIni := M->B9_QINI
nVIni1 := M->B9_VINI1
nPQINI := ASCan(aCposTel, {|x| AllTrim(x[1]) == 'B9_QINI'})
nPVINI1 := ASCan(aCposTel, {|x| AllTrim(x[1]) == 'B9_VINI1'})
If Len(oGrade:aSumCpos) > 0
nPSum := ASCan(oGrade:aSumCpos, {|x| AllTrim(x[1]) == 'B9_VINI1'})
EndIf
If nPSum > 0
oGrade:aSumCpos[nPSum, 2] := 0
EndIf
If nQtdIni > 0 .And. nVIni1 > 0 .And. nPQINI > 0 .And. nPVINI1 > 0
For nLinGrd := 1 To Len(aColsGrade[nLinO])
For nColGrd := 2 To Len(aColsGrade[nLinO, nLinGrd])
nVal := nVINI1 * aColsGrade[nLinO, nLinGrd, nColGrd, nPQINI] / nQtdIni
//Manipular o aColsGrade para futura gravação no banco de dados
aColsGrade[nLinO, nLinGrd, nColGrd, nPVINI1] := nVal
//Manipular o aCols para que o usuário visualize os valores pré-carregados
aCols[nLinGrd, nColGrd] := nVal
//Manipular o totalizador, se houver
If nPSum > 0
oGrade:aSumCpos[nPSum, 2] += nVal
EndIf
Next nColGrd
Next nLinGrd
EndIf
EndIf
EndIf
//Exemplo: Tratamento para o pedido de compras
If FWIsInCallStack('MATA121') .And. AllTrim(cCampo) == 'C7_QUANT'
//Distribui o saldo somente na primeira coluna
nPProd := ASCan(aHeadAux, {|x| AllTrim(x[2]) == 'C7_PRODUTO'})
nPQuant := ASCan(aHeadAux, {|x| AllTrim(x[2]) == 'C7_QUANT'})
nPQntC7 := ASCan(aCposTel, {|x| AllTrim(x[1]) == 'C7_QUANT'})
If Len(oGrade:aSumCpos) > 0
nPSum := ASCan(oGrade:aSumCpos, {|x| AllTrim(x[1]) == 'C7_QUANT'})
EndIf
If nPSum > 0
oGrade:aSumCpos[nPSum, 2] := 0
EndIf
If nPPRod > 0 .And. nPQuant > 0 .And. nPQntC7 > 0
cProduto := SubStr(aColsAux[nLinO, nPProd], 1, nTamProd) //Código da grade
nQuant := M->C7_QUANT //Quantidade digitada no pedido
EndIf
If !Empty(cProduto)
SB4->(DbSetOrder(1)) //B4_FILIAL+B4_COD
lUsaGrad := SB4->(DbSeek(FWXFilial('SB4')+cProduto))
EndIf
If lUsaGrad .And. nPQuant > 0
cTabLin := SB4->B4_LINHA
cTabCol := SB4->B4_COLUNA
//Encontra as chaves das tabelas
SBV->(DbSetOrder(1)) //BV_FILIAL+BV_TABELA+BV_CHAVE
If SBV->(DbSeek(FWXFilial('SBV')+cTabLin))
While !SBV->(EoF()) .And. SBV->(BV_FILIAL+BV_TABELA) == FWXFilial('SBV')+cTabLin
AAdd(aChvLin, SubStr(SBV->BV_CHAVE, 1, nTamLin))
SBV->(DbSkip())
EndDo
EndIf
If SBV->(DbSeek(FWXFilial('SBV')+cTabCol))
While !SBV->(EoF()) .And. SBV->(BV_FILIAL+BV_TABELA) == FWXFilial('SBV')+cTabCol
AAdd(aChvCol, SubStr(SBV->BV_CHAVE, 1, nTamCol))
SBV->(DbSkip())
EndDo
EndIf
//Verifica quais produtos foram cadastrados
SB1->(DbSetOrder(1)) //B1_FILIAL+B1_COD
aProd := {}
nColGrd := 1 //Verifica somente a primeira coluna
For nLinGrd := 1 To Len(aChvLin)
If SB1->(DbSeek(FWXFilial('SB1')+cProduto+aChvLin[nLinGrd]+aChvCol[nColGrd]))
AAdd(aProd, {SB1->B1_COD, aChvLin[nLinGrd], aChvCol[nColGrd]})
EndIf
Next nLinGrd
nVal := nQuant / Len(aProd) //Valor distribuido em cada linha da 1a coluna
//Encontra a posição na grade da primeira coluna. Os campos no aHeader são _+chave da coluna
nColGrd := ASCan(aHeadGrade[nLinO], {|x| ValType(x)=='A' .And. AllTrim(x[2]) == '_'+aChvCol[1]})
If nColGrd > 0
For nLinGrd := 1 To Len(aColsGrade[nLinO])
//Verifica se o produto existe para a linha
cChvLin := aColsGrade[nLinO, nLinGrd, 1] //<- coluna 1 fixa, contem a chave da linha
cChvLin := SubStr(cChvLin, At('[', cChvLin)+1, nTamLin)
nProd := AScan(aProd, {|x| x[2] == cChvLin})
If nProd > 0
//Manipular o aColsGrade para futura gravação no banco de dados
aColsGrade[nLinO, nLinGrd, nColGrd, nPQntC7] := nVal
//Manipular o aCols para que o usuário visualize os valores pré-carregados
aCols[nLinGrd, nColGrd] := nVal
//Manipular o totalizador, se houver
|
06. EXEMPLO DE UTILIZAÇÃO
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#Include 'TOTVS.ch' /*/{Protheus.doc} User Function MT220GRL Permite alterar o array da rotina automática do MATA390 - Manutenção de Lotes na inclusão de saldo inicial (MATA220) Por conta da implementação do ponto de entrada, é recomendado acessar sempre a última posição do array, pois o ponto de entrada é chamado uma vez por linha da SD5, onde é incluida uma linha nova a cada chamada. @type Function @author TOTVS /*/ User Function MT220GRL() Local aLotes := ParamIXB[1] Local aHeader := ParamIXB[2] Local nLast := Len(aLotes) Local nPDtVenc := 0 Local nPQtd := 0 Local nPLote := 0 Local cUnMed := '' Local nNewLast := 0 Local cNewLote := '' //Alterando somente a última posição do array //Exemplo: Caso a data de vencimento informada seja igual a data de hoje, alterar para 31/12/2049 nPDtVenc := AScan(aLotes[nLast], {|x| AllTrim(x[1]) == 'D5_DTVALID'}) If nPDtVenc > 0 .And. aLotes[nLast, nPDtVenc, 2] <= dDataBase aLotes[nLast, nPDtVenc, 2] := CToD('31/12/2049') EndIf //Exemplo: Para produtos controlados em KG, quebra em lotes de 100Kg cUnMed := Posicione('SB1', 1, FWXFilial('SB1')+SB9->B9_COD, 'B1_UM') nPLote := AScan(aLotes[nLast], {|x| AllTrim(x[1]) == 'D5_LOTECTL'}) nPQtd := AScan(aLotes[nLast], {|x| AllTrim(x[1]) == 'D5_QUANT'}) If cUnMed == 'KG' .And. nPQtd > 0 .And. nPLote > 0 cNewLote := Soma1(RTrim(aLotes[nLast, nPLote, 2])) While aLotes[nLast, nPQtd, 2] > 100 If ASCan(aLotes, {|x| RTrim(x[nPLote, 2]) == RTrim(cNewLote)})If nPSum > 0 cNewLote := Soma1(cNewLote) oGrade:aSumCpos[nPSum, 2] += nVal Loop EndIf EndIf aLotes[nLast, nPQtd, 2] -= 100 AAdd(aLotes, aClone(aLotes[nLast])) EndIf nNewLast := Len(aLotes) Next nLinGrd aLotes[nNewLast, nPQtd, 2] := 100EndIf EndIf aLotes[nNewLast, nPLote, 2] := cNewLote EndIf //Restaura a área das EndDotabelas EndIf Return aLotes |
...
AEval(aAreas, {|x| RestArea(x)})
Return |