Forma certa de se posicionar em um item marcado para ser deletado ( um item que sofreu um dbDelete())

Estou fazendo uma solução onde eu deleto um item antes da tela abrir, porem caso a pessoa feche a tela ou cancele eu quero voltar esse item. Usando msSeek e dbRecall não esta funcionando para mim, não ocorre erro, porem não retira o status de deletado do item.


            dbSelectArea("SB2")
            dbSetOrder(1)
            SB2->(dbGoTop())
            IF(msSeek(xFilial("SB2") + cCod + cLocal))
                RecLock("SB2",.F.)
                dbRecall()
                msUnlock()
            EndIf
            dbCloseArea()

Obs. Após debugar percebi que o problema pode ser o msSeek, pois ele esta sempre retornando .F., isso eu consigo resolver correndo a tabela toda e procurando 1 a 1 o item que eu quero com um while, mas é realmente o melhor a se fazer?

Solucionei fazendo mais na unha:


BeginSql Alias alSB2
SELECT R_E_C_N_O_ AS SB2REC FROM %TABLE:SB2% B2 WHERE B2_COD = %EXP:cCod% AND B2_LOCAL = %EXP:cLocal%
EndSql
dbSelectArea("SB2")
dbSetOrder(1)
DBGOTO((alSB2)->SB2REC)
RecLock("SB2",.F.)            
dbRecall()            //Como esta na tela de exclusão é necessario retornar o DELETE que foi executado a cima
msUnlock()

dbCloseArea()

Mas se tiver alguma função pronta eu aceito.

Boa tarde, Patrick!

Por padrão, o sistema não reconhece registros deletados. Caso queira que os mesmos sejam visíveis, use o comando Set Deleted Off. Exemplo:


//Abro a tabela DAK
DbSelectArea('DAK')

//Vou para o Recno 100
DAK->(DbGoTo(100))

//Verifico se está posicionado
If(!DAK->(EoF())

    //Deleto o registro
    RecLock('DAK', .F.)
        DAK->(DbDelete())
    DAK->(MsUnlock())

Endif

//Fecho a tabela
DAK->(DbCloseArea())

//Exibo registros deletados
Set Deleted Off

//Abro a tabela DAK
DbSelectArea('DAK')

//Vou para o Recno 100
DAK->(DbGoTo(100))

//Verifico se está posicionado
If(!DAK->(EoF())

    //Recupero o registro
    RecLock('DAK', .F.)
        DAK->(DbRecall())
    DAK->(MsUnlock())

Endif

//Fecho a tabela
DAK->(DbCloseArea())

//Exibo apenas registros válidos
Set Deleted On

Lembre-se que no final do seu processo, usar o comando Set Deleted On para retornar o comportamento original do sistema.

Me parece bastante útil e perigosa ao mesmo tempo, vou procurar usa-la sempre junto com o Begin Transaction…End Transaction para garantir a integridade. Muito obrigado novamente Giordano.

Boa tarde Patrick,

Para retornar um registro deletado, é como você mesmo fez ou como o Giordano também demonstrou, porém você pode fazer isso de forma mais simples, pois você tem uma query para isso, por exemplo:


if TCSqlExec( "UPDATE " + RetSqlName("SB2") + " SET D_E_L_E_T_ = ' ' WHERE B2_COD = '" + cCod + "' AND B2_LOCAL = '" + cLocal + "'" ) < 0
    UserException( TCSqlError() )
endif

Dessa forma você terá uma performance muito superior.

Vou experimentar também, nesse caso a diferença de performance não será nem notada, mas sempre bom fazer do melhor jeito. Obrigado Daniel.