Хотелось бы продолжить данную тему, так как проблема все таки имеет место и не решается с помощью выше указанного способа.
И так начнем, у нас есть источник данных в виде
TMemTableEh и есть древовидная структура таблицы.
Есть ветки, которые пользователь может свернуть.
Так вот, когда пользователь вводит некие данные, нам нужно подсчитать некий итог, и тут начинаются пляски с бубном.
Предоставленные способы обхода данных
TMemTableEh не дают нужного результата.
Полный пример реализующий данную проблему доступен в прикрепленном проекте.Если есть какой-то другой способ - хотелось бы его узнать, в документации ничего такого не нашел (вполне возможно что плохо смотрел).
Способ первый: через
InstantReadEnter - не заходит в свернутые ветки
Код:
// При этом варианте не учитываются свернутые ветки
for i := 0 to mtData.InstantReadRowCount-1 do begin
mtData.InstantReadEnter(i);
if mtData.FieldByName('F2').AsInteger > 0 then
total := total + mtData.FieldByName('F3').AsInteger;
mtData.InstantReadLeave;
end;
Способ второй: через
RecordsView.MemTableData.RecordsList - не видит измененные данные
Код:
// При этом варианте не учитываются измененное значение F3 текущей записи.
for i := 0 to mtData.RecordsView.MemTableData.RecordsList.Count-1 do begin
with mtData.RecordsView.MemTableData.RecordsList[i] do begin
if (DataValues['F2', dvvCurValueEh] > 0) then begin
total := total + DataValues['F3', dvvCurValueEh];
end;
end;
end;
Способ третий: свой способ (но кривой)
Так же минус этого способа в том, что необходимо либо помнить длиннющие пути, либо копировать от куда-то шаблоны,
а это очень влияет на производительность при написании кода.
Код:
// И вот такой более менее рабочий вариант
// Проблема этого метода в том, что не получается сделать метод расширения
// для обхода коллекции, так как я не знаю как сопоставить текущую запись вьюшки и курсора
// без явного указания полей
for i := 0 to mtData.RecordsView.MemTableData.RecordsList.Count-1 do begin
with mtData.RecordsView.MemTableData.RecordsList[i] do begin
if (DataValues['F2', dvvCurValueEh] > 0) then begin
// По текущей записи берем через курсор, а остальные из вьюшки
if DataValues['F1', dvvCurValueEh] = mtData.FieldByName('F1').AsInteger then
total := total + mtData.FieldByName('F3').AsInteger
else
total := total + DataValues['F3', dvvCurValueEh];
end;
end;
end;
Что бы хотелось в итоге - рабочий нормальный незамысловатый вариант, либо что-то на подобии такого
Код:
mtData.ForeachView(procedure (Rec: TViewRecordEh) begin
ShowMessage(Rec.FieldByName('F3').AsString);
if (Rec.FieldByName('F1').AsInteger = 5) then
Rec.Break();
end);
Либо интерфейс для реализации такого функционала через хелпер класс, имеется ввиду полный обход коллекции который включает в себя измененные данные и независимость от свернутых узлов дерева.