Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

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.

Array contendo os campos do cabeçalho da tela de preenchimento dos lotes.

NomeTipoDescrição
aHeadAux - ParamIXB[1]Array

aHeadAux - Em rotinas com grid (Pedido de compras, pedido de vendas, etc.), vem preenchido com o aHeader da rotina em questão, pois a variável aHeader passará a conter o cabeçalho da tela de grade.

aHeaderArray

05. RETORNO

...

Estrutura do array:

aHeadAux: Array contendo os campos cabeçalho
aHeadAux[n]: Contém os dados do campo
aHeadAux[n][1]: Título do campo, Ex: "Quantidade"
aHeadAux[n][2]: Nome do campo. Ex: "C7_QUANT"
aHeadAux[n][3]: Máscara do campo. Ex: "@E 99,999,999,999.99"
aHeadAux[n][4]: Tamanho do campo. Ex: 14
aHeadAux[n][5]: Decimal do campo. Ex: 2
aHeadAux[n][6]: Valid do campo. Ex: "MatVldGGrd() .And. aVldGr220()"
aHeadAux[n][7]: Usado do campo. Ex: "û"
aHeadAux[n][8]: Tipo do campo. Ex: "N"
aHeadAux[n][9]: F3 do campo. Ex: "SB1"
aHeadAux[n][10]: Contexto do campo - Real (R) ou Virtual (V)
aColsAux - ParamIXB[2]Array

aColsAux - Em rotinas com grid (Pedido de compras, pedido de vendas, etc.), vem preenchido com o aCols da rotina em questão, pois a variável aCols passará a conter o conteúdo da tela de grade.

Estrutura do array:

aColsAux: Contém os arrays de cada linha do grid da tela anterior
aColsAux[n]: Linha do grid
aColsAux[n][nPos]: Conteúdo do campo, conforme ordenação do aHeadAux. Ex: "PRODUTO000001"

Obs.: a última coluna de cada linha é do tipo lógico, que indica se a linha está deletada (.T.) ou não (.F.)

nLinO    - ParamIXB[3]Numérico

nLinO    - Em rotinas com grid (Pedido de compras, pedido de vendas, etc.), vem preenchido com a linha posicionada no aCols da rotina em questão. Em rotinas sem grid (Saldo inicial, etc.), sempre vem preenchido com o conteúdo 1.

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.

NomeTipoDescrição
aHeadGradeArray

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:

aHeadGradeContém um ou mais cabeçalhos de grade, a depender de quantos produtos com controle de grade foram informados na rotina principal.
aHeadGrade[nLinO]Contém 1+j posições, dependendo da quantidade de colunas de grade (tabela SBV)
aHeadGrade[nLinO,1]Indica se é uma Referência (R) ou não (N)
aHeadGrade[nLinO,j]A partir da segunda posição, contém as colunas da grade do produto, até o número diponível. Ex: Grade de 3 colunas, aHeadGrade[nLinO][2] a aHeadGrade[nLinO][4], j vai de 2 a 4. Contém arrays de 10 posições no mesmo padrão do aHeader do MsGetDados
aHeadGrade[nLinO,j,1]Título do campo, Ex: "[01] PEDRA"
aHeadGrade[nLinO,j,2]Nome do campo (controle interno). Ex: "_01"
aHeadGrade[nLinO,j,3]Máscara do campo. Ex: "@E 99,999,999,999.99                         "
aHeadGrade[nLinO,j,4]Tamanho do campo. Ex: 14
aHeadGrade[nLinO,j,5]Decimal do campo. Ex: 2
aHeadGrade[nLinO,j,6]Valid do campo. Ex: "MatVldGGrd() .And. aVldGr220()"
aHeadGrade[nLinO,j,7]Usado do campo. Ex: "û"
aHeadGrade[nLinO,j,8]Tipo do campo. Ex: "N"
aHeadGrade[nLinO,j,9]F3 do campo. Não utilizado
aHeadGrade[nLinO,j,10]Contexto do campo - Real (R) ou Virtual (V)

Recomenda-se que esta variável seja somente acessada para leitura.

oGrade:aCposCtrlGrdArray

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.

aColsGradeArray

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:

aColsGradeContém um ou mais grids da grade de produtos, a depender de quantos produtos com controle de grade foram informados na rotina principal.
aColsGrade[nLinO]Contém i posições, dependendo da quantidade de linhas de grade (tabela SBV)
aColsGrade[nLinO,i]Contém 1+j posições, dependendo da quantidade de colunas de grade (ver aHeadGrade)
aColsGrade[nLinO,i,1]Contém o título da linha. Ex: "[01] 10   "
aColsGrade[nLinO,i,j]A partir da segunda posição, contém as colunas da grade do produto, até o número diponível. Ex: Grade de 3 colunas, aColsGrade[nLinO][i][2] a aColsGrade[nLinO][i][4], j vai de 2 a 4. Contém array de k posições, a depender da quantidade de campos na rotina que permitem o controle de grade. Por exemplo, o Saldo inicial MATA220 possui 13 campos que permitem o preenchimento de grade, logo, este array terá 13 posições. Ver exemplo abaixo.
aColsGrade[nLinO,i,j,k]Contém o valor gravado na linha/coluna/campo da grade.

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
languagejava
themeMidnight
titleExemplo
linenumberstrue
#Include 'TOTVS.ch'

/*/{Protheus.doc} User Function MT220GRLA410GRDW
    Permite manipular a alterargrade ode arrayprodutos daem rotinadiversas automáticarotinas do sistema.
 MATA390 - Manutenção deÉ Lotes
possível aplicar tratamento pontual nautilizando inclusãoa defunção saldoFWIsInCallStack
 inicial (MATA220)
  para verificar Pora contarotina daque implementaçãochamou doo ponto de entrada, é recomendado acessar sempre a última posição
    doTambém array,é poispossível overificar pontoqual decampo entradaestá ésendo chamadopreenchido umapelo vezusuário
 por linha da SD5,com ondea é incluida uma linha
    nova a cada chamada.função ReadVar()

    Verificar a documentação completa no TDN
    @type  Function
    @author TOTVS Totvs
    /*/
User Function MT220GRLA410GRDW()
    Local aLotesaHeadAux := ParamIXB[1]
    Local aColsAux := ParamIXB[12]
    Local nLinO aHeader   := ParamIXB[23]
    Local nLast 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    := Len(aLotes)StrTokArr(cMask, ',')
    Local nTamProd := 0
    Local nTamLin  := 0
    Local nPDtVencnTamCol  := 0
    Local nQtdIni  := 0
    Local nVIni1   := 0
    Local nColGrd  := 0
    Local nLinGrd  := 0
    Local nPQINI   := 0
    Local nPVINI1  := 0
    Local nPQtdnVal     := 0
    Local nPSum nPLote   := 0
    Local cUnMed  nPProd   := 0
    Local cProduto := ''
    Local nNewLast nPQuant  := 0
    Local nQuant   := 0
    Local nPQntC7  := 0
    Local lUsaGrad := .F.
    Local cTabLin  := ''
    Local cTabCol  := ''
    Local aChvLin  := {}
    Local cNewLoteaChvCol  := {}
    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])

    //Alterando somente a última posição do array
Exemplo: Tratamento para o saldo inicial
    If FWIsInCallStack('MATA220')
     //Exemplo: Caso a data de vencimento informada seja igual a data de hoje, alterar para 31/12/2049
    nPDtVenc := AScan(aLotes[nLast]   //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]) == 'D5B9_DTVALIDVINI1'})
            EndIf
            If nPSum > 0
                oGrade:aSumCpos[nPSum, 2] := 0
            EndIf
            If nPDtVenc nQtdIni > 0 .And. nVIni1 > 0 .And. nPQINI > 0 .And. aLotes[nLast, nPDtVenc, 2] <= dDataBase
 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
              aLotes[nLast, nPDtVenc, 2] := CToD('31/12/2049')          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: 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] 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]) == 'D5C7_LOTECTLQUANT'})
       nPQtd If Len(oGrade:aSumCpos) > 0
            nPSum   := AScan(aLotes[nLast]ASCan(oGrade:aSumCpos, {|x| AllTrim(x[1]) == 'D5C7_QUANT'})
        EndIf
        If cUnMed == 'KG' 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. nPQtdnPQuant > 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. nPLote > 0
 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))
               cNewLote := Soma1(RTrim(aLotes[nLast, nPLote, 2]))
 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]))
              While aLotes[nLast, nPQtd, 2] > 100
      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 If:= ASCan(aLotesaHeadGrade[nLinO], {|x| RTrimValType(x)=='A' .And. AllTrim(x[nPLote, 2]) == RTrim(cNewLote)}) '_'+aChvCol[1]})
            If nColGrd > 0
                For cNewLotenLinGrd := Soma1(cNewLote)
1 To Len(aColsGrade[nLinO])
                    //Verifica se o produto existe Loop
para a linha
          EndIf
          cChvLin := aLotesaColsGrade[nLastnLinO, nPQtdnLinGrd, 21] -= 100//<- coluna 1 fixa, contem a chave da linha
            AAdd(aLotes, aClone(aLotes[nLast]))
        cChvLin := SubStr(cChvLin, At('[', cChvLin)+1, nTamLin)
                    nProd nNewLast  := Len(aLotes)
AScan(aProd, {|x| x[2] == cChvLin})
                     aLotes[nNewLast, nPQtd, 2]  := 100If 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
            aLotes[nNewLast, nPLote            //Manipular o totalizador, se houver
                        If nPSum > 0
                            oGrade:aSumCpos[nPSum, 2] := cNewLote+= nVal
                        EndIf
                    EndIf
                Next nLinGrd
            EndIf
        EndDoEndIf
    EndIf

Return aLotes
  

...

    //Restaura a área das tabelas
    AEval(aAreas, {|x| RestArea(x)})
Return