2012-04-04 17 views
7

¿cómo puedo averiguar si un campo de componente compatible con datos ha sido modificado cuando el conjunto de datos ya está en estado Insertar? Quiero saber si un campo fue 'realmente' modificado. (No me importa si el usuario ha ingresado algo en un campo y después de eso borrar todo, esto significa que se produjo una modificación).Delphi - TDataSet determinar si se modificó cuando está en insertar/editar el estado

DataSet.Modified, DataSet.UpdateStatus o ChangeCount no resuelven mi problema.

LE: déjame explicarte más a fondo esto. Por lo tanto, el conjunto de datos inicial se parece

------------------------------------- 
|PK | Field1| Field2| Field3|Field4| 
------------------------------------- 
| 1 | a | b  | c  | d | 
------------------------------------- 

después de inserción

------------------------------------- 
|PK | Field1| Field2| Field3|Field4| 
------------------------------------- 
| 2 |  |  |  |  | 
------------------------------------- 
| 1 | a | b  | c  | d | 
------------------------------------- 

cuando el conjunto de datos es realmente modificado

------------------------------------- 
|PK | Field1| Field2| Field3|Field4| 
------------------------------------- 
| 2 | avalue|  |  |  | 
------------------------------------- 
| 1 | a | b  | c  | d | 
------------------------------------- 
+0

¿Qué le parece pedir directamente el control? Quiero decir, por ejemplo 'TDBEdit.Modified'? Tómelo como una nota floja, por favor, no soy un usuario de controles de base de datos :-) – TLama

+1

@TLama - el problema es que esto está contenido por un formulario/marco maestro muy utilizado. Por lo tanto, estoy tratando de encontrar una solución genérica que me indique si el conjunto de datos 'realmente' cambió cuando ya está en un modo de inserción/edición ... – RBA

+2

No hay un nivel de conjunto de datos para hacerlo. Solo una forma de control de datos para hacerlo. –

Respuesta

8

Usted puede piratear la DataSet a cambiar su Modified propiedad en AfterInsert/AfterEdit (y conjunto inicial/predeterminado valores) y luego prueba para DataSet.Modified (por ej. encendido antes del poste).
Para determinar qué campos específicos se modificaron, tengo una copia del registro inicial ej .:

type 
    TDataRecord = array of record 
    FieldName: string; 
    Value: Variant; 
    end; 

type 
    TForm1 = class(TForm) 
    ... 
    private 
    FInitRecord, FPostRecord: TDataRecord; 
    end; 

function GetDataRecord(DataSet: TDataSet): TDataRecord; 
var 
    I: Integer; 
begin 
    Result := nil; 
    if Assigned(DataSet) then begin 
    SetLength(Result, DataSet.FieldCount); 
    for I := 0 to DataSet.FieldCount - 1 do begin 
     Result[I].FieldName := DataSet.Fields[I].FieldName; 
     Result[I].Value := DataSet.Fields[I].Value; 
    end; 
    end; 
end; 

type 
    TDataSetAccess = class(TDataSet); 

procedure TForm1.ADODataSet1AfterInsert(DataSet: TDataSet); 
begin 
    // set initial values 
    ADODataSet1.FieldByName('PK').Value := GetMyPKValue; 
    ADODataSet1.FieldByName('DateCreated').AsDateTime := Now(); 
    // un-modify 
    TDataSetAccess(ADODataSet1).SetModified(False); 
    // save initial record 
    FInitRecord := GetDataRecord(ADODataSet1); 
end;  

procedure TForm1.ADODataSet1BeforePost(DataSet: TDataSet); 
var 
    I: Integer; 
begin 
    if ADODataSet1.Modified then 
    begin 
    FPostRecord := GetDataRecord(ADODataSet1); 
    Memo1.Lines.Clear; 
    for I := 0 to Length(FPostRecord) - 1 do begin 
     if FPostRecord[I].Value <> FInitRecord[I].Value then 
     Memo1.Lines.Add(Format('Field %s was modified', [FPostRecord[I].FieldName])); 
    end; 
    end; 
end; 

bueno, es la idea abstracta de todos modos. Podría subclasificar su TDataSet como yo, e implementar esta característica directamente dentro de su componente TDataSet.

3

Cuando el estado es el uso dsInsert:

VarCompareValue(Field.NewValue, Unassigned) = vrNotEqual; 

dsEdit uso:

OldValue <> Value; 

No utilice esta en el estado dsInsert como en campos numéricos 0 es igual asignar:

Field.NewValue <> Unassigned 
+1

esto significa verificar que el campo no es nulo ...variante nula – RBA

+0

No acabo de recibir su comentario, el código que publiqué debe verificarse en el registro real, generalmente en el evento BeforePost, le dirá si fue "realmente" modificado. Después del evento Post solo verifica el ChangeCount. –

0

Hasta ahora encontré una solución, que parece funcionar. La solución consiste en: - vincular una fuente de datos al descendiente tdataset - una variable booleana global se establece en falsa en el evento del conjunto de datos OnAfterScroll, y es verdadera en el evento OnDataChange de las fuentes de datos.

De las pruebas que realicé en la aplicación hasta ahora, parece que esta solución está funcionando. Ahora necesito investigar todos los eventos que ocurren y necesito un tratamiento especial para no alterar el estado de la variable global en el proceso.

Cualquier otra idea es bienvenida

Cuestiones relacionadas