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.
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:
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_ = ' '
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.