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_ = ' ' */
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:
- Central de Atendimento TOTVS – Campos _USERLGI e _USERLGA Gravando com ano de 1996
- Portal do Cliente – Download da LIB
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.
Eu sempre me perguntei em como ler essa informação. Obrigado por compartilhar
Opa, obrigado pelo comentário Jorge.
Grande abraço.
Muito bom. Valeu Atílio.
Opa, obrigado pelo comentário Armando.
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
Opa, obrigado pela contribuição Ciro.
Grande abraço jovem.
Boa tarde, gostaria de saber o porque do 112 no convert?
Bom dia Roberto, tudo bem?
O 112 é o padrão ISO (YYYYMMDD) que é o que o Protheus trabalha, nesse link da Microsoft tem a listagem (veja a partir de Estilos de data e hora): https://learn.microsoft.com/pt-br/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16
Abraços.
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.
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
Bom dia Arlindo, tudo joia?
Opa, muito obrigado pelo comentário e pelo exemplo fornecido.
Com toda a certeza vai ajudar a comunidade.
Um grande abraço.
Boa tarde
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?
Boa noite Rafael.
Opa, obrigado pelo adendo e explicações.
Por enquanto se for o caso, tente usar os campos S_T_A_M_P_ e I_N_S_D_T_ – https://terminaldeinformacao.com/2023/01/25/para-que-serve-os-novos-campos-s_t_a_m_p_-e-i_n_s_d_t_-e-como-utiliza-los-no-protheus/
Se alguém compartilhar uma solução, ou se conseguirmos simular, iremos atualizar o artigo.
Se você encontrar alguma solução também, nos envie.
Um grande abraço.
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.
Boa tarde Rafael, tudo joia?
Opa, nós que agradecemos pelo excelente adendo.
Realmente o S_T_A_M_P_ e I_N_S_D_T_ podem ajudar bastante.
Um grande abraço.
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.
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?
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.
Bom dia Alexandre.
Sim, igual citei no tópico 5 do link https://terminaldeinformacao.com/2023/01/25/para-que-serve-os-novos-campos-s_t_a_m_p_-e-i_n_s_d_t_-e-como-utiliza-los-no-protheus/ , que esta assim: “Se a tabela que você quer que esses campos sejam criados, já existir, faça um backup dela e drope…”
Um forte abraço.
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)),””)
Boa noite Paulo, tudo bem?
Não cheguei a realizar testes após a data de corte, mas tente utilizar a FWLeUserLG, ao invés de ter que usar a antiga Embaralha.
Segue um link de exemplo: https://terminaldeinformacao.com/2022/02/02/como-fazer-um-relatorio-lendo-os-campos-userlg/
Abraços
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
Opa, obrigado pelo comentário e contribuição José.
Um forte abraço.
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.
Bom dia Filipe, tudo joia?
Opa, obrigado pelo comentário e pela contribuição.
Um forte abraço.
Olá meu amigo sabe como ficou essa nova consulta para as ultimas libs ? porqque já não funciona mais retorna data incorreta
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.
Bom dia Johnny, tudo joia?
Opa, atualizei os exemplos das queries acima, conforme o comentário do Jose Rogerio do Prado Junior.
Os exemplos das queries agora estão funcionais.
Um grande abraço.
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
Boa tarde Paulo, tudo joia?
Opa obrigado pelo comentário.
Fazendo um adendo, temos um link de exemplo de como acionar ela em um relatório (TReport), segue o link caso lhe interessa: https://terminaldeinformacao.com/2022/02/02/como-fazer-um-relatorio-lendo-os-campos-userlg/
Um grande abraço.