Postagem em destaque
- Gerar link
- Outros aplicativos
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.
Seleciono a ordem 1 (X3_ARQUIVO+X3_ORDEM)
E, agora, utilizando a opção “Copiar Para CTRL+Y” efetuo a cópia. Vou usar o mesmo Driver de Origem.
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”.
Após a cópia uma mensagem com o número de registros “copiados” é mostrada conforme abaixo:
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.
Pronto. Minha tabela está limpinha e pronta para os testes.
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.
Efetuando o “Append CTRL+A”:
Irei “Importar” os registros da tabela selecionada. No caso: a tabela anteriormente “copiada”.
Pronto. A tabela foi “repopulada”
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”
(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).
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\.
Ambas as tabelas SX3 estão abertas. Vamos prepara-las para a Posicione.
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.
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
O índice será um índice temporário com as colunas X3_ARQUIVO+X3_CAMPO:
(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.)
Para o exemplo, indexamos apenas a tabela na qual a Posicione será utilizada, que é a tabela com a “Ordem Original”.
Agora, para que a Posicione funcione corretamente, os procedimentos abaixo deverão ser seguidos à RISCA:
- Selecione a Tabela na qual efetuará o “Replace CTRL+R”;
- Posicione o Ponteiro do Mouse na Primeira Linha da Tabela para que o “Replace” seja efetuado a partir da linha corrente;
- Monte a Expressão “Com” para o “Replace CTRL+R”;
Posicione("SX301011",1,SX30101->(X3_ARQUIVO+X3_CAMPO),"X3_ORDEM") - 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”
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:
- Copiar a Tabela SX30101 para SX3010 ; ou
- Efetuar o ZAP na Tabela SX3010, efetuar o Append dos Dados da tabela SX30101 e reordena-los ; ou
- 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.
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) |
e, finalmente. Restaurar a Ordem “Original”
Após o “Replace”, se efetuarmos a contagem anterior deveremos obter o valor 0 (Zero)
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
- Gerar link
- Outros aplicativos
Comentários
Postagens mais visitadas
BlackTDN :: RLeg ~ Desvendando a Função ParamBox
- Gerar link
- Outros aplicativos
Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login
- Gerar link
- Outros aplicativos
Preciso alterar no campo R8_DTFIM, somente o ano
ResponderExcluirExemplo:
R8_DTFIM = 31/01/2014
IF(SUBSTR(CTOD(RFQ_DTFIM,5,4)=="2014"),"2013") ISSO É POSSIVEL via APSDU?
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