Copy, Append e Replace - APSDU Olá! Hoje, por sugestão de um leitor, vamos falar um pouco sobre as operações básicas do APSDU. O APSDU/MPSDU é uma ferramenta de gerenciamento de base de dados para o TOTVS Protheus, tanto para tabelas em arquivos DBF/CTREE/BTRIEVE quanto para tabelas na base de dados SQL. Dessa forma, através dele é possível de gerenciar tanto dicionários de dados quanto às tabelas de registros de usuário (clientes, fornecedores, produtos, TES, condições de pagamento, etc). Para exemplificar algumas das funcionalidades do sistema, vamos fazer um processo de cópia de registros (que pode ser utilizado para backup antes de uma operação), append de registros em uma tabela, como apagar uma tabela da base de dados e como realizar replace em registros; Lembrando que toda e qualquer operação na base de dados deve ser realizada com muito cuidado e atenção. Uma vez que existem relacionamentos de sistema (o Protheus não usa relacionamentos dentro da base de dados) entre os registros da tabela, qualquer alteração feita em um registro pela ferramenta APSDU será aceita e executada. Isso pode gerar diversos problemas durante a execução dos processos no sistema. O ideal é trabalhar com uma base de dados local primeiro para ter certeza que as alterações não irão impactar negativamente o sistema Tabela de Exemplo Para esse artigo criei uma tabela de testes simples na base de dados. Ela contém poucos campos, mas que já ajudam a analisar todo o processo e alguns problemas que podem surgir alterando manualmente os registros de uma tabela: ZA0_FILIAL ZA0_CODIGO ■ ■ Título e descrição: Código Tipo e tamanho: C 6,0 ■ ■ Picture: @! X3_RELACAO: GETSX8NUM(“ZA0″,”ZA0_CODIGO”) ZA0_NOME ■ ■ ■ Título e descrição: Nome Tipo e tamanho: C 60,0 Picture: @! ZA0_NASCTO ■ ■ Título e descrição: Dt. Nascto Tipo e tamanho: D 8,0 Criei a tabela como ZA0 aqui e a única particularidade da tabela é que ela tem um númerador automatico no campo ZA0_CODIGO. Dessa forma, criei uma função de AxCadastro simples pra tabela e inseri alguns registros nela. Se precisar de ajuda sobre como fazer uma função dessas, leia esse artigo: AxCadastro – Cadastro Simples. Após criar a função você poder colocar em um menu para facilitar o seu acesso: Menu de Acesso ao Sistema. Ainda, se você precisar de ajuda para criar a tabela na base de dados, segue listagem de artigos sobre o assunto: Tabelas e Campos e Índices e Agendando Alterações no Dicionário de Dados Cópia/Backup dos Dados Uma das funcionalidades mais importantes do APSDU é realizar a cópia dos dados de uma tabela para um arquivo separado. Esse tipo de operação existe desde os precursores do APSDU (FOX, DBU…) porém é possível realizar a cópia de registros de uma tabela em uma base SQL para um arquivo .dbf, por exemplo. Assim, podemos fazer um “backup” dos registros de determinadas tabelas antes de executar algum processo que irá alterar radicalmente a estrutura ou dados (um update, pode exemplo). Para acessar a função cópia vá em Utilitário > Copiar Para, ou utilize as teclas de atalho CTRL + Y. É importante já estar com a tabela aberta (que pode ser feito com as teclas de atalho CTRL + B). A tela acima será exibida com os seguintes campos: ■ (Caminho)Arquivo: é o caminho onde o arquivo com os registros selecionados será salvo. Ao clicar no botão “…” será apresentada a tela acima a esquerda onde é possível selecionar em qual diretório o arquivo será salvo. Caso queira alterar o nome padrão oferecido para o arquivo, basta alterar no campo de texto; ■ ■ Driver: Informa qual o tipo de arquivo que será utilizado para o arquivo salvo. Estão disponíveis as opções “DBF (DBFCDXADS/DBFCDXAX)“, “Top Connect (TOPCONN)“, “BTrieve (BTVCDX)“, “Ctree (CTREECDX)” e “Arquivo TXT“; Para: Esse é um campo importante. Ele define um filtro de quais registros serão copiados para o arquivo final. Ou seja, você pode clicar no botão “…” e será apresentada a tela padrão de filtros do TOTVS Protheus: Nessa tela é possível selecionar quais os campos da tabela aberta no momento da cópia, definir o operador utilizado (Igual a, Maior que, Maior ou igual a, Menor que, etc) e qual o valor da expressão que deverá ser obedecido. Utilizando os operadores and e or, juntamente com os parênteses, você consegue definir uma expressão completa que servirá de filtro para selecionar os registros que serão salvos no arquivo; ■ ■ Enquanto: É importante lembrar que todas as funções de execução em massa no APSDU são executadas a partir do registro atual em que o usuário está posicionado. Dessa forma, o campo enquanto define uma condição que deve ser atendida para a cópia dos arquivos e, somente enquanto ela for satisfeita os registros serão copiados.Pensando na lógica de como ela funciona, podemos traçar uma comparação direta com um Do While em Clipper/AdvPL. Ela é muito utilizada quando o usuário abre uma tabela, organiza os registros de acordo com um determinado índice, busca uma determinada informação (CTRL + S) e irá copiar os dados enquanto aquela busca for atendida. A expressão utilizada para esse campo também pode ser informada através do botão “…”; Opções: Outra possibilidade interessante da tela de cópia é que é possível copiar uma quantidade definida de registros que atendem as condições especificadas. As opções disponíveis são: Todos (irá copiar todos os registros que atendam as condições especificadas), Próximos (exibe um campo lateral para você informar quantos registros que atendam as condições especificadas serão copiados à partir do registro atual) e Resto (irá copiar o restando dos registros que atendam as condições especificadas, à partir do atual). Após especificar os registros que você deseja copiar através das condições informadas, você pode clicar no botão OK. Uma tela com uma barra de progresso da cópia será exibida e o tempo dependerá da quantidade de registros que serão selecionados. No término da operação, o arquivo será gerado no caminho solicitado e estará disponível para cópia, transferência, exclusão…enfim, qualquer operação disponível para os arquivos no computador. Append dos Dados Já realizamos a cópia de registros de uma tabela do Protheus para um arquivo separado, agora vamos fazer o processo inverso: copiar os registros de um arquivo para uma tabela do sistema. Esse é um procedimento muito comum, utilizado para equalizar dicionários de dados e copiar registros de uma base para outra (validação para produção, por exemplo). Para acessar a função de Append, basta ir em Utilitário > Append From ou utilizar as teclas de atalho CTRL + A. A mesma tela de parâmetros apresentada na cópia irá aparecer só que, nesse momento, o alvo dos parâmetros é o arquivo que vamos utilizar para a cópia e não a tabela aberta no APSDU. Dessa forma, podemos copiar somente alguns registros para dentro da tabela do sistema e não somente o conteúdo completo de um arquivo. Uma coisa importante de mencionar no processo de cópia de registros é que o APSDU faz simplesmente a cópia dos registros e, como o Protheus não utiliza definições de base de dados para numeradores sequenciais em tabelas, campos como Código poderão ficar com o seu conteúdo prejudicado para os próximos cadastros. Isso acontece porque o sistema trabalha com um conceito de múltiplas possibilidades de arquitetura de bancos de dados e é possível escolher entre diversos SGBDs. Nem todos eles tem um mecânismo de controle de numeração interno (imagine uma base de dados DBF). Agora imagine o seguinte cenário: você tem uma tabela com um campo sequencial (como o ZA0_CODIGO), cadastra três registros (o sequencial fica com o próximo número em “000004“) e você faz o append de 3 registros (tomando o cuidado de alterar manualmente o conteúdo do campo ZA0_CODIGO desses registros para que fiquem “000004“, “000005” e “000006“). Quando você for cadastrar um novo registro através do sistema, qual o código que será gerado automaticamente? Sim, “000004“! E, ao salvar você receberá um belo erro de chave duplicada na tabela Para solucionar isso você pode alterar manualmente os sequenciais no TOTVS Protheus (supondo que o seu servidor não esteja configurado para controlar o sequencial no hardlock), o que é um procedimento que não recomendo por abrir margem para diversos erros, ou você pode utilizar o código abaixo para solucionar o problema: /*/ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±± ±±ºPrograma ³FIXSXENUM º Autor ³ Vinícius Gregório º Data ³ 09/07/14 º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºDescricao ³ Função auxiliar para ajustar código sequencial de tabela º±± ±±º ³ º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºUso ³ AcademiaERP º±± ±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ±± ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß /*/ User Function FIXSXENUM(cTabela,cCampo,nQuantidade) //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Declaracao de Variaveis ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Local aArea := GetArea() Local lRetorno := .T. DEFAULT cTabela DEFAULT cCampo DEFAULT nQuantidade := "ZA0" := "ZA0_CODIGO" := 4 For nLoop := 1 to nQuantidade GetSX8Num(cTabela,cCampo) ConfirmSX8() Next nLoop RestArea(aArea) Return lRetorno Básicamente, é uma função para solicitar o próximo número de determinado campo com sequencial de uma tabela e confirmar essa numeração. Essa funcionalidade é executada pelas funções GetSX8Num e ConfirmSX8 que, respectivamente, solicita o próximo número e confirma a utilização desse número. No meu caso, coloquei um laço controlando a quantidade de números que serão utilizados e coloquei na assinatura da função a possibilidade de receber as informações de qual tabela (alias da tabela), qual o campo e quantos números serão “queimados”. Para chamar em menu sem precisar colocar uma tela para informar esses parâmetros, utilizei o DEFAULT para cada um desses pârametros. Revisão das funcionalidades + Drop de Tabela + Replace Conclusão Espero que tenham gostado desse artigo! Como podem ver, hoje começamos uma nova linha de artigos aqui na AcademiaERP, com conteúdo em vídeo no nosso novo canal do Youtube. A idéia é publicarmos mais vídeos com conteúdo do TOTVS Protheus e estou deixando o link do canal para quem quiser se inscrever: www.youtube.com/user/academiaerp Obrigado e até o próximo! TOTVSMNTLIC As vezes nos deparamos com a mensagem de que não há mais licenças disponíveis ao acessar o sistema. A função TOTVSMNTLIC é uma boa opção para descobrirmos quem esta consumindo licenças. Para utiliza-la é só digitar a palavra TOTVSMNTLIC no campo programa dos parâmetros iniciais do Protheus. Os demais campos devem ser preenchidos de acordo com a sua base. Será exibida a tela uma tela conforme abaixo, porém serão exibidas as informações de consumo de licença de acordo com o seu License Server. Como eu utilizo uma base de testes, não tenho informações reais para demonstrar neste exemplo. Mas faça o teste em sua base e descubra como suas licenças estão sendo consumidas. [optinform] É isso ai galera, espero que tenham gostado. Atualização de Binário Neste artigo iremos mostrar detalhadamente o processo para atualização de Binário. Segue tela com a instrução do download do Binário. Obs. Download disponível no portal da Totvs. Após o download, repare que a estrutura das pastas que baixou é exatamente esta abaixo. O procedimento para atualização é bem simples. Pare os serviços do Protheus, abra a pasta appserver cujo você baixou, copie todos os arquivos e cole na sua pasta appserver do sistema, mandando substituir o que tiver o mesmo nome. Repita este procedimento para os outros diretórios, smartclient e smartclientActiveX. Obs. Os arquivos de configuração como appserver.ini e smartclient.ini não serão afetados. [optinform] Desta forma o Binário estará atualizado. Lembre-se apenas que após atualização do Binário, deve-se renovar os arquivos de acesso ao sistema (smartclient), caso contrário aparecerá a mensagem “incompatibilidade de versão”. Chave SpecialKey - Protheus Quando o controle de numeração do sistema for realizado através do hardlock e existir mais de uma base compartilhando este hardlock, precisamos utilizar uma chave chamada SpecialKey. Ela serve para que o sistema possa identificar qual base fez a requisição do próximo numero. Vamos supor que temos um campo chamado A1_SEQUEN e o inicializador padrão deste campo executa a função GETSXENUM para buscar a numeração sequencial. Se tivermos uma base de teste e uma base de produção com esta mesma configuração, ao entrar na base de teste e executar a função, o sistema retornará o próximo numero e se depois entrarmos no ambiente de produção ele retornará o numero sequencial ao utilizado no ambiente de teste. Numero recebido pela base de teste: 4 Numero recebido pela base de produção: 5 Isso acontece porque o hardlock não sabe o que é sua base de teste e o que é sua base de produção. Por isso devemos utilizar a chave SpecialKey no Ini do server para informar ao hardlock que estamos utilizando bases diferentes, assim a numeração de uma base será independente da outra. [optinform] A utilização da chave é bem simples, basta coloca-la abaixo da seção do ambiente. A chave necessita apenas de uma string que será utilizada para identificar a base, por exemplo, no ambiente de produção pode ser SpecialKey=prd e no ambiente de teste SpecialKey=tst. Abaixo temos o exemplo de como o appserver.ini ficaria. [producao] SourcePath=c:producaoApo RootPath=C:producao StartPath=system RpoDb=TOP LocalFiles=CTREE RpoLanguage=Portuguese RpoVersion=111 Trace=0 LocalDbExtension=.DTC SpecialKey=prd [teste] SourcePath=c:testeApo RootPath=C:teste StartPath=system RpoDb=TOP LocalFiles=CTREE RpoLanguage=Portuguese RpoVersion=111 Trace=0 LocalDbExtension=.DTC SpecialKey=tst É isso ai galera, espero ter ajudado. Conf. NFSE Parte I Configurações básicas para Nota Fiscal de Serviço Eletrônica (NFSE) via WebService. Parte I Nota Fiscal de Serviço Eletrônica é um assunto que sempre gera muitas dúvidas e muitos problemas, portanto neste artigo iremos mostrar algumas configurações básicas que com certeza será de grande valia. Para configuração do SPED NFSE (via TSS), é necessário que possua um certificado digital, de preferencia o modelo A1 do certificado. Com base no link abaixo, veja qual a versão do TSS e empresa fornecedora do Layout de seu município, caso a versão do seu TSS seja inferior a indicada no município da tabela, o TSS deverá ser atualizado, caso contrario, não há necessidade. http://tdn.totvs.com.br/download/attachments/30605375/Rela%C3%A7%C3%A3o+Munic%C3%ADpi os+Homologados+Via+TSS.pdf?version=2&modificationDate=1391776100000 Abaixo seguem algumas dicas Atualizar os rdmakes da NFSE padrão no seu ambiente. (Disponível para download no Portal da Totvs) ———————————— nfsexml001 – DSFNET nfsexml002 – Abrasf nfsexml003 – Osasco padrão Único (E-governe) nfsexml102 – Arquivos xml – txt nfsexmlenv – P11 se NFSEMOD=T (engloba todos os fontes)Agora, o próximo passo são os cadastros. ————————— Fontes de informação. Consulta de Soluções, Portal Totvs. Os cadastros no arquivo de empresa devem ser preenchidos sem nenhum caractere especial, e os dados de preenchimento obrigatórios para o funcionamento da NFSE são: Endereço completo, Cnae, Código de Municipio e Inscrição Municipal. A TES usada na nota deve calcular e tributar o ISS. Não teve conter nenhum caractere especial no cadastro do cliente. O código de serviço(tabela 60 na SX5) deve estar preenchido no cadastro do Produto. O parâmetro MV_NFSEMOD deve estar como .F. (false), para não habilitar o modelo único de envio. Verifique se a serie da nota que será emitida está preenchida no parâmetro MV_ESPECIE, Supondo que a série seja A1, o conteúdo do parâmetro ficaria: A1 =RPS [optinform] Bom galera, essa é a primeira parte de nossas dicas sobre Nota Fiscal de Serviço Eletrônica. Criei um grupo no fórum para tirar duvidas sobre NFSE e NFE Sefaz. Caso tenham alguma duvida estou a disposição. http://www.academiaerp.com.br/forums/topic/dicas-de-desenvolvimento/ Índices e Agendando Alterações no Dicionário de Dados Continuando a nossa série de artigos de criação de tabelas customizadas, vamos hoje falar sobre índices e como aplicar essas alterações na base de dados. Criando índices Índices representam um mecanismo para ordenar os registros dentro de uma tabela. Através deles é possível realizar pesquisas dentro das tabelas da base de dados de forma prática e rápida (ao invés de fazer um full scan na tabela). Na edição de uma tabela, podemos selecionar o item “Índices” no menu lateral. Será apresentado uma tela com todos os índices da tabela em edição. No nosso caso, ainda está vazio Para incluir um novo índice, basta clicar no botão A tela acima será apresentada. Ela apresenta os seguintes campos: Chave: Determina quais das colunas da tabela, em ordem específica, farão parte desse índice. Seu preenchimento é feito através da opção “Campos”, dentro do menu inferior direito “Ações relacionadas”. Esse é o campo principal para preenchimento nessa tela. É importante ressaltar que, salvo raras exceções, todos os índices começam sempre com o campo filial. O motivo disso é simples: separar os registros de acordo com a estrutura de empresas e filiais do Totvs Protheus. Nickname: Esse campo determina qual será o “apelido” desse índice. Os apelidos nos índices foram criados com o objetivo de evitar alterações na ordem dos índices no dicionário de dados, utilizando a função dbOrderNickname(<apelido do índice>). Dessa forma, ao invés de utilizar o dbSetOrder(<número do índice>) e correr o risco de, em determinado ambiente de cliente, o índice estar em outra posição, utilizando apelidos para nossos índices, evitamos esse problema. Descrição, Desc. Espanhol, Desc. Inglês: Esse campo é a concatenação do nome dos campos que compõe o índice. Serve para facilitar o entendimento do índice para o analista. Mostra pesq: Esse checkbox define se o índice estará disponível para a pesquisa dos usuários em telas de cadastro. Se esse campo estiver marcado, ele aparecerá na caixa de seleção de ordem de pesquisa para o usuário. [optinform] É importante notar que, para que uma tabela possa ser utilizada em cadastros, é necessário que ao menos um índice tenha essa opção marcada. Aplicando as alterações no dicionário de dados Após realizar a manutenção dos campos e índice, vamos aplicar as nossas alterações na base de dados. Esse processo faz com que todas as alterações no dicionário sejam utilizados para realizar as alterações necessárias no seu SGBD (cria a tabela na base de dados, com os campos e índices que você definiu). Para realizar essa tarefa, vamos confirmar as alterações na tabela clicando no botão . Após essa confirmação, na barra superior, clicamos em . Será apresentada a tela abaixo com o resumo das alterações que foram criadas no dicionário de dados. Para continuar o processo basta clicar em “Avançar” para os passos apresentados e aguardar, na etapa final, o resultado da operação. Em geral, o processo é bem simples e fácil, raramente apresentando erros na parte de aplicar as alterações na base. No entanto, para que o sistema consiga aplicar determinadas alterações (tudo que alterar a estrutura da base de dados: criação ou alteração de campos não virtuais, criação de tabelas, criação ou alteração de índices…) ele irá verificar e solicitar que nenhum outro usuário esteja conectado no sistema no momento. Para tanto, muitas vezes é necessário solicitar aos usuários que permaneçam fora do sistema em um determinado intervalo de tempo e/ou realizar essas manutenções fora do horário de expediente. Agendando alterações para aplicação posterior Outra solução para o problema de exclusividade da base de dados no momento de aplicar uma alteração é agendar essa tarefa para execução posterior ou salvar as alterações para serem aplicadas em outra hora. Por definição, sempre que saímos do Configurador após realizarmos alterações no dicionário, a seguinte mensagem será apresentada: Clicando em “Sim” suas alterações ficarão salvas até que o gerenciador de dicionário de dados do Configurador seja aberto novamente, apresentando a mensagem abaixo para recuperar essas alterações: Após recuperadas as alterações, basta clicar em normalmente e aplicar as alterações. Esse processo é útil para quando realizamos as alterações e só poderemos salvá-las depois. No entanto, existem casos em que vamos querer que as alterações sejam aplicadas em determinado horário, sem a nossa intervenção. Para isso, podemos clicar no botão . A tela abaixo será apresentada: Após preencher a data e horário que deseja que a manutenção ocorra, clique para salvar o agendamento. Se não houveram erros no preenchimento, a tela de confirmação será apresentada: Se o sistema estiver exclusivo no momento agendado, a aplicação das alterações ocorrerá corretamente Conclusão Com esse artigo estamos próximos de concluir esse guia básico de criação de um cadastro simples no sistema. No próximo artigo, vamos mostrar como criar um cadastro simples em cima dessa tabela e como trabalhar com algumas funções que fazem parte desse processo. Até lá! Tabela e Campos - Tabelas Customizadas Protheus Olá, Uma das tarefas mais comuns do analista desenvolvedor é criar projetos que envolvam um ou mais modelos de dados diferentes dos originais do sistema. Por “modelos de dados” estamos tratando de entidades que serão representadas por conjuntos de registros dentro de uma tabela na base de dados. Esses modelos podem ser necessários quando o conceito que eles abordam são extremamente particulares ao negócio de uma empresa e, portanto, não estão representados dentro das tabelas do padrão do sistema. Nesse artigo vamos fazer um passo-a-passo de criação de uma tabela “customizada” na base de dados e como criar um cadastro para ela. Como exemplo, vamos gerar uma tabela bem simples, com dois campos apenas e que serve apenas para o propósito de estudo desse artigo. É um procedimento extremamente básico, mas para os analistas que estão começando é muito importante dominar completamente essas operações Acessando o Configurador Para começar nosso tutorial, acesso o módulo Configurador do TOTVS Protheus (lembre-se que os campos Comunicação no cliente irá variar de acordo com a chave de comunicação – ip e porta – do seu arquivo smartclient.ini. Para o caso do campo Ambiente, a definição está no appserver.ini, dentro da instalação do servidor do Protheus): Para acessar esse módulo, o seu usuário deve ter a permissão de acesso devida para manutenção do SIGACFG (verifique as permissões de seu usuário). Após acessar o módulo, entre nas opções Dicionário > Base de Dados no menu: Essa tela nos traz a manutenção do dicionário de dados do Protheus. O dicionário de dados é um cadastro (em diversos arquivos-tabelas) que define a estrutura da base de dados e alguns comportamentos específicos do sistema, como Gatilhos (preenchimentos automáticos de determinados campos, quando o usuário preenche uma informação em outro campo), validações de dados, máscaras de preenchimento… [optinform] No frame lateral, vamos selecionar a opção Dicionário de Dados. No painel lateral direito, uma listagem das tabelas cadastradas no dicionário de dados será apresentada. Incluindo uma nova tabela (SX2) Vamos incluir uma nova tabela clicando em exibida: na barra superior. A seguinte tela será Vamos preencher os campos apresentados da seguinte forma: ■ ■ ■ ■ ■ Prefixo: Esse é o Alias da tabela. Seu código representativo. Como estamos criando uma tabela temporária, existem alguns grupos de códigos que normalmente são utilizados para a criação de tabelas customizadas (SZx, Pxx, Zxx … onde “x” são caracteres abstratos que podem ir de 0 a Z). No nosso caso, vamos criar a tabela “ZZZ”; Path: Esse é o caminho, dentro do Protheus_Data, onde essa tabela será salva. Na realidade, esse campo só é útil quando utilizamos bases de dados DBF ou CDX, que criam um arquivo físico representando cada uma das tabelas do sistema; Nome: É o nome completo da tabela dentro da base de dados (novamente, para bases DBF ou CDX, esse será o nome do arquivo, seguido da sua extensão. Ex: ZZZ990.DBF). Em bases de dados SQL, o sistema irá criar uma tabela (CREATE TABLE) com esse nome dentro do banco. A estrutura para esse nome é bem simples de ser decomposta: ZZZ é o código da tabela, 99 é o número da empresa (no nosso caso, estamos usando a empresa de testes 99) e 0 é o sufixo final reservado (o último caracter do nome de uma tabela sempre será 0); Descrição: Esse campo é utilizado para descrever a utilidade dessa tabela. Geralmente, é utilizado para descrever a entidade que é representada por cada um dos registros da tabela (Ex.: Clientes); Ac. Filial, Ac. Unidade e Ac. Empresa: Determina se essa tabela será compartilhada ou exclusiva dentro do sistema de filiais, unidades de negócio e empresas do sistema. Uma tabela pode ser compartilhada de forma diferente dentro de cada nível de estrutura da organização da empresa dentro do sistema. Dessa forma, uma tabela compartilhada entre filiais vai ter registros de todas as filiais de uma determinada unidade de negócio e empresa dentro dela e, consequentemente, independente da filial em que o usuário estiver logado, ele poderá consultar todos esses registros; Após preencher esses campos, é necessário clicar em no botão verde na barra superior para que o Configurador crie a estrutura básica da tabela na memória: Criação de campos (SX3) Com a estrutura básica da tabela já criada, vamos criar os campos (colunas da base de dados para ela). Com a tabela ZZZ selecionada na grid, clique no botão Editar na barra superior. Aparecerá uma tela com a estrutura da tabela. Selecione, no frame lateral esquerdo, a opção Campos e depois clique em Será apresentado para o usuário uma tela com campos que irão representar um as propriedades de um campo dentro da tabela na base de dados. Vamos analisar cada um dos campos disponíveis para preenchimento: ■ ■ ■ Campo: Esse campo determina qual será o nome da coluna dentro da base de dados. Por convenção, o nome de um campo deve conter parte do nome de sua tabela. No caso de tabelas começadas com S, normalmente do padrão, o campo deve começar com o segundo e terceiro caracteres do código da tabela, seguindo de underline (Ex.: A1_ para campos da SA1). Para tabelas customizadas (como é nosso caso) o campo deve começar com o código da tabela, seguindo de underline (Ex: ZZZ_ para campos da tabela ZZZ); Tipo: Descreve qual o tipo de dado que será armazenado nesse campo (Caracter, Númerico, Lógico, Data, Memo); Tamanho e Decimal: Esse campo serve para limitar o tamanho do campo que será criado. Para o caso de campos numéricos, o campo Decimal informa quantas posições serão utilizadas depois da ■ ■ ■ ■ ■ vírgula; Formato: Esse campo determina qual a máscara que será utilizada para o preenchimento do campo. A máscara funciona como uma validação de quais caracteres serão aceitos no preenchimento dos campos. Para preencher esse campo, é necessário que o usuário se familiarize com alguns padrões de que determinam quais os caracteres aceitos, chamados de wildcards (Ex: @! para campos de texto e @E 9..9,99 para campos númericos); Contexto: Define se o campo que estamos criando será um campo físico dentro da base de dados ou somente uma estrutura virtual dentro do dicionário. Essa informação é muito importante e gera muita confusão em desenvolvedores iniciantes. Um campo virtual, embora esteja presente para que o usuário o edite, não será salvo na base de dados, uma vez que não existe uma coluna pra ele na tabela. Seu propósito é de ser um facilitador para rotinas de preenchimento ou visualização de informações durante a manutenção do registro; Propriedade: Determina se o campo poderá ser editado pelos usuários ou somente visualizado. Campos visuais ficam desabilitados enquanto o usuário estiver realizando a manutenção no registro; Título, Tit. Espanhol, Tit. Inglês: Campos utilizados para colocar o nome do campo para o usuário. Como o sistema trabalha com um sistema de 3 idiomas, existem campos para cada um deles; Descrição, Des. Espanhol e Des. Inglês: Esses campos são um nível mais detalhado da descrição ■ ■ ■ ■ ■ ■ do campo, permitindo o preenchimento de mais caracteres; Help: O campo de Help é uma descrição completa da funcionalidade do campo. Seu conteúdo é exibido quando o usuário está posicionado dentro da edição do campo e aperta F1 (Ajuda); Lista Opções, Lista Espanhol, Lista Inglês: Os campos de Lista são utilizados para campos que serão representados visualmente por um objeto de seleção do tipo ComboBox. Nesse campo é possível determinar a listagem de opções seguindo esse padrão: X=Descrição da Opção;Y=Descrição da Outra Opção. X e Y representam os valores possíveis para o campo, após de cada sinal de = fica a descrição da opção e cada opção é separada por ponto-e-vírgula; Inic. Padrão: Essa informação determina qual o valor inicial (quando um novo registro é gerado) para o campo. Aqui podem ser utilizadas também funções, onde o retorno da função será o valor inicial do campo. É muito importante sempre tomar atenção para que o valor inicial do campo seja condizente com o tipo de informação que ele pode armazenar; Inic. Browse: Determina qual será o valor exibido para esse campo em listagens de registros, como MBrowse, MarkBrowses e outros. Caso não seja preenchido, o valor real do campo (para campos reais da base de dados, não virtuais) será exibido; Modo Edição: Define uma condição booleana (.T. ou .F.) para que este campo esteja habilitado para edição. Caso não preenchido, o campo estará disponível para edição (no caso de inclusões ou alterações no registro); Cons. Padrão: Define qual será a consulta utilizada para esse campo. Uma consulta padrão é uma forma de listar registros de outra tabela para o usuário, facilitando o seu preenchimento (pode ser acessada através da tecla de atalho F3). É utilizada em campos que determinam uma chave estrangeira dentro da tabela. Para todos os outros casos, não é obrigatório preencher essa informação; ■ ■ Val. Usuário, Val. Sistema: Determinam regras de validação para que o preenchimento desse campo seja válido. Essas regras devem ser expressas através de expressões de programação que dêem um retorno booleano (.T. a informação é válida, .F. a informação não é válida e o usuário retorna fica “preso” no campo até corrigir). Ex.: Positivo() —-> para verificar se o preenchimento de um campo numérico é um número positivo; Nível: Define qual o nível de usuário necessário para visualizar e editar esse campo; ■ ■ ■ Obrigatório: Esse checkbox determina se o preenchimento do campo é obrigatório; Usado: Esse checkbox determina se esse campo está em uso pela regra de negócio do sistema. Caso o campo venha a se tornar obsoleto e o responsável não queira excluí-lo (para não perder informaçõe históricas talvez), é possível simplesmente desmarcar essa opção e desativá-lo; Browse: Esse checkbox define se esse campo será exibido em listagens de registros dessa tabela, como MBrowse ou MarkBrowse, por exemplo; ■ Módulos: Determina em quais módulos do sistema esse campo será utilizado. Normalmente, não é necessário alterar esse tipo de controle de acesso Como iremos criar alguns campos para essa tabela, vou listar as informações de preenchimento dos campos (após preencher os campos corretamente, clique em Confirmar e depois em Incluir para criar o novo campo): Campo: ZZZ_USER Tipo: Caracter Tamanho: 6 Formato: @! Contexto: Real Propriedade: Visualizar Inic Padrão: RetCodUsr() —–> essa função retorna o código do usuário que está logado no sistema no momento. Ou seja, caso o Administrador esteja utilizando o sistema, a função irá pegar o código “000000” e colocar como valor padrão desse campo; Obrigatório, Usado e Browse Campo: ZZZ_NOMUSR Tipo: Caracter Tamanho: 60 Formato: @! Contexto: Virtual —–> esse é um ótimo exemplo de campo virtual. Como o objetivo do campo é exibir o nome do usuário e não alterá-lo, não existe motivos para ter essa informação duplicada nessa tabela dentro da base de dados. Pensando em normalização da nossa base de dados, como essa informação virá de uma outra tabela e é armazenada lá, esse campo não deve ser real dentro da base de dados e sim somente um facilitador para o usuário; Propriedade: Vizualizar —–> novamente, igual ao comentário anterior. Como não há motivos para o usuário alterar essa informação, esse campo pode ser somente visual; Inic Padrão: USRFULLNAME(RETCODUSR()) —–> Esse é um ótimo exemplo de encadeamento de funções. A função USRFULLNAME() retorna o nome completo do usuário passado como parâmetro e a função RETCODUSR(), como já vimos, retorna o código do usuário autenticado no sistema. Assim, o valor inicial desse campo é o nome do usuário autenticado no momento; Inic.Browse: USRFULLNAME(ZZZ->ZZZ_USER) —–> Quando o usuário visualizar uma listagem de registros da tabela ZZZ, é interessante que ele veja o nome completo do usuário e não somente o seu código. Para isso, temos que preencher o Inicializador de Browse. O contéudo é igual ao inicializador padrão, exceto que ao invés de passarmos o código do usuário autenticado no momento, vamos passar o campo ZZZ_USER (imagine que diversos usuários cadastraram registros na tabela e você, depois disso, irá visualizar esses registros. Você irá ver o nome de cada um desses usuários e não o seu nome diversas vezes :p ) Usado e Browse Campo: ZZZ_NUMERO Tipo: Numérico Tamanho: 9 Decimal: 2 Formato: @E 999,999.99 —-> perceba que a contagem do tamanho – 9 – leva em consideração o ponto separador e os 2 dígitos decimais. A vírgula funciona como um separador estético e, portanto, não entra na contagem de tamanho Contexto: Real Propriedade: Alterar Val. Usuário: POSITIVO() Obrigatório, Usado e Browse Conclusão Vamos fazer uma pausa por enquanto para que você possa assimilar e testar cada uma dessas opções. Nos próximos artigos, vamos falar sobre a criação de índices, gatilhos, efetivação das alterações dentro da base de dados, agendamento dessa efetivação, criação de um cadastro simples para essa tabela e como visualizar a estrutura dessa tabela diretamente dentro do dicionário de dados. Abraços e até lá. Dicas de utilização da APSDU / MPSDU. Neste artigo iremos mostrar algumas funcionalidades e emprega-las em necessidades reais do nosso dia-a-dia. Apesar de simples, são dicas que nos poupam bastante tempo na hora de efetuar alguma manutenção direto na ferramenta APSDU / MPSDU. Situação 1 Podemos ver na imagem abaixo que todas as tabelas estão apontando para empresa 99, e precisamos replicar este arquivo SX2 para outra empresa, a empresa 02 por exemplo. Solução: Vá até a pasta system, no caminho Protheus_Data>System, faça uma copia do arquivo SX2990.DBF, e renomeie a cópia para SX2020.DBF. Abra o arquivo que acabou de criar, em nosso exemplo foi o arquivo SX2020.dbf. Faça um backup antes de prosseguir, e utilize a função PADR para alterar apenas nos 3 ultimos dígitos do campo X2_ARQUIVO. (Atalho para Replace no APSDU, Ctrl+R) PADR(<Campo que deseja alterar>,<Posição que deseja manter>)+<”conteúdo que deseja completar até o tamanho do campo”> Em nosso exemplo ficou assim. PADR(X2_ARQUIVO,3)+”020” Obs. Esta orientação também se aplica para a função PADL, que é diferenciada apenas pela referencia do campo estar a Esquerda, e PADR estar a Direita. [optinform] Registros alterados com Sucesso… Situação 2 Na maioria das empresas existem mais de uma empresa cadastrada no sistema. E é de costume fazer com que a Matriz tenha os cadastros base, e as demais empresas do grupo aponte suas tabelas para Matriz. Tais como cadastros de Produtos, Clientes, Fornecedores, Naturezas, Condições de Pagamento, entre outros. Abaixo mostraremos uma forma rápida de localizar quais tabelas estão sendo apontadas para outra empresa. Ainda no registro SX2, clique em Filtro (tecla de atalho Ctrl+F no APSDU / MPSDU) Clique no botão Expressão. Utilizaremos a função SUBSTR para localizar as tabelas que estão sendo apontadas para outra empresa. SUBSTR(<Campo que deseja alterar>,<Indica Posição inicial dentro do campo que deseja alterar>,<Posições a considerar a partir da posição inicial indicada no campo anterior>) Em nosso exemplo ficou da seguinte forma: SUBSTR(X2_ARQUIVO,4,2)<>”02” E aí está após a confirmação do filtro encontramos quais tabelas apontam pra outra empresa. Valeu Pessoal, até a próxima. X31UPDTABLE: Atualizar top via comando. Neste artigo iremos mostrar como criar campos no banco de dados via comando através da função X31UPDTABLE. Quem nunca passou pelo problema de ter que replicar um campo de uma empresa ou base para outra e não conseguir acesso exclusivo ao sistema para atualizar a base através do Configurador. Pensando em tal problema, iremos mostrar como podemos driblar esta dificuldade. A ideia é: incluir o campo direto no SX3, e atualizar o banco via comando através da rotina fórmulas. O comando é X31UPDTABLE(“ALIAS”) Lembre-se, que para que funcione este comando, a tabela que utilizar no “ALIAS” não pode estar aberta por nenhuma rotina. Vamos lá, em nosso exemplo incluiremos um campo na tabela de clientes (SA1). Abra o arquivo SX3 da empresa que deseja incluir o campo. Faça o Append do campo que precisa incluir na tabela. Dica: Atente-se para questão da ordem do campo. Caso a ordem do campo que está incluindo já esteja sendo utilizada por outro campo, altere para uma ordem do final que ainda não exista, e depois que rodar o comando e atualizar o banco, você pode alterar apenas a ordem através do Configurador, para alteração de ordem não é necessário acesso exclusivo. [optinform] A rotina Formulas está disponível em praticamente todos os módulos. Normalmente no caminho Atualizações>Cadastros>Formulas *Exemplo pelo modulo compras. Agora é só chamar a função no campo Formula e dar enter, assim os campos do banco de dados ficarão atualizados de acordo com que está no dicionário de dados SX3. Dica: Está funcionalidade ( X31UPDTABLE ) serve para incluir ou excluir campos. Recarregar a lista de tabelas do APSDU Olá pessoal, hoje vou dar uma dica rápida que acaba ajudando no dia a dia dos analistas. Geralmente quando “dropamos” uma tabela pelo APSDU, temos que sair do sistema e entrar novamente para que ela apareça na lista de tabelas. Para não ter que ficar saindo do APSDU e entrando novamente, podemos usar a tecla de atalho Ctrl+T, isso mesmo a tecla de importação de dados. A rotina de importação de tabelas atualiza o link de conexão entre o TotvsDbAccess e o Banco de dados. Veja abaixo o passo a passo. Vamos usar no exemplo a tabela CC2 (Cadastro de Municípios) Primeiro devemos abrir a tabela no APSDU. Em seguida fazemos o backup da tabela acessando as opções: Utilitário > Copiar Para ou pressione a tecla de atalho Ctrl+Y. Após realizar a copia da tabela, clicamos na opção de “DROP TABLE” que fica em Utilitário ou pressione a tecla de atalho Ctrl+D. Em seguida será apresentada a mensagem de confirmação. OBS: Atenção, não nos responsabilizamos por eventuais perdas de dados ou coisa do gênero. Ao confirmar, o sistema irá apagar a tabela do banco de dados. Para criá-la no banco de dados, temos que acessar alguma rotina que utilize a tabela. No nosso exemplo, acessamos o cadastro de clientes SA1. [optinform] Ao acessar o cadastro de clientes, o sistema recriou a tabela no banco de dados. Porém se estivermos com o APSDU aberto e tentar abrir a tabela, recebemos a mensagem dizendo que a não foi encontrado a tabela “CC2” (conforme imagem abaixo). Isso ocorre por que o link entre o TotvsDbAccess e o Banco de dados não foi atualizado. Como comentei no inicio do artigo, para que possamos abrir a tabela, normalmente temos que sair do APSDU e entrar novamente. Mas ai que vem a dica. Pressione a tecla de atalho “Ctrl+T”, essa combinação de teclas irá abrir a tela de importação de dados conforme imagem abaixo, em seguida clique em “Cancelar” somente para fechar a tela. OBS: Ao acessar a tela de importação de dados, o sistema refaz a conexão com o TotvsDbAccess e atualiza o link com o banco de dados. Agora vamos abrir a tabela no APSDU clicando na opção “Open” ou pressionando a tecla “CTRL+B”. Veja que a tabela passa a ser exibida na lista novamente. Em caso de duvidas deixem comentários. Espero ter ajudado !!!