Короткая версия
Как мне позвонить:
dataset1.FieldByName(fieldName).AsString := 'Something';
и заставить это работать?
Длинная версия
У меня есть DataSet
:
var
ds: TDataSet;
ds := GetSomeSortOfDataSetFromSomewhere();
Этот набор данных будет экспортирован (например, в Excel, cSV, TSV, Markdown, HTML, XML):
ExportDataSet(ds);
, и экспорт будет содержать все столбцы и все строки:
| Username | Fullname |
|----------|-------------------------|
| ian | IAN BOYD |
| MartynA | MARTIN |
| ngal | NASREDDINE GALFOUT |
| uewr | UWE RAABE |
Теперь я хочу изменить поле Fullname
для каждой строки в памяти , прежде чем делать с ним что-то еще (т. е. никогда не возвращаться в база данных, я не знаю, откуда она взялась, возможно, она не пришла из базы данных):
while not ds.EOF do
begin
ds.FieldByName('Fullname').AsString := FormatNamePrettyLike(ds.FieldByName('Fullname').AsString;
ds.Next;
end;
При попытке изменить поле выдается исключение:
Набор данных не находится в режиме редактирования или вставки
Решение состоит в том, чтобы клонировать набор данных в оперативную память TClientDataset
:
///<summary>Clones a dataset into a TClientDataSet; which is an editable in-memory DataSet.</summary>
function CloneDataSet(dsSource: TDataSet): TDataSet; //TDataSet > TCustomClientDataSet > TClientDataSet
var
tempProvider: TDataSetProvider;
data: OleVariant;
ds: TClientDataSet;
begin
tempProvider := TDataSetProvider.Create(nil);
try
tempProvider.DataSet := dsSource;
data := tempProvider.Data;
finally
tempProvider.Free;
end;
ds := TClientDataSet.Create(nil);
ds.Data := data;
Result := ds;
end;
Что дает больший код:
var
ds: TDataset;
dsEditable: TDataSet;
ds := GetDataSomeOfSomeSortFromSomewhere();
//Clone to dataset to an in-memory dataset so we can modify it.
dsEditable := CloneDataSet(ds);
ds.Free;
ds := edEditable;
while not ds.EOF do
begin
ds.FieldByName('Fullname').AsString := FormatNamePrettyLike(ds.FieldByName('Fullname').AsString;
ds.Next;
end;
Но это выдает ошибку:
Набор данных не находится в режиме редактирования или вставки
Решение состоит в том, чтобы поставить набор данных в режиме редактирования :
//The in-memory ClientDataSet won't be editable until you mark it editable.
ds.Edit;
///<summary>Clones a dataset into a TClientDataSet; which is an editable in-memory DataSet.</summary>
function CloneDataSet(dsSource: TDataSet): TDataSet; //TDataSet > TCustomClientDataSet > TClientDataSet
var
tempProvider: TDataSetProvider;
data: OleVariant;
ds: TClientDataSet;
begin
tempProvider := TDataSetProvider.Create(nil);
try
tempProvider.DataSet := dsSource;
data := tempProvider.Data;
finally
tempProvider.Free;
end;
ds := TClientDataSet.Create(nil);
ds.Data := data;
//The in-memory ClientDataSet won't be editable until you mark it editable.
ds.Edit;
Result := ds;
end;
Повторение нормы теперь дает ошибку:
Поле Fullname
не может быть изменено .
Решение состоит в том, чтобы установить для Field.ReadOnly значение false :
//Even after marking the in-memory data-set as editable, you still can't edit it
//until you mark all fields as editable.
for i := 0 to ds.FieldCount-1 do
ds.Fields[i].ReadOnly := False;
///<summary>Clones a dataset into a TClientDataSet; which is an editable in-memory DataSet.</summary>
function CloneDataSet(dsSource: TDataSet): TDataSet; //TDataSet > TCustomClientDataSet > TClientDataSet
var
tempProvider: TDataSetProvider;
data: OleVariant;
ds: TClientDataSet;
begin
tempProvider := TDataSetProvider.Create(nil);
try
tempProvider.DataSet := dsSource;
data := tempProvider.Data;
finally
tempProvider.Free;
end;
ds := TClientDataSet.Create(nil);
ds.Data := data;
//The in-memory ClientDataSet won't be editable until you mark it editable.
ds.Edit;
//Even after marking the in-memory data-set as editable, you still can't edit it
//until you mark all fields as editable.
for i := 0 to ds.FieldCount-1 do
ds.Fields[i].ReadOnly := False;
Result := ds;
end;
Повторение упражнения дает ошибка:
Попытка изменить поле только для чтения.
Так что я сдаюсь. Как мне отредактировать поле DataSet?
Все клонированное содержимое TCustomClientDataSet в памяти; я просто хочу отредактировать их на клиенте для отображения.
Bonus Chatter
Очевидно, я не могу добавлять новые столбцы в набор данных:
| Username | Fullname | PrettyFullname |
|----------|-------------------------|--------------------|
| ian | IAN BOYD | Ian Boyd |
| MartynA | MARTIN | Martin |
| ngal | NASREDDINE GALFOUT | Nasreddine Galfout |
| uewr | UWE RAABE | Uwe Raabe |
Очевидно, что я не могу присоединить обработчик событий к набору данных:
- , так как этот обработчик данных будет недействительным, когда набор данных передается следующему человеку в цепочке (например, в потоке), и исходная форма освобождается
- , и это также не то, что я спрашиваю; что касается изменения содержимого набора данных
- , обновление значений затрагивает другие системы (например, базы данных, веб-службы и т. д. c). Я хочу, чтобы изменения были сделаны один раз, а затем в наборе данных