Pular para o conteúdo principal

Postagem em destaque

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️ Olá pessoal, Espero que este post encontre todos vocês bem! É com grande entusiasmo que compartilho que estou expandindo meus serviços como Desenvolvedor AdvPL para novos desafios e colaborações. Com mais de duas décadas de experiência sólida, minha jornada profissional tem sido enriquecedora, com a oportunidade de participar de projetos empolgantes ao longo dos anos. Agora, estou ansioso para trazer minha experiência e habilidades para novas equipes e projetos, trabalhando de forma remota. Minha expertise abrange não apenas AdvPL, mas também outras tecnologias-chave, incluindo JS, SQL, Infraestrutura e Otimização de Processos. Acredito que essa combinação de conhecimentos me permite oferecer soluções abrangentes e eficazes para uma variedade de necessidades de desenvolvimento. Acredito que a tecnologia tem o poder de transformar negócios e impulsionar o sucesso, e estou comprometido em ajudar meus clientes a alcançar seu

BlackTDN :: Posicione via SDU

SDU :: Siga Database Utility == APSDU :: Advanced Protheus “S” DataBase Utility == MPSDU :: Microsiga Protheus “S” DataBase Utility.

Quem nunca usou essa ferramenta que atire a primeira pedra.

Luizinho “Leitão” da TOTVS RJ aprendeu um cadinho de truques para usar no SDU, dentre eles: o uso da função posicione para um “Replace” via SDU.

Normalmente, quando se abre uma tabela via SDU ela recebe o seguinte “Alias” <Nome da Tabela> + “1”. Então, se abrirmos a tabela CNT010 seu alias será CNT0101.

Por padrão, não podemos abrir 2 vezes a mesma tabela. Mas nada nos impede de abrirmos duas tabelas com o mesmo nome.

Podemos abrir a tabela CNT010 via TOPCONN e a tabela CNT010 via DBFCDXADS/DBFCDXAX. Então, a primeira terá o alias CNT0101 e a segunda CNT0102.

Poderemos abrir tabelas de mesmo nome e para um mesmo RDD se estiverem ambas em localidades diferentes. Neste caso o SDU respeitará o esquema de nomeação de Alias sufixando o nome da tabela com um seqüencial 1, 2,…,n.

No exemplo, e por ser mais didático, utilizarei a tabela SX3 (Dicionário de campos do Protheus).

Vou usar duas tabelas SX3 com o mesmo nome, no mesmo RDD mais em localidades diferentes para efetuar um “Replace” (busca e substituição)  na coluna X3_ORDEM.

Em primeiro lugar vou salvar a tabela SX3010 da pasta \system\ na pasta tmp. Posso fazer isso de n maneiras. Dentre elas: copiando-a diretamente para a pasta, “Importando” (CTRL+T) ou “Copiando para (CTRL+Y) Via SDU . A vantagem de efetuar a cópia via SDU é a possibilidade efetuar um filtro.

Vamos ao exemplo:

Abrindo a tabela SX3010 via SDU usando o RDD (Driver) DBFCDXADS/DBFCDXAX.

image

image

Seleciono a ordem 1 (X3_ARQUIVO+X3_ORDEM)

image

E, agora, utilizando a opção “Copiar Para CTRL+Y” efetuo a cópia. Vou usar o mesmo Driver de Origem.

image

Observe que a sugestão de nome de arquivo segue o padrão de nomeação do Alias. Ou seja, é o nome da tabela sufixada com um número seqüencial. No nosso exemplo, como existe apenas uma tabela SX3010 aberta, o seu sufixo será “1”. Clico no botão OK e a cópia tem início. Neste caso todos os registros serão copiados pois nenhum filtro foi implementado. Vale lembrar, também, do estado de SET DELETED. Se ligado ou Desligado para a cópia, inclusive, dos registros “Deletados”.

image

Após a cópia uma mensagem com o número de registros “copiados” é mostrada conforme abaixo:

image

Considerando que a Ordem selecionada para a “Cópia” foi a 1, os registros foram fisicamente gravados na seqüencia X3_ARQUIVO + X3_ORDEM.

Agora, para que o exemplo fique mais didático, eu vou, primeiro, eliminar todos os registros da tabela SX3010 corrente (uma vez que já efetuei a cópia) utilizando a opção “ZAP CTRL+Z” para posterior “Append” na Ordem em que a cópia foi gravada.

image

Pronto. Minha tabela está limpinha e pronta para os testes.

image

Vou aproveitar a deixa e “Fechar” todos os índices da Tabela Corrente. Índice\Fechar. Isso porque, minha próxima ação será importar os registros de acordo com a Ordem de Gravação e depois efetuar o “Replace” no campo X3_ORDEM e, considerando que o campo X3_ORDEM faz parte da chave, se a mantiver aberta o processo não será concluído com sucesso.

image

Efetuando o “Append CTRL+A”:

image

Irei “Importar” os registros da tabela selecionada. No caso: a tabela anteriormente “copiada”.

image

Pronto. A tabela foi “repopulada”

.image

E, agora, usando a expressão ADVPL abaixo vou reordenar (Alterar o conteúdo do campo X3_ORDEM) de forma seqüencial e de acordo com X3_ARQUIVO de forma todos os intervalos sejam preenchidos.

IF(Type("x3o")=="C".and.xAlias==X3_ARQUIVO,x3o:=__Soma1(x3o),(xAlias:=X3_ARQUIVO,x3o:="01"))

Destrinchando a expressão ADVPL acima teremos: Usando a função condicional IF (equivalente a IIF) verifico se a variável “x30” está definida através da função Type que me retornará “C” se verdadeiro e “U” caso contrário. Se o retorno de Type() for “U” e o conteúdo de xAlias (ainda não declarada) for igual ao conteúdo da coluna/campo X3_ARQUIVO ele irá atribuir à coluna X3_ORDEM o retorno da atribuição x3o :=__Soma1(x3o), caso contrário, irá: 1 declarar (se ainda não estiver definida a variável xNome) é atribuir-lhe o conteúdo de X3_ARQUIVO e setar o conteúdo da variável x3o com “01” (valor inicial da seqüência).

Usando a opção “Replace CTRL+R”

image

(Obs.: A opção “Replace”, como todas as outras, poderiam ser melhoradas se já pré-selecionassem o campo de acordo com a coluna em foco. Normalmente a seleção  manual e a desatenção são a maior causa de problemas nesse tipo de operação).

image

image

Bem, todos os 70106 registros foram “reordenados”. Agora, ao uso da Posicione para restaurar a “Ordem” original.  Para isso, vamos, agora, “Abrir CTRL+B” a tabela SX30101 salva em \tmp\.

image

Ambas as tabelas SX3 estão abertas. Vamos prepara-las para a Posicione.

image

Mas antes, vamos descobrir qual o Alias atribuído à tabela SX30101. Para isso, basta simular uma “Cópia CTRL+Y” e o SDU nos mostrará qual Alias foi atribuído à tabela SX30101.

image

Sabemos, agora, o Alias atribuído à tabela SX30101: sx301011 (que segue a regra de atribuição anteriormente apresentada). Se a nova tabela aberta fosse SX3010 ao invés de SX30101 seu Alias seria SX30102 ao invés de SX301011. (Não precisamos confirmar a cópia e clicamos no botão “cancelar”).

Para que seja possível usar a função Posicione na tabela SX30101 ela deverá estar devidamente ordenada. Então, para isso, iremos criar um índice temporário: Índice\Criar

image

O índice será um índice temporário com as colunas X3_ARQUIVO+X3_CAMPO:

image

(Observe que para o índice ele atribui o mesmo nome do arquivo alterando, apenas, a sua extensão quando o Driver (RDD Controlador) é o DBFCDXADS/DBFCDXAX.)

image

Para o exemplo, indexamos apenas a tabela na qual a Posicione será utilizada, que é a tabela com a “Ordem Original”.

image

Agora, para que a Posicione funcione corretamente, os procedimentos abaixo deverão ser seguidos à RISCA:

  1. Selecione a Tabela na qual efetuará o “Replace CTRL+R”;
  2. Posicione o Ponteiro do Mouse na Primeira Linha da Tabela para que o “Replace” seja efetuado a partir da linha corrente;
  3. Monte a Expressão “Com” para o “Replace CTRL+R”;
    Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_ORDEM")
  4. Monte a Expressão “Para” com  a “Condição do Replace”;
    (Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_CAMPO")==SX30101->X3_CAMPO)

    Efetuando o “Replace”

    image

    image

    Observe que, por distração, o “Replace” foi executado na coluna/campo X3_ARQUIVO quando o correto seria na coluna X3_ORDEM. Desespero?!??!?! Não. No mínimo 2 (duas) soluções possíveis:

    image

    1. Copiar a Tabela SX30101 para SX3010 ; ou
    2. Efetuar o ZAP na Tabela SX3010, efetuar o Append dos Dados da tabela SX30101 e reordena-los ; ou
    3. Efetuar o Replace na Coluna X3_ARQUIVO de forma a restaura-la à sua situação original. (ainda bem que foi esse o campo) usando a seguinte regra:
      IF(SubStr(X3_CAMPO,3,1)=="_","S"+SubStr(X3_CAMPO,1,2),SubStr(X3_CAMPO,1,3))

      Pois a regra de formação do campo é: se o primeiro byte do Alias for “S” o campo não terá o “Alias” completo será SubStr(X3_ARQUIVO,2,2)+_+campo, caso contrário, a formação do campo será X3_ARQUIVO+_+campo.

    image

    image

    Ufa. Agora que restauramos o conteúdo do campo X3_ARQUIVO vamos ao “replace” da coluna X3_ORDEM usando Posicione.

    Mas, antes, vamos contar quantos registros foram alterados com a reordenação do campo X3_ORDEM usando a seguinte regra:

    !(Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_ORDEM")==SX30101->X3_ORDEM)

    image 

    image

    image 

    e, finalmente. Restaurar a Ordem “Original”

    image

    image

    image

    Após o “Replace”, se efetuarmos a contagem anterior deveremos obter o valor 0 (Zero)

    image

    image

    Pronto. Ordem restaurada.

    ATENÇÃO :: Vale lembrar que qualquer operação efetuada diretamente no SDU deve ser feita com muita atenção e após garantir uma cópia da tabela original.

    As expressões ADVPL utilizadas no exemplo foram:

    1 - Para “Reordenar” o campo X3_ORDEM utilizando a função __Soma1()
    IF(Type("x3o")=="C".and.xAlias==X3_ARQUIVO,x3o:=__Soma1(x3o),(xAlias:=X3_ARQUIVO,x3o:="01"))
    2 - Retorno da Expressão do Replace “Com”
    Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_ORDEM")
    3 - Condição do Replace “Para”
    (Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_CAMPO")==SX30101->X3_CAMPO)
    4 - Restaurar o conteúdo do campo X3_ARQUIVO
    IF(SubStr(X3_CAMPO,3,1)=="_","S"+SubStr(X3_CAMPO,1,2),SubStr(X3_CAMPO,1,3))
    5 - Contar o número de registros afetados pela expressão em 1
    !(Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_ORDEM")==SX30101->X3_ORDEM)

    []s
    иαldσ dj

    Comentários

    1. Preciso alterar no campo R8_DTFIM, somente o ano
      Exemplo:
      R8_DTFIM = 31/01/2014
      IF(SUBSTR(CTOD(RFQ_DTFIM,5,4)=="2014"),"2013") ISSO É POSSIVEL via APSDU?

      ResponderExcluir
    2. IF(SUBSTR(CTOD(RFQ_DTFIM,5,4)=="2014"),"2013"), e possível incluir essa função via APSDU para mudar somente o campo DATA,

      ResponderExcluir

    Postar um comentário

    Postagens mais visitadas deste blog

    BlackTDN :: RLeg ~ Desvendando a Função ParamBox

    Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg. //---------------------------------------------------------- // Função exemplo utilizando a função ParamBox() //---------------------------------------------------------- User Function xParamBox() Local aRet := {} Local aParamBox := {} Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"} Local i := 0 Private cCadastro := "xParambox" // ---------------

    Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

    Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..." Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema. #INCLUDE "PROTHEUS.CH" #INCLUDE "TBICONN.CH" /*/ Funcao: MATA010Ex Data: 30/04/2011 Autor: Marinaldo de Jesus Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou 2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando ) /*/ User Function MATA010Ex( cEmpFil ) Local aEmpFil Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) } Local cEmp Local cFil Local cMod Local cModName := "SIGAFAT" DEFA

    BlackTDN :: Customizando a interface de Login no Protheus e by You

    A publicação “ BlackTDN :: By You e sua nova tela de login ”  de nosso amigo OBona deu o que falar e, em função disso, esse que a muito não vos escreve resolveu criar uma versão onde será possível personalizar, “por completo”, a tela de login no Protheus/by You. Considerando que OBona já havia “mapeado, identificado e customizado” as imagens peguei-as emprestadas para o exemplo que se segue: O primeiro passo para a customização “total” da interface de login do Protheus/by You será implementar o “Ponto de Entrada” ChgPrDir (Diretório de impressão) . Usaremos esse PE juntamente como programa U_FindMsObject.prg (apresentado pela primeira vez em: Protheus :: ADVPL : The Container : Presents Pandora's box ). Diferente do exemplo proposto por OBona, que substitui, durante o processo de compilação, as imagens padrões do sistema (excluindo-as) por imagens customizadas (com o mesmo nome) este novo exemplo mantém, no RPO, as imagens padrões adicionando novas imagens customizadas que serã