Como ver o conteúdo dos campos LGI e LGA no SQL Server

Basta usar Substring e Convert que você consegue ver o resultado dos campos.


Para visualizar o usuário que incluiu ou alterou, você deve concatenar as seguintes posições: 03, 07, 11, 15, 19, 02, 06, 10, 14, 01, 18, 05, 09, 13, 17, 04, 08. Pois nas versões antigas do Protheus, era gravado o nome do usuário (por exemplo, “Daniel Atilio”), e a partir das versões mais novas, é gravado apenas o código (por exemplo, “000007”).

Para visualizar a data, você deve pegar a posição 12 e a 16, transformar em ascii tirando 50 caracteres e converter para data, pegando como início de corte 01/01/1996. Se for o campo de alteração, essa posição 12 além de tirar 50, você deve multiplicar por 100.

Abaixo o exemplo da query completa.

/* Exemplo atualizado conforme comentário do Jose Rogerio do Prado Junior */
SELECT 
    B1_COD,
    B1_DESC,
    B1_USERLGI, 
    B1_USERLGA,

    CASE WHEN SUBSTRING(B1_USERLGI, 03, 1) != ' ' AND B1_USERLGI != '' THEN
        CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGI,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGI,16,1)) - 50) + IIF(SUBSTRING(B1_USERLGI,08,1) = '<',10000,0)),'1996-01-01'), 103)
    ELSE 
        ''
    END AS DATA_INCL,

    CASE WHEN SUBSTRING(B1_USERLGA, 03, 1) != ' ' AND B1_USERLGA != '' THEN
        CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGA,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGA,16,1)) - 50) + IIF(SUBSTRING(B1_USERLGA,08,1) = '<',10000,0)),'1996-01-01'), 103)
    ELSE ''
    END AS DATA_ALT,

    LEFT(
        SUBSTRING(B1_USERLGI, 11, 1) +
        SUBSTRING(B1_USERLGI, 15, 1) +
        SUBSTRING(B1_USERLGI, 19, 1) +
        SUBSTRING(B1_USERLGI, 02, 1) +
        SUBSTRING(B1_USERLGI, 06, 1) +
        SUBSTRING(B1_USERLGI, 10, 1) +
        SUBSTRING(B1_USERLGI, 14, 1) +
        SUBSTRING(B1_USERLGI, 01, 1) +
        SUBSTRING(B1_USERLGI, 18, 1) +
        SUBSTRING(B1_USERLGI, 05, 1) +
        SUBSTRING(B1_USERLGI, 09, 1) +
        SUBSTRING(B1_USERLGI, 13, 1) +
        SUBSTRING(B1_USERLGI, 17, 1) +
        SUBSTRING(B1_USERLGI, 04, 1) +
        SUBSTRING(B1_USERLGI, 08, 1)
    , 6) AS USER_INCL,
    LEFT(
        SUBSTRING(B1_USERLGA, 11, 1) +
        SUBSTRING(B1_USERLGA, 15, 1) +
        SUBSTRING(B1_USERLGA, 19, 1) +
        SUBSTRING(B1_USERLGA, 02, 1) +
        SUBSTRING(B1_USERLGA, 06, 1) +
        SUBSTRING(B1_USERLGA, 10, 1) +
        SUBSTRING(B1_USERLGA, 14, 1) +
        SUBSTRING(B1_USERLGA, 01, 1) +
        SUBSTRING(B1_USERLGA, 18, 1) +
        SUBSTRING(B1_USERLGA, 05, 1) +
        SUBSTRING(B1_USERLGA, 09, 1) +
        SUBSTRING(B1_USERLGA, 13, 1) +
        SUBSTRING(B1_USERLGA, 17, 1) +
        SUBSTRING(B1_USERLGA, 04, 1) +
        SUBSTRING(B1_USERLGA, 08, 1)
    , 6) AS USER_ALTE
FROM 
    SB1990 SB1
WHERE
    B1_FILIAL = ' '
    AND B1_MSBLQL != '1'
    AND SB1.D_E_L_E_T_ = ' '

/* Exemplo original:
SELECT
    B1_COD,
    B1_USERLGI,
    B1_USERLGA,
   
    SUBSTRING(B1_USERLGI, 03, 1) +
    SUBSTRING(B1_USERLGI, 07, 1) +
    SUBSTRING(B1_USERLGI, 11, 1) +
    SUBSTRING(B1_USERLGI, 15, 1) +
    SUBSTRING(B1_USERLGI, 19, 1) +
    SUBSTRING(B1_USERLGI, 02, 1) +
    SUBSTRING(B1_USERLGI, 06, 1) +
    SUBSTRING(B1_USERLGI, 10, 1) +
    SUBSTRING(B1_USERLGI, 14, 1) +
    SUBSTRING(B1_USERLGI, 01, 1) +
    SUBSTRING(B1_USERLGI, 18, 1) +
    SUBSTRING(B1_USERLGI, 05, 1) +
    SUBSTRING(B1_USERLGI, 09, 1) +
    SUBSTRING(B1_USERLGI, 13, 1) +
    SUBSTRING(B1_USERLGI, 17, 1) +
    SUBSTRING(B1_USERLGI, 04, 1) +
    SUBSTRING(B1_USERLGI, 08, 1) AS USER_INC,
    CONVERT(VARCHAR(10),CAST(DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGI,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGI,16,1)) - 50)),'1996-01-01') AS DATETIME),103) AS DATA_INC,
   
    SUBSTRING(B1_USERLGA, 03, 1) +
    SUBSTRING(B1_USERLGA, 07, 1) +
    SUBSTRING(B1_USERLGA, 11, 1) +
    SUBSTRING(B1_USERLGA, 15, 1) +
    SUBSTRING(B1_USERLGA, 19, 1) +
    SUBSTRING(B1_USERLGA, 02, 1) +
    SUBSTRING(B1_USERLGA, 06, 1) +
    SUBSTRING(B1_USERLGA, 10, 1) +
    SUBSTRING(B1_USERLGA, 14, 1) +
    SUBSTRING(B1_USERLGA, 01, 1) +
    SUBSTRING(B1_USERLGA, 18, 1) +
    SUBSTRING(B1_USERLGA, 05, 1) +
    SUBSTRING(B1_USERLGA, 09, 1) +
    SUBSTRING(B1_USERLGA, 13, 1) +
    SUBSTRING(B1_USERLGA, 17, 1) +
    SUBSTRING(B1_USERLGA, 04, 1) +
    SUBSTRING(B1_USERLGA, 08, 1) AS USER_ALT,
    CASE WHEN SUBSTRING(B1_USERLGA, 03, 1) != ' ' THEN
        CONVERT(VARCHAR,DATEADD(DAY,((ASCII(SUBSTRING(B1_USERLGA,12,1)) - 50) * 100 + (ASCII(SUBSTRING(B1_USERLGA,16,1)) - 50)),'19960101'),112)
    ELSE ''
    END AS DATA_ALT
FROM
    SB1010 SB1
WHERE
    B1_USERLGI != ' '
*/

Para criar esse artigo, usei como base 2 exemplos na internet, o do site Universo AdvPL e o do Mundo AdvPL, vale a pena conferir o conteúdo deles.

Update 14/06/2021:

Abaixo uma query, para quem tem o dicionário no banco, onde é possível fazer o relacionamento com a tabela SYS_USR:

/* Exemplo atualizado conforme comentário do Jose Rogerio do Prado Junior: */
SELECT 
    B1_COD,
    B1_DESC,
    B1_USERLGI, 
    B1_USERLGA,

    USR_I.USR_ID AS USRINC_COD,
    USR_I.USR_NOME AS USRINC_NOM,
    CASE WHEN SUBSTRING(B1_USERLGI, 03, 1) != ' ' AND B1_USERLGI != '' THEN
        CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGI,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGI,16,1)) - 50) + IIF(SUBSTRING(B1_USERLGI,08,1) = '<',10000,0)),'1996-01-01'), 103)
    ELSE 
        ''
    END AS DATA_INCL,

    USR_A.USR_ID AS USRALT_COD,
    USR_A.USR_NOME AS USRALT_NOM,
    CASE WHEN SUBSTRING(B1_USERLGA, 03, 1) != ' ' AND B1_USERLGA != '' THEN
        CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGA,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGA,16,1)) - 50) + IIF(SUBSTRING(B1_USERLGA,08,1) = '<',10000,0)),'1996-01-01'), 103)
    ELSE ''
    END AS DATA_ALT
FROM 
    SB1990 SB1
    LEFT JOIN SYS_USR USR_I ON (
        USR_I.USR_ID = LEFT(
            SUBSTRING(B1_USERLGI, 11, 1) +
            SUBSTRING(B1_USERLGI, 15, 1) +
            SUBSTRING(B1_USERLGI, 19, 1) +
            SUBSTRING(B1_USERLGI, 02, 1) +
            SUBSTRING(B1_USERLGI, 06, 1) +
            SUBSTRING(B1_USERLGI, 10, 1) +
            SUBSTRING(B1_USERLGI, 14, 1) +
            SUBSTRING(B1_USERLGI, 01, 1) +
            SUBSTRING(B1_USERLGI, 18, 1) +
            SUBSTRING(B1_USERLGI, 05, 1) +
            SUBSTRING(B1_USERLGI, 09, 1) +
            SUBSTRING(B1_USERLGI, 13, 1) +
            SUBSTRING(B1_USERLGI, 17, 1) +
            SUBSTRING(B1_USERLGI, 04, 1) +
            SUBSTRING(B1_USERLGI, 08, 1)
        , 6)
    )
    LEFT JOIN SYS_USR USR_A ON (
        USR_A.USR_ID = LEFT(
            SUBSTRING(B1_USERLGA, 11, 1) +
            SUBSTRING(B1_USERLGA, 15, 1) +
            SUBSTRING(B1_USERLGA, 19, 1) +
            SUBSTRING(B1_USERLGA, 02, 1) +
            SUBSTRING(B1_USERLGA, 06, 1) +
            SUBSTRING(B1_USERLGA, 10, 1) +
            SUBSTRING(B1_USERLGA, 14, 1) +
            SUBSTRING(B1_USERLGA, 01, 1) +
            SUBSTRING(B1_USERLGA, 18, 1) +
            SUBSTRING(B1_USERLGA, 05, 1) +
            SUBSTRING(B1_USERLGA, 09, 1) +
            SUBSTRING(B1_USERLGA, 13, 1) +
            SUBSTRING(B1_USERLGA, 17, 1) +
            SUBSTRING(B1_USERLGA, 04, 1) +
            SUBSTRING(B1_USERLGA, 08, 1)
        , 6)
    )
WHERE
    B1_FILIAL = ' '
    AND B1_MSBLQL != '1'
    AND SB1.D_E_L_E_T_ = ' '

/* Query original: 
SELECT
    B1_COD,
    B1_DESC,
    B1_TIPO,
      
    USR_I.USR_ID AS USRINC_COD,
    USR_I.USR_NOME AS USRINC_NOM,
    CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGI,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGI,16,1)) - 50)),'1996-01-01'), 112) AS DATA_INC,
    
    USR_A.USR_ID AS USRALT_COD,
    USR_A.USR_NOME AS USRALT_NOM,
    CASE WHEN SUBSTRING(B1_USERLGA, 03, 1) != ' ' THEN
        CONVERT(VARCHAR,DATEADD(DAY,((ASCII(SUBSTRING(B1_USERLGA,12,1)) - 50) * 100 + (ASCII(SUBSTRING(B1_USERLGA,16,1)) - 50)),'19960101'),112)
    ELSE ''
    END AS DATA_ALT
FROM
    SB1990 SB1
    LEFT JOIN SYS_USR USR_I ON (
        USR_I.USR_ID = (
            SUBSTRING(B1_USERLGI, 11, 1) +
            SUBSTRING(B1_USERLGI, 15, 1) +
            SUBSTRING(B1_USERLGI, 19, 1) +
            SUBSTRING(B1_USERLGI, 02, 1) +
            SUBSTRING(B1_USERLGI, 06, 1) +
            SUBSTRING(B1_USERLGI, 10, 1) +
            SUBSTRING(B1_USERLGI, 14, 1) +
            SUBSTRING(B1_USERLGI, 01, 1) +
            SUBSTRING(B1_USERLGI, 18, 1) +
            SUBSTRING(B1_USERLGI, 05, 1) +
            SUBSTRING(B1_USERLGI, 09, 1) +
            SUBSTRING(B1_USERLGI, 13, 1) +
            SUBSTRING(B1_USERLGI, 17, 1) +
            SUBSTRING(B1_USERLGI, 04, 1) +
            SUBSTRING(B1_USERLGI, 08, 1)
        )
    )
    LEFT JOIN SYS_USR USR_A ON (
        USR_A.USR_ID = (
            SUBSTRING(B1_USERLGA, 11, 1) +
            SUBSTRING(B1_USERLGA, 15, 1) +
            SUBSTRING(B1_USERLGA, 19, 1) +
            SUBSTRING(B1_USERLGA, 02, 1) +
            SUBSTRING(B1_USERLGA, 06, 1) +
            SUBSTRING(B1_USERLGA, 10, 1) +
            SUBSTRING(B1_USERLGA, 14, 1) +
            SUBSTRING(B1_USERLGA, 01, 1) +
            SUBSTRING(B1_USERLGA, 18, 1) +
            SUBSTRING(B1_USERLGA, 05, 1) +
            SUBSTRING(B1_USERLGA, 09, 1) +
            SUBSTRING(B1_USERLGA, 13, 1) +
            SUBSTRING(B1_USERLGA, 17, 1) +
            SUBSTRING(B1_USERLGA, 04, 1) +
            SUBSTRING(B1_USERLGA, 08, 1)
        )
    )
WHERE
    B1_FILIAL = ''
    AND B1_MSBLQL != '1'
    AND SB1.D_E_L_E_T_ = ' '
*/

Exemplo de resultado com join na SYS_USR

Update Agosto de 2023:

Pessoal, recentemente no nosso grupo do WhatsApp, um dos alunos disse que o bug de não gravar corretamente foi corrigido na lib mais nova. Abaixo os links que foram compartilhados:

Pessoal, também atualizei as queries acima, conforme o exemplo que o Jose Rogerio do Prado Junior enviou nos comentários.

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

34 Responses

  1. Jorge Orlando disse:

    Eu sempre me perguntei em como ler essa informação. Obrigado por compartilhar

  2. Armando Neto disse:

    Muito bom. Valeu Atílio.

  3. ciro bizelli disse:

    E ai Dan Atilio! Beleza?

    Parabéns pelo seu site, em 2014, aprendi programar em ADVPL com suas vídeo aulas. ^^

    Só compartilhando, eu uso o mesmo esquema porém em funções no SQL, segue sintaxe;

    CREATE FUNCTION USERLGCOD(@CONTEUDO CHAR(17))
    –@EXAMPLE USERLGCOD(E2_USERLGI)
    RETURNS CHAR(6)
    AS
    BEGIN
    DECLARE @RETORNO VARCHAR(6)
    SET @RETORNO = SUBSTRING(@CONTEUDO, 11,1)+SUBSTRING(@CONTEUDO, 15,1)+
    SUBSTRING(@CONTEUDO, 2, 1)+SUBSTRING(@CONTEUDO, 6, 1)+
    SUBSTRING(@CONTEUDO, 10,1)+SUBSTRING(@CONTEUDO, 14,1)+
    SUBSTRING(@CONTEUDO, 1, 1)+SUBSTRING(@CONTEUDO, 5, 1)+
    SUBSTRING(@CONTEUDO, 9, 1)+SUBSTRING(@CONTEUDO, 13,1)+
    SUBSTRING(@CONTEUDO, 17,1)+SUBSTRING(@CONTEUDO, 4, 1)+
    SUBSTRING(@CONTEUDO, 8, 1)
    RETURN @RETORNO
    END

    CREATE FUNCTION USERLGDATA(@CONTEUDO CHAR(17))
    –@EXAMPLE USERLGDATA(E2_USERLGI)
    RETURNS CHAR(10)
    AS
    BEGIN
    DECLARE @DATA CHAR(8)
    DECLARE @RETORNO VARCHAR(10)
    SET @DATA = CONVERT(VARCHAR,DATEADD(DAY,((ASCII(SUBSTRING(@CONTEUDO,12,1)) – 50) * 100 + (ASCII(SUBSTRING(@CONTEUDO,16,1)) – 50)),’19960101′),112)
    SET @RETORNO = CONVERT(VARCHAR(10), CONVERT(DATE,@DATA,101), 103)
    RETURN @RETORNO
    END

  4. Roberto disse:

    Boa tarde, gostaria de saber o porque do 112 no convert?

  5. ARLINDO JUNIOR DE BARCELOS PELISSARI disse:

    Parou de funcionar depois do dia 15/05/2023

    • Boa tarde Arlindo, tudo joia?
      Que estranho, pode ter sido alguma atualização de LIB. Ainda não tenho nenhum cliente com a base mais atualizada para realizar os testes.
      Se você conseguir algo, nos envie para atualizarmos o artigo.
      Um grande abraço.

      • ARLINDO disse:

        Aqui estou usando assim, não tive mais problemas

        CREATE FUNCTION [dbo].[DTUSERLG](@USERLG varchar(20))
        RETURNS VARCHAR(100)
        AS
        BEGIN
        –DECLARE @USERLG VARCHAR(25)=’ 0# 1@< 203 503 '
        DECLARE @cDTUSERLG VARCHAR(15)
        /*

        DATA DE ALTERAÇÃO

        */

        IF TRIM(@USERLG)”
        BEGIN
        SET @cDTUSERLG = ISNULL(
        TRY_CONVERT(
        VARCHAR(10),CAST(DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(@USERLG,12,1)) – 50, ASCII(SUBSTRING(@USERLG,16,1)) – 50))+IIF(ASCII(SUBSTRING(@USERLG, 08, 1))>=60,ASCII(SUBSTRING(@USERLG, 08, 1))*166.669,0),’1996-01-01′) AS DATETIME)
        ,120),’19960101′
        )
        END

        IF TRIM(@USERLG)=”
        BEGIN

        SET @cDTUSERLG = ‘19960101’

        END

        RETURN( ISNULL(CAST(@cDTUSERLG AS DATE),CAST(‘19960101’ AS DATE)) )

        END

  6. Rafael Ogeda disse:

    Boa tarde

  7. Rafael Ogeda disse:

    Boa tarde
    Verificamos que a gravação do LGI LGA “bugou” a partir de 18/05/23, e abrimos o chamado 17110139 na TOTVS que gerou a ISSUE DFRM1-32574. Eles corrigiram a gravação do LGI LGA, mas a partir da correção é como se a contagem de dias obtida a partir do SUBSTR e dos caracteres ASCII tivesse zerado a partir de 18/05/23. Então o SELECT SQL no LGI LGA agora retorna para registros atuais como se fossem dias após 01/01/1996… Pelo que constatamos esta solução LGI LGA criada pela Microsiga MS.DOS tem uma validade de 27,33 anos, e agora “expirou” e começou do zero novamente… ou alguma loucura assim.
    Tentamos uma “gambiarra” no SELECT mas não funcionou muito bem: fizemos um CASE para se (ASCII(SUBSTRING(A1.A1_USERLGI,12,1))-50) > 50 usar ‘20230519’, senão usar ‘19960101’. Funciona parcialmente, pois para registros anteriores a 2010 dá ruim…

    (CASE WHEN (ASCII(SUBSTRING(A1.A1_USERLGI,12,1))-50) > 50 THEN CONVERT(VARCHAR,DATEADD(DAY,((ASCII(SUBSTRING(A1.A1_USERLGI,12,1))-50)*100+(ASCII(SUBSTRING(A1.A1_USERLGI,16,1))-50)),’19960101′),112)
    ELSE CONVERT(VARCHAR,DATEADD(DAY,((ASCII(SUBSTRING(A1.A1_USERLGI,12,1))-50)*100+(ASCII(SUBSTRING(A1.A1_USERLGI,16,1))-50)),’20230519′),112)
    END) AS DATELGI

    Portanto ainda estamos com problema em manipular LGI LGA via SELECT SQL após este “bug” recente.

    TOTVS: A Release Oficial foi expedida e publicada na Central de Downloads.
    – O pacote pode ser acessado no endereço: Ambiente Lobo https://suporte.totvs.com/portal/p/10098/download?e=989259 – Ambiente Harpia https://suporte.totvs.com/portal/p/10098/download#detail/1050526
    – Para acessar a documentação da solicitação acesse o link: https://tdn.totvs.com/pages/viewpage.action?pageId=762724211

    Será que alguém tem alguma ideia de como contornar este “zeramento” no LGI LGA?

  8. Rafael Hernandes Ogeda disse:

    Boa tarde

    Passados 10 dias do “bug” com o contador que voltou de 9999 para 0, nesta semana tivemos mais uma divergência para o LGA e o cálculo de *100. Parece que a partir da mudança gerada pela ISSUE DFRM1-32574, além do caracter 8 agora estar preenchido, parece que tanto LGI quanto LGA estão agora usando a regra do CONCAT ao invés da soma.

    Fizemos algumas descobertas empíricas aqui sobre a mudança no LGI LGA.
    • Entre 01/01/1996 e 18/05/2023 temos um intervalo de 9999 dias. Quando este limite estourou o PROTHEUS passou a gravar incorretamente LGI LGA, voltando o caracter ASCII da posição 12 a 50 e reiniciando este contador. Com isto o Log de Registros em 23/05/23 apareciam no Log de Registros como 05/01/1996.
    • Ambos os caracteres 12 e 16 recebem caracteres ASCII variando de 50 a 149 (2 a ò). Para fechar as 9999 contagens de dias (XXYY), caracter 12 guarda milhares e centenas (XX), caracter 16 guarda dezenas e unidades (YY). O caracter 16 incrementa a cada dia e reinicia após 99, caracter 12 incrementa a cada 100 dias.
    • Pelo que identificamos, após o patch da Issue , houve mudança na gravação da posição 8: antes do patch era vazia (ASCII=32) e agora está preenchida com “<” (ASC2=60). A TOTVS não deu mais detalhes do ajuste realizado, mas acreditamos que tenham também modificado a CFGX025 na exibição das datas.
    • A regra de multiplicar por 100 o caracter 12 não está funcionando nesta nova sequência do contador de dias do LGA: para termos o resultado correto para 30/05/23 multiplicamos por 10 e não por 100. O caracter 16 quando chegou em 59 não continuou até 149 mas voltou para 50 e incrementou o caracter 12 de 50 para 51 (somente deveria ter feito isto após 100 dias transcorridos, e fez em 10 dias transcorridos). Então parece que também mudaram a gravação dos caracteres 12 e 16, e após ajuste TOTVS o caracter 16 passou a reinciar após 9, e assim caracter 12 incremente a cada 10 dias. Pelo teste realizado com 30 e 31/05/23 se for usada a regra do LGI para o LGA dá certo.
    Conclusão: entendemos que se o caracter 8 estiver preenchido deve-se somar os dias calculados a 19/05/2023 ao invés de 01/01/1996 (ou somar mais 10000 dias aos dias calculados) + deve-se usar a mesma regra do LGI para ambos (com CONCAT ao invés de somar).

    Regra anterior:
    – LGI: 19960101 + INT(CONCAT({LGI_12}-50,{LGI_16}-50))
    – LGA: 19960101 + ({LGA_12}-50)*100 + {LGA_16}-50

    Nova regra a partir de 19/05/23 (ou após patch de 23/05/23):
    – LGI, se LGI_3 não vazio: 19960101 + INT(CONCAT({LGI_12}-50,{LGI_16}-50)) se LGA_8 vazio, senão 20230519 + INT(CONCAT({LGI_12}-50,{LGI_16}-50))
    – LGA, se LGI_3 não vazio: 19960101 + ({LGA_12}-50)*100 + {LGA_16}-50 se LGA_8 vazio, senão 20230519 + INT(CONCAT({LGA_12}-50,{LGA_16}-50))

    De qualquer modo, decidimos abandar LGI e LGA (muitas incertezas…) e estudar o uso dos campos S_T_A_M_P_ e I_N_S_D_T_ recomendados pelo @Daniel. Obrigado @Daniel pela dica.

  9. Alexandre disse:

    Olá, essa solução (S_T_A_M_P_ e I_N_S_D_T_ ), serve para 12.1.33, sem dicionário no banco?

    • Bom dia Alexandre, tudo joia?

      Sem dicionário no banco, não realizamos testes, mas como é algo direto no DBAccess eu acho que é para funcionar sim (no TDN cita apenas que o DBAccess tem que ser acima do 19.2.1.0).

      Abraços.

  10. Alexandre disse:

    Bom dia Daniel, tudo bem e você?

    Apliquei aqui no meu DBAccess (S_T_A_M_P_ e I_N_S_D_T_ ), porém não funcionou, uma pena.

    Tenho relatórios e integrações que uso esses campos LGI e LGA e estão todos com problema….

    Abraços.

    • Bom dia Alexandre, estou bem graças a Deus e você?

      Não funcionou, você diz de não gravar, ou de não criar os campos? Após você aplicar, você fez um backup, dropou a tabela, deixou o sistema recriar com os campos novos e fez o append dos dados?

  11. Alexandre disse:

    Olá, tudo bem também.

    Ele não cria os campos, é necessário dropar a tabela e acessar a rotina para criação da tabela novamente?

    Achei que criaria os campos sem dropar a tabela.

  12. Paulo disse:

    Utilizava o seguinte código para trazer usuário e data num relatório. Como ficaria após a mudança do dia 15?

    _cCampo :=”_aQry->E2_USERLGI”
    _cUserLG :=Embaralha(&_cCampo,1)

    _cUsuarioI:=If (!Empty(_cUserLg),Subs(_cUserLg,1,15),””)
    If !Empty(_cUsuarioI)
    PswOrder(2)
    _lAchou := PswSeek(_cUsuarioI,.T.) // Pesquiso por Usuário
    If _lAchou = .F.
    _cUsuarioI:=If (!Empty(_cUserLg),Subs(_cUserLg,3,6),””)
    PswOrder(1) // Ordem de código
    If PswSeek(_cUsuarioI,.T.)
    _aRetUser := PswRet(1)
    _cUsuarioI:= alltrim(_aRetUser[1,2])
    EndIf
    Endif
    Endif

    _cDataI :=IIF(!Empty(_cUserLg),CTOD(“01/01/96″,”DDMMYY”) + Load2in4(Substr(_cUserLg,16)),””)

  13. Jose Rogerio do Prado Junior disse:

    Houve alteração no tamanho dos campos LGI E LGA a partir de 19/05/2023 – Precisam baixar a Lib para atualização. Depois, podem usar como exemplo a consulta a abaixo. Antes e depois de 19/05/2023.

    SELECT C7_EMISSAO,
    CASE WHEN SUBSTRING(C7_USERLGI, 03, 1) != ‘ ‘ THEN

    IIF(C7_USERLGI = ”,”,CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(C7_USERLGI,12,1)) – 50, ASCII(SUBSTRING(C7_USERLGI,16,1)) – 50) + IIF(SUBSTRING(C7_USERLGI,08,1) = ‘<',10000,0)),'1996-01-01'), 103))

    ELSE ''
    END AS [Data Inclusão],
    CASE WHEN SUBSTRING(C7_USERLGA, 03, 1) != ' ' THEN

    IIF(C7_USERLGA = '','',CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(C7_USERLGA,12,1)) – 50, ASCII(SUBSTRING(C7_USERLGA,16,1)) – 50) + IIF(SUBSTRING(C7_USERLGA,08,1) = '<',10000,0)),'1996-01-01'), 103))

    ELSE ''
    END AS [Data Alteracao],
    —usar um case para pegar datas anterior a 19/05/202
    –CONVERT(DATE,DATEADD(DAY,((ASCII(SUBSTRING(C7_USERLGA,12,1)) – 50) * 100 + (ASCII(SUBSTRING(C7_USERLGA,16,1)) – 50)),'19960101')) AS ALTERACAO2,

    C7_FILIAL AS FILIAL, C7_NUM AS CONTRATO, C1.R_E_C_N_O_ AS REGISTRO,
    SUBSTRING(C7_USERLGA, 3, 1) + SUBSTRING(C7_USERLGA, 7, 1) +
    SUBSTRING(C7_USERLGA, 11, 1) + SUBSTRING(C7_USERLGA, 15, 1) +
    SUBSTRING(C7_USERLGA, 2, 1) + SUBSTRING(C7_USERLGA, 6, 1) +
    SUBSTRING(C7_USERLGA, 10, 1) + SUBSTRING(C7_USERLGA, 14, 1) +
    SUBSTRING(C7_USERLGA, 1, 1) + SUBSTRING(C7_USERLGA, 5, 1) +
    SUBSTRING(C7_USERLGA, 9, 1) + SUBSTRING(C7_USERLGA, 13, 1) +
    SUBSTRING(C7_USERLGA, 17, 1) + SUBSTRING(C7_USERLGA, 4, 1) +
    SUBSTRING(C7_USERLGA, 8, 1) AS USUARIO_ALTEROU, B.USR_NOME
    FROM SC7010 C1
    INNER JOIN SYS_USR B ON B.USR_ID = SUBSTRING(SUBSTRING(C7_USERLGA, 3, 1) + SUBSTRING(C7_USERLGA, 7, 1) +
    SUBSTRING(C7_USERLGA, 11, 1) + SUBSTRING(C7_USERLGA, 15, 1) +
    SUBSTRING(C7_USERLGA, 2, 1) + SUBSTRING(C7_USERLGA, 6, 1) +
    SUBSTRING(C7_USERLGA, 10, 1) + SUBSTRING(C7_USERLGA, 14, 1) +
    SUBSTRING(C7_USERLGA, 1, 1) + SUBSTRING(C7_USERLGA, 5, 1) +
    SUBSTRING(C7_USERLGA, 9, 1) + SUBSTRING(C7_USERLGA, 13, 1) +
    SUBSTRING(C7_USERLGA, 17, 1) + SUBSTRING(C7_USERLGA, 4, 1) +
    SUBSTRING(C7_USERLGA, 8, 1),3,6)
    WHERE
    C7_FILIAL = '01MG0001'
    AND C7_NUM = '262990'
    AND C1.D_E_L_E_T_ = '*'
    ORDER BY C7_FILIAL, C7_NUM

  14. Filipe Nanclarez disse:

    Com relação aos campos novos do DBAccess, tomem cuidado porque eles registram operações do DBAccess não do usuário. Então se você precisar restaurar um backup via append do APSDU, ele vai atualizar esses campos com a data do restore MESMO QUE ELES JÁ ESTEJAM PREENCHIDOS. Inclusive o campo de inclusão!

    Então dependendo do objetivo, esses campos novos podem não atender a necessidade.

    No meu caso aqui, essa última versão do Jose Rogério funcionou na 2210.

  15. Johnny Cleiton Camargo dos Santos disse:

    Olá meu amigo sabe como ficou essa nova consulta para as ultimas libs ? porqque já não funciona mais retorna data incorreta

  16. Johnny Cleiton Camargo dos Santos disse:

    Daniel consegue fazer a nova query funcional ai para os registros com data posterior a 19/05/2023 ? vi o pessoal comentando tudo ai maneira da nova query mas já tentei tudo que é jeito com os exemplos do comentarios e nada agradeço se puder.

  17. Paulo Lana disse:

    Pessoal, o Protheus tem uma função para retornar o usuário e data da inclusão/alteração do registro. Trata-se da função FwLeUserLg.
    Link: https://tdn.totvs.com.br/pages/releaseview.action?pageId=6814934

Deixe uma resposta

Terminal de Informação