Boa noite,
Abaixo um exemplo que utilizei em um dos meus artigos sobre essa classe:
#include "protheus.ch"
// -----------------------------------------------------------------
/*{Protheus.doc} DnlTmpTbl
Exemplo de utilização da classe FWTemporaryTable
@sample U_DnlTmpTbl()
@author Daniel Mendes
@since 05/06/2019
@version 1.0
*/
// -----------------------------------------------------------------
user function DnlTmpTbl()
local oTable as object
local aFields as array
local nConnect as numeric
local lCloseConnect as logical
local cAlias as char
local cTableName as char
local cAreaQuery as char
local cQuerySQL as char
//--------------------------------------------------------------------------
//Esse bloco efetua a conexão com o DBAccess caso a mesma ainda não exista
//--------------------------------------------------------------------------
if TCIsConnected()
nConnect := TCGetConn()
lCloseConnect := .F.
else
nConnect := TCLink()
lCloseConnect := .T.
endif
//-------------------------------------------------------------------------------------------
//Só podemos continuar com a geração da tabela temporária caso exista conexão com o DBAccess
//-------------------------------------------------------------------------------------------
if nConnect >= 0
//--------------------------------------------------------------------
//O primeiro parâmetro de alias, possui valor default
//O segundo parâmetro de campos, pode ser atribuido após o construtor
//--------------------------------------------------------------------
oTable := FWTemporaryTable():New( /*cAlias*/, /*aFields*/)
//----------------------------------------------------
//O array de campos segue o mesmo padrão do DBCreate:
//1 - C - Nome do campo
//2 - C - Tipo do campo
//3 - N - Tamanho do campo
//4 - N - Decimal do campo
//----------------------------------------------------
aFields := {}
aAdd(aFields, {"C_ID", "C", 36, 0})
aAdd(aFields, {"N_COD", "N", 10, 0})
aAdd(aFields, {"C_NAME", "C", 50, 0})
aAdd(aFields, {"D_DATE", "D", 8, 0})
aAdd(aFields, {"C_OBS", "C", 255, 0})
oTable:SetFields(aFields)
//---------------------
//Criação dos índices
//---------------------
oTable:AddIndex("01", {"C_ID"} )
oTable:AddIndex("02", {"N_COD"} )
oTable:AddIndex("03", {"N_COD", "C_NAME"} )
//---------------------------------------------------------------
//Pronto, agora temos a tabela criado no espaço temporário do DB
//---------------------------------------------------------------
oTable:Create()
//------------------------------------
//Pego o alias da tabela temporária
//------------------------------------
cAlias := oTable:GetAlias()
//--------------------------------------------------------
//Pego o nome real da tabela temporária no banco de dados
//--------------------------------------------------------
cTableName := oTable:GetRealName()
//------------------------------
//Inserção de dados para testes
//------------------------------
(cAlias)->(DBAppend())
(cAlias)->C_ID := FWUUIDv4()
(cAlias)->N_COD := 1
(cAlias)->C_NAME := "Daniel"
(cAlias)->D_DATE := Date()
(cAlias)->C_OBS := "Kamehameha"
(cAlias)->(DBCommit())
//-------------------------------------------------------------------------
//Inserção de dados via INSERT, vamos usar o nome real da tabela para isso
//-------------------------------------------------------------------------
cQuerySQL := ""
cQuerySQL += "INSERT INTO " + cTableName + " (C_ID, N_COD, C_NAME, D_DATE, C_OBS) VALUES "
cQuerySQL += "('" + FWUUIDv4() + "', 2, 'Mendes', '" + DtoS(Date()) + "', 'Hadouken')"
if TCSqlExec(cQuerySQL) < 0
ConOut("Ops:", TCSqlError())
endif
(cAlias)->(DBSetOrder(3)) //N_COD+C_NAME
if (cAlias)->(DBSeek("1" + "Daniel"))
ConOut("Registro encontrado =)")
else
ConOut("Ops...")
endif
//---------------------------------------------------------
//Exemplo de query, agora vamos usar o nome real da tabela
//---------------------------------------------------------
cAreaQuery := GetNextAlias()
//--------------------------------------------------------------------
//É válido lembrar que a data é gravada como string no banco de dados
//--------------------------------------------------------------------
cQuerySQL := "SELECT C_ID, N_COD, C_NAME, D_DATE, C_OBS FROM " + cTableName
DBUseArea(.T., "TOPCONN", TCGenQry(,,cQuerySQL), cAreaQuery, .T., .T.)
while !(cAreaQuery)->(Eof())
ConOut( (cAreaQuery)->C_ID, (cAreaQuery)->N_COD, (cAreaQuery)->C_NAME, (cAreaQuery)->D_DATE, (cAreaQuery)->C_OBS )
(cAreaQuery)->(DBSkip())
enddo
//-----------------------------------------------------------
//Sempre fecho a workarea após utilizar do retorno da query
//-----------------------------------------------------------
(cAreaQuery)->(DBCloseArea())
//-------------------------------------------------------------------
//Fecho e apago a tabela temporária
//Por mais que a tabela temporária seja excluída de forma automática,
//é sempre uma boa prática fechar e excluir a mesma
//-------------------------------------------------------------------
oTable:Delete()
endif
//--------------------------------------
//Fecha a conexão criada para os testes
//--------------------------------------
if lCloseConnect
TCUnLink()
endif
return nil
Já escrevi alguns artigos sobre essa classe, dê uma olhada, acredito que possam lhe ajudar:
https://medium.com/totvsdevelopers/protheus-tabela-tempor%C3%A1ria-b2e955f43be4
https://medium.com/totvsdevelopers/insert-into-select-populando-tabela-tempor%C3%A1ria-1b3e1d1c93f
Os fontes dos artigos estão entre os meus gists:
https://gist.github.com/Dadinel
TDN:
https://tdn.totvs.com/display/framework/FWTemporaryTable
Com o seu exemplo, teríamos um código mais ou menos da seguinte forma:
local aTrbCpo as array
local cArqTab as char
local oTempTbl as object
aTrbCpo := {}
// Obs.: A estrutura do array para a FWTemporaryTable é a mesma
// Array para montar a Tabela Temporária para o Mark Browser
// Campo Tipo Tamanho Decimal
aAdd(aTrbCpo, {"FLAG" , "C", 02 , 2})
aAdd(aTrbCpo, {"FILIAL" , "C", Len(SF2->F2_FILIAL), 0})
aAdd(aTrbCpo, {"NOTA" , "C", Len(SF2->F2_DOC) , 0})
aAdd(aTrbCpo, {"SERIE" , "C", Len(SF2->F2_SERIE) , 0})
aAdd(aTrbCpo, {"EMISSAO" , "C", 10 , 0})
aAdd(aTrbCpo, {"CODIGO" , "C", 6 , 0})
aAdd(aTrbCpo, {"NOME" , "C", 35 , 0})
aAdd(aTrbCpo, {"VALOR" , "N", 13 , 0})
aAdd(aTrbCpo, {"VEICULO" , "C", 02 , 0})
aAdd(aTrbCpo, {"PLACA" , "C", 8 , 0})
aAdd(aTrbCpo, {"ESTADO" , "C", 2 , 0})
// Cria tabela temporária
//Primeiro parâmetro para o new é o alias, o segundo é a estrutura de campos
oTempTbl := FWTemporaryTable():New("TSZ1", aTrbCpo)
// Eu também poderia enviar a estrutura de campos com o método SetFields
// oTempTbl:SetFields(aTrbCpo)
//Utilizamos o método Create para criar a tabela temporária, ela será criada e aberta
oTempTbl:Create()
//Como antes o cArqTab era a variável que tinha o nome físico do arquivo, podemos trabalhar com ela
//sendo o nome real da tabela no banco de dados, para isso usamos o método GetRealName
cArqTab := oTempTbl:GetRealName()
//Após fazer o uso da tabela, as boas práticas pedem que a mesma seja fechada
//O método Delete efetuar a exclusão da tabela e também fecha a workarea da mesma
oTempTbl:Delete()
Clístenis, boa noite, quando você colocar um código como exemplo, por favor, coloque o código como texto, como imagem é muito mais complexo para responder, pois temos que digitar o seu código inteiro novamente, obrigado. Eu já havia respondido, criei um novo exemplo com base em seu código.
— Daniel Mendes 03 de Dec de 2019