Sobre o Componente TUCControlHistoric e TUCHist_DataSet
No geral apresentam-se com aspecto muito agradável, não está mal pensado, e é um excelente trabalho.
Pena ter sido abandonado, pelo menos aparentemente…
Todavia, impõe-se uma observação muito genérica acerca de ambos já que um não funciona se o outro, mas em particular quanto ao primeiro e na Propriedade
Options.TypeSavepostEdit:=tpSaveModifiedFields:
Tem como problema não se saber de que registo faz parte sempre que a opção for a registar “apenas os campos alterados”;
caso não altere um único campo chave identificando um único registo, nunca se saberá a qual pertence!
Parece-me que aqui necessita de uma correcção que passará, necessariamente, por guardar a PK (ou uma outra chave única que eventualmente exista). Doutro modo, nunca se saberá, a alteração inserida no histórico, a que registo pertence e
convém saber-se. Salvo melhor opinião é um lapso e tanto!
A alternativa será guardar todo o registo na Propriedade
Options.TypeSavepostEdit:=tpSaveAllFields
porque ai, como estão todos os campos representados consegue-se saber sempre a que registo diz respeito a alteração em histórico.
A utilização de um campo MEMO[OBS] formatado em texto para guardar o detalhe do registo alterado, percebe-se, mas não sei se
será a mais feliz!? Eu talvez tivesse optado pelo padrão do INI. Só é preciso testar qual dos modos será o mais rápido, para não ter de se voltar ao ficheiro com formato de registo variável. Enfim! É o de menos importância, São opções.
Atrás falei em bugs a corrigir. Por exemplo, a função “GetValueFields” não testa se o FieldKind=fkdata
pelo que é necessário acrescer uma linha, ficando como abaixo:
===============================================
function TUCHist_DataSet.GetValueFields: String;
===============================================
Var Aux : Integer;
begin
Result := ”;
For Aux := 0 to DataSet.FieldCount – 1 do
Begin
If DataSet.Fields[ Aux ].IsBlob = False then
If DataSet.Fields[ Aux ].FieldKind = fkData then
Begin
With DataSet.Fields[ Aux ] do
Begin
If DataSetInEdit = false then // inserindo ou deletando
try Result := Result + Format(‘%-20s = %s ‘,[ FieldName , AsString ] ) + #13#10; except end
else
Begin //editando
If fControl.Options.TypeSavePostEdit = tpSaveModifiedFields then
Begin
If Value <> AFields[ Aux ] then
try Result := Result + Format(‘%s||%s||%s’,[FieldNAme, AFields[ Aux ] , Value ] ) + #13#10; except end;
End
else
try Result := Result + Format(‘%s||%s||%s’,[FieldNAme, AFields[ Aux ] , Value ] )+ #13#10; except end;
End;
End;
end;
End; // for
end;
De outro modo rebenta sempre que haja um campo fkLookup; fkCalculate; fkInternalCalc ou fkAggregate.
Enquanto isso, creio ter encontrado na procedure “SetComBoValues” um erro que originava um “MemoryLeaks”
Foi resolvido o memory leaks do TAuxObj, conforme se pode ver abaixo:
=======================================
procedure TFrmHistorico.SetComBoValues;
=======================================
Var Aux : TAuxObj;
Begin
Aux := TAuxObj.Create;
// Cria aqui mas depois nunca mais liberta!!!???
Aux.IdUser := -1;
ComboUser.Items.Clear;
ComboForm.Items.Clear;
ComboEvento.Items.Clear;
ComboTabela.Items.Clear;
ComboUser.Items.AddObject( fControl.HistoryMsg.Hist_All , Aux );
ComboForm.Items.Add ( fControl.HistoryMsg.Hist_All );
ComboEvento.Items.Add( fControl.HistoryMsg.Hist_All );
ComboEvento.Items.Add( fControl.HistoryMsg.Evento_Insert );
ComboEvento.Items.Add( fControl.HistoryMsg.Evento_Delete );
ComboEvento.Items.Add( fControl.HistoryMsg.Evento_Edit );
ComboEvento.Items.Add( fControl.HistoryMsg.Evento_NewRecord );
ComboTabela.Items.Add( fControl.HistoryMsg.Hist_All );
DataSetHist := fControl.UserControl.DataConnector.UCGetSQLDataset(
Format(‘Select distinct %s from %s’,[
fControl.TableHistory.FieldTableName,
fControl.TableHistory.TableName]));
while DataSetHist.Eof = False do
Begin
ComboTabela.Items.Add( DataSetHist.Fields[ 0 ].AsString );
DataSetHist.Next;
End;
DataSetHist := nil;
DataSetHist := fControl.UserControl.DataConnector.UCGetSQLDataset(
Format(‘Select distinct %s from %s’,[
fControl.TableHistory.FieldCaptionForm,
fControl.TableHistory.TableName ]));
while DataSetHist.Eof = False do
Begin
ComboForm.Items.Add( DataSetHist.Fields[ 0 ].AsString );
DataSetHist.Next;
End;
DataSetHist := nil;
DataSetHist := fControl.UserControl.DataConnector.UCGetSQLDataset(
Format(‘Select %s, %s as Usuario from %s where %s = %s order by %s’,
[ fControl.UserControl.TableUsers.FieldUserID,
fControl.UserControl.TableUsers.FieldLogin ,
fControl.UserControl.TableUsers.TableName ,
fControl.UserControl.TableUsers.FieldTypeRec,
QuotedStr(‘U’) ,
fControl.UserControl.TableUsers.FieldLogin ]));
If fControl.UserControl.CurrentUser.Privileged = true then
Begin
while DataSetHist.Eof = False do
Begin //Salvo o devido respeito, parece-me errado
// Aux:= TAuxObj.Create; Dentro do ciclo? Uma vez p/cada registo? É muito estranho e provavelmente uma distração!
Aux.IdUser := DataSetHist.Fields[ 0 ].AsInteger;
ComboUser.Items.AddObject( DataSetHist.Fields[ 1 ].AsString, Aux );
DataSetHist.Next;
End;
End
else
begin
// Aux := TAuxObj.Create; //Salvo o devido respeito, parece-me errado
Aux.IdUser := fControl.UserControl.CurrentUser.UserID;
ComboUser.Items.AddObject( fControl.UserControl.CurrentUser.UserLogin, Aux );
end;
ComboUser.ItemIndex := 0;
ComboForm.ItemIndex := 0;
ComboEvento.ItemIndex := 0;
ComboTabela.ItemIndex := 0;
DataSetHist := nil;
DataSetHist := fControl.UserControl.DataConnector.UCGetSQLDataset(
Format(‘Select UH.%s as UserId, Uh.%s as Form , ‘ +
‘Uh.%s as Evento , Uh.%s as Obs, Uh.%s as FormCaption, Uh.%s as EventDate, Uh.%s as EventTime, uh.%s as TableName, ‘+
‘US.%s As UserName from %s UH, %s US where UH.%s = US.%s and Uh.%s = %s order by Uh.%s, uh.%s’,
[ fControl.TableHistory.FieldUserId ,
fControl.TableHistory.FieldForm ,
fControl.TableHistory.FieldEvent ,
fControl.TableHistory.FieldObs ,
fControl.TableHistory.FieldCaptionForm ,
fControl.TableHistory.FieldEventDate ,
fControl.TableHistory.FieldEventTime ,
fControl.TableHistory.FieldTableName ,
fControl.UserControl.TableUsers.FieldLogin ,
fControl.TableHistory.TableName ,
fControl.UserControl.TableUsers.TableName ,
fControl.TableHistory.FieldUserId ,
fControl.UserControl.TableUsers.FieldUserID ,
fControl.TableHistory.FieldApplicationID ,
QuotedStr(fControl.UserControl.ApplicationID) ,
fControl.TableHistory.FieldTableName ,
fControl.TableHistory.FieldEventDate ]));
DataSource1.DataSet := DataSetHist;
FreeAndNil(Aux);
// Minha corrcção. Quando sai liberta em definitivo Mário Reis
end;
Mas há mais memoryleaks ainda não cheguei lá. Não deixo aqui um “Print Screen” porque não tem como. Para o caso de alguém já te conseguido resolver e querer partilhar. Estão a dar-me cabo da cabeça porque não há uma pista que me conduza até lá! Obrigado
Ponta Delgada 2020-04-23 Mário Reis