![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Просмотр и восстановление "удаленных" записей в DBF таблицах [D7, dBase, FoxPro]
АМБ © (2005-07-18 11:15:00)Как организовать просмотр помеченных на удаление записей в DBF таблице? Т.е. сначала, записи обрабатываются tblDBF1.Delete; и становятся невидимы в DBGrid-е. Как сделать их видимыми, да еще и другим цветом, или как-то еще их выделить, а затем, выбрав какую-нибудь запись - восстановить ее, т.е. снять пометку на удаление.
Kacnep (2005-10-07 12:04:00) [1]Да у меня вопрос не в удаленных зхаписях
а в
if FieldDefs.Count>0 then for row:=FieldDefs.Count-1 downto 0 do Fields[row].Free;
FieldDefs.Clear;
TableName:=s; --- указываю с какой табл буду работать
FieldDefs.Update; --- получаю список полей в датасет
если сначала открыть таблицу считать ее поля потом закрыть и попытаьтся считать поля другой таблицы - выдастся ошибка.
вывод - надо удалить поля старой. А КАК?
if FieldDefs.Count>0 then for row:=FieldDefs.Count-1 downto 0 do Fields[row].Free;
FieldDefs.Clear;
ЭТО НЕ РАБОТАЕТ!
Вот ошибка
Debugger Exception Notification
---------------------------
Project balance.exe raised exception class EOleException with message 'Item cannot be found in the collection corresponding to the requested name or ordinal'. Process stopped. Use Step or Run to continue.
Seg (2005-10-07 11:39:00) [2]Как организовать просмотр помеченных на удаление записей в DBF таблице? Т.е. сначала, записи обрабатываются tblDBF1.Delete; и становятся невидимы в DBGrid-е. Как сделать их видимыми, да еще и другим цветом, или как-то еще их выделить, а затем, выбрав какую-нибудь запись - восстановить ее, т.е. снять пометку на удаление.
Добавляешь еще одно поле в таблицу например DELETED.
Для удаленных записей устанавливаешь 1, для неудаленных 0.
Таким образом ты можещь показывать
1.Все неудаленные
2.Все удаленные
3.Все удаленные и неудаленные.
4.Ничего не показывать
С обработчиком строк (раскраской) тоже не должно возникнуть проблем.
Ну и установку/отмену статуса строки тоже легко можно реализовать.
Kacnep (2005-10-07 11:30:00) [3]
АМБ (27.07.05 15:26) [67]
Наконец-то, догадалься, что список полей - это буквально только список, а не сами поля :-(). Так что, теперь в начале процедуры открытия таблицы использую код:
if tblDBF.FieldDefs.Count <> 0 then
begin
CulcDelFld.Free;
for i := tblDBF.FieldDefs.Count-1 downto 0 do
tblDBF.Fields[i].Free;
end;
Теперь разные таблицы переоткрываются без ошибок и все, вроде бы, пока хорошо.
А насчет лишних линий при отрисовки ячеек, я это взял из примера статей, которые рекомендовали в этом форуме. Подозревал, что они могут быть излишне, но еще не проверял на практике. Сейчас проверил. Вы правы. Работает и без них.
Так что еще раз БОЛЬШОЕ СПАСИБО!
:о))))
У меня не получилось :(((( не работает. Не работает переоткрытие в adoTable разных таблиц.
Вот что у меня...
s:='ТАБЛИЦА_АКЦЕССА1';
with dm.adot_Meh do begin
if FieldDefs.Count>0 then for row:=FieldDefs.Count-1 downto 0 do Fields[row].Free;
FieldDefs.Clear;
TableName:=s; --- указываю с какой табл буду работать
FieldDefs.Update; --- получаю список полей в датасет
Filtered:=false;
for row:=0 to FieldDefs.Count-1 do begin
FieldDefs.Items[row].CreateField(dm.adot_Meh); -- создаю поля из датасета динамически
end;
f:=TStringField.Create(dm.adot_Meh); дальше создаю дополнит поле
f.Name:='adot_MehSumm';
f.FieldName:='Summ';
f.DisplayLabel:='Сумма';
f.DataSet:=dm.adot_Meh;
f.Calculated:=true;
f.FieldKind:=fkCalculated;
Open; -- открываю набор данных
{поработал с набором в ДБгриде, Закрыл набор данных}
end;
s:='ТАБЛИЦА2'
вызываю код приведенный выше.... иии НА FieldDefs.Update; --- получаю список полей в датасет
ошибка таковая...
Debugger Exception Notification
---------------------------
Project balance.exe raised exception class EOleException with message 'Item cannot be found in the collection corresponding to the requested name or ordinal'. Process stopped. Use Step or Run to continue.
Если гуру подскажут спасут то что осталось от мозга решавшего этот трабл на протяжении 6и часов :((
Блин перепробовал все.
Anatoly Podgoretsky (2005-09-05 16:00:00) [4]Так это надо рисовать в OnDrawCell - кстати а ты то тут причем, этот вопрос от АМБ
А тебе надо задать свой вопрос как рисовать строки другим цветом или посмотреть в каком ни будь Чаво, ими просто завален Интернет да и в справке есть пример.
sweet lou (2005-09-05 14:39:00) [5]интересные тут такие рассуждения были.......но я так и не понял, как же сделать чтобы в моем гриде удаленные записи отличались другим цветом!!!!
АМБ (2005-07-29 14:04:00) [6]Спешу поделиться радостью...;о)))
Немного изменил процедуру:
tblDBF.Edit;
sBuffer := tblDBF.ActiveBuffer;
ShowMessage(tblDBF.ActiveBuffer[0]);
tblDBF.ActiveBuffer[0]:=' ';
ShowMessage(tblDBF.ActiveBuffer[0]);
tblDBF.Post;
Все заработало... Пока...
Большое СПАСИБО > sniknik
АМБ (2005-07-29 13:55:00) [7]Прощу прощения. Ошибся.
> но запись не удаляет.
т.е. запись не восстанавливается.
АМБ (2005-07-29 13:53:00) [8]Да. Вариант с DbiUndeleteRecord сразу пока не идет.
Взял пример прямо из BDE32.HLP. На строке:
Check(DbiUndeleteRecord(dBASETbl.Handle));
выдает ошибку: Operation not applicable.
Работа с ActiveBuffer как-то больше нравиться. Не знаю еще почему. Написал код:
begin
sBuffer := tblDBF.ActiveBuffer;
ShowMessage(tblDBF.ActiveBuffer[0]); //Показывает "*"
tblDBF.ActiveBuffer[0]:=' ';
ShowMessage(tblDBF.ActiveBuffer[0]); //Показывает " "
tblDBF.Edit;
tblDBF.Post;
end;
Проходит без ошибок, но запись не удаляет.
Продолжаю разбираться... Но, если подскажите, то буду рад...:о)
sniknik (2005-07-29 11:28:00) [9]ты в хелп так и не научился заглядывать? ;) BDE-шная функция DbiUndeleteRecord
но подозреваю могут быть опять проблемы ;о)), изза тогоже несоответствия...
а попробуй в ActiveBuffer исправить. получится?
АМБ (2005-07-29 11:23:00) [10]Да, об этом я догадывалься ;о)
Согласно Вашей методике
> Опять же польза - учимся работать с файлами БД напрямую.
, так, я думаю, и надо делать. Правда, я ее еще не освоил, хотя за исходники спасибо.
А нет ли функций, типа UnDelete?
ANB (2005-07-29 11:09:00) [11]Надо заменить * на пробел
АМБ (2005-07-29 10:59:00) [12]Извините за назойливость... Но мы забыли вторую часть вопроса:
"... а затем, выбрав какую-нибудь запись - восстановить ее, т.е. снять пометку на удаление."
Подскажите, пожалуйста.
АМБ (2005-07-27 15:26:00) [13]Наконец-то, догадалься, что список полей - это буквально только список, а не сами поля :-(). Так что, теперь в начале процедуры открытия таблицы использую код:
if tblDBF.FieldDefs.Count <> 0 then
begin
CulcDelFld.Free;
for i := tblDBF.FieldDefs.Count-1 downto 0 do
tblDBF.Fields[i].Free;
end;
Теперь разные таблицы переоткрываются без ошибок и все, вроде бы, пока хорошо.
А насчет лишних линий при отрисовки ячеек, я это взял из примера статей, которые рекомендовали в этом форуме. Подозревал, что они могут быть излишне, но еще не проверял на практике. Сейчас проверил. Вы правы. Работает и без них.
Так что еще раз БОЛЬШОЕ СПАСИБО!
:о))))
sniknik (2005-07-27 12:31:00) [14]> свободен от нынешней ошибки при переоткрытии таблицы...
ошибка при переоткрытии твоя, метод не причем. созданные обьекты надо уничтожать.
а уж будет или нет... как напишеш. (правда в 1-й строчке ошибку сделать труднее чем в пяти/десяти ;о)))
у тебя еще и в отрисовке эти
TDBGrid(Sender).Canvas.FillRect(Rect);
TDBGrid(Sender).Canvas.TextOut(Rect.Left,Rect.Top,Column.Field.Text);
строки лишние.
АМБ (2005-07-27 12:08:00) [15]Точно... Переносил код через буфер, а он в окошке не помещалься, да и ремарки на русском не переносились, вот и "напортачил".
Конечно:
CulcDelFld.FieldKind := fkCalculated;
А вот и функция, которую забыл:
procedure TfrmMain.MyCalcField(DtSt: TDataSet);
begin
if Deleted(tblDBF) Then tblDBF['flgDelete'] := '*';
end;
Что касается, tblDBF.FieldDefs[i].CreateField(Self);
так я пробовал делать tblDBF.FieldDefs.Free;
но также пока не получилось... Буду пробовать дальше...
Спасибо за второй метод. Кажеться более интересным, и кажеться будет свободен от нынешней ошибки при переоткрытии таблицы...
Постараюсь и его реализовать.
Еще раз спасибо.
sniknik (2005-07-27 11:33:00) [16]ладно, допустим это работает... т.к. нет функции MyCalcField, нет такого типа Calculated и это не позволит коду даже скомпилится.
кстати ошибка при повторном открытии у тебя от того, что
tblDBF.FieldDefs[i].CreateField(Self);
это функция. которая возвращает результат (кстати! ;) ... ты его теряеш, но от того что ты на созданные обьекты не обращаеш внимания, они существовать не перестанут...
(в принципе ссылки на них можно и из таблици вытащить, гдето они должны сохранятся)
второй метод о котором я говорил это просто доведенная до логического завершения мысль ANB, он пытался получить информацию из файла (но как тогда связь записей в файле с табличным делать? и зачем если можно проще), я получаю тоже самое из внутреннего буфера самой таблицы ActiveBuffer (строка записи "as is", до разбора на составляющие (поля), в ней признак '*' еще есть.)
все в общемто. думаю достаточно. (кстати тоже не всегда соответствует действительности... если тупо заменить Deleted() в событии по вычисляемому полю на проверку по нему тоже дает неверный результат... странно (может глюк. второйраз проверять не хочется). в событии DrawColumnCell зато соответствие полное)
АМБ (2005-07-27 09:36:00) [17]
> sniknik
Показываю...
interface
...
var
...
//Сделал глобальной, т.к. может использоваться и в других процедурах
CulcDelFld : TField;
//Открытие файла для работы
procedure TfrmMain.N11_OpenFileClick(Sender: TObject);
begin
...
tblDBF.FieldDefs.Clear;
tblDBF.FieldDefs.Update;
//Добавляем все поля
for i := 0 to tblDBF.FieldDefs.Count-1 do
tblDBF.FieldDefs[i].CreateField(Self);
//Создаем вычисляемое поле
CulcDelFld := TStringField.Create(Self);
CulcDelFld.FieldName := 'flgDelete';
CulcDelFld.FieldKind := Calculated;
CulcDelFld.DataSet := tblDBF;
CulcDelFld.Calculated := True;
CulcDelFld.Size := 1;
CulcDelFld.DataSet.AutoCalcFields := True;
CulcDelFld.DataSet.OnCalcFields := frmMain.MyCalcField;
/////////////////////////////
tblDBF.Open;
tblDBF.First;
dbgDBF.SetFocus;
...
procedure TfrmMain.dbgDBFDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if tblDBF['flgDelete'] = '*' then
begin
TDBGrid(Sender).Canvas.Brush.Color := $00ff00;
TDBGrid(Sender).Canvas.Font.Color := $0000ff;
TDBGrid(Sender).Canvas.FillRect(Rect);
TDBGrid(Sender).Canvas.TextOut(Rect.Left,Rect.Top,Column.Field.Text);
IF gdSelected IN State Then
Begin
TDBGrid(Sender).Canvas.Brush.Color:= clHighLight;
TDBGrid(Sender).Canvas.Font.Color := clHighLightText;
End;
TDBGrid(Sender).DefaultDrawColumnCell(Rect,DataCol,Column,State);
end;
end;
Вроде все...
Правда, при открытии другой таблицы, такой же структуры, выдает ошибку дубликата полей на коде:
for i := 0 to tblDBF.FieldDefs.Count-1 do
tblDBF.FieldDefs[i].CreateField(Self);
Процедура
tblDBF.FieldDefs.Clear;
не помогает...
Anatoly Podgoretsky (2005-07-27 08:52:00) [18]Если надо что бы было почти полное подобие xBase то именно через вычислимое поле и надо, там оно является не функцией, а именно полем _DELETED_, вроде такое имя если память не подводит.
Наличие поля упрощает всю остальную обработку.
sniknik (2005-07-27 08:49:00) [19]> Сделал как Вы советовали через вычисляемое поле.
покажи.
АМБ (2005-07-27 08:24:00) [20]Еще раз БОЛЬШОЕ СПАСИБО > sniknik!!!
Сделал как Вы советовали через вычисляемое поле. Все работает.
Уважаемый > sniknik!
А можно, теперь, узнать и о другом способе?