Форум: "Базы";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];
ВнизПросмотр и восстановление "удаленных" записей в DBF таблицах Найти похожие ветки
← →
Val © (2005-07-21 15:05) [40]Разбирается. Разберется - скажет. 18 кил символов, означающих странные вещи - не шутки.
← →
АМБ (2005-07-21 15:30) [41]Всем спасибо! Судя по полученному коду (за что, конечно, БОЛЬШОЕ спасибо ANB) мне еще и до тупорылого шагать и шагать...%((((
Поэтому прийдеться и впрям идти в... дворники, и то, если возьмут.
> Anatoly Podgoretsky © (21.07.05 14:52) [38]
Я и не сомневалься, что БДЕ работает нормально, но... так и не понял, почему в моем случае она (функция DELETED) все время показывает True? Ну, да... может когда-нибудь и пойму...
Еще раз ВСЕМ СПАСИБО %о))))(((())))
← →
Anatoly Podgoretsky © (2005-07-21 15:38) [42]Ты сначала сделай блок ELSE в своем коде. Потом сделай метку и двигаясь по записям вывод в нее состояние, тогда и говорить можно, а что говорить по ошибочному коду, не понимая как работает OnDrawCell
← →
АМБ (2005-07-21 15:51) [43]
> Anatoly Podgoretsky © (21.07.05 15:38) [42]
procedure TfrmMain.dbgDBFDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if DELETED(tblDBF) 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+2,Rect.Top+2,Column.Field.Text);
end
else
begin
TDBGrid(Sender).Canvas.Brush.Color := $ffffff;
TDBGrid(Sender).Canvas.Font.Color := $000000;
TDBGrid(Sender).Canvas.FillRect(Rect);
TDBGrid(Sender).Canvas.TextOut(Rect.Left+2,Rect.Top+2,Column.Field.Text);
end;
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;
"Шагал" по всем записям... Идет по каждой ячейки всей записи, переходит на новую, снова по всем ячейкам и т.д. В блок ELSE ни разу не попадает.
← →
Anatoly Podgoretsky © (2005-07-21 16:04) [44]Для начала сделай тестовую версию
n1 := 0;
n2 := 0;
tblDBF.First;
begin
while not tblDBF.Eof do
if Deleted(tblDBF) do begin
N1 := N1 + 1;
Label1.Caption := IntToStr(N1);
end;
else begin
N2 := N2 + 1;
Label2.Caption := IntToStr(N1);
end;
Application.ProcessMessages;
tblDBF.Next;
end;
← →
АМБ (2005-07-21 17:20) [45]
> Anatoly Podgoretsky © (21.07.05 16:04) [44]
Немного изменил текст кода:
procedure TfrmMain.Button1Click(Sender: TObject);
var
N1, N2: integer;
begin
n1 := 0;
n2 := 0;
tblDBF.First;
while not tblDBF.Eof do
begin
if Deleted(tblDBF) Then
begin
N1 := N1 + 1;
// Label1.Caption := IntToStr(N1);
end
else
begin
N2 := N2 + 1;
// Label2.Caption := IntToStr(N1);
end;
Application.ProcessMessages;
tblDBF.Next;
end;
lblForInfo.Caption:="Del:"+IntToStr(N1)+#10+"NotDel:"+IntToStr(N2);
end;
Результат: Del:14
Т.е., в таблице, которая открывалась в DBGrid-e всего 14 записей: удаленных и неудаленных
← →
ANB © (2005-07-21 19:13) [46]
> begin
> N2 := N2 + 1;
> // Label2.Caption := IntToStr(N1);
> end;
- вот это место замени на
> begin
> N2 := N2 + 1;
> // Label2.Caption := IntToStr(N2);
> end;
Проблеме не поможет, но будет красивее работать.
← →
АМБ (2005-07-25 08:28) [47]Мастера, извините за назойливость.
В силу "специфики" работы со сторонними организациями, я работаю с DBASE-III.
dbiGetRecord заработала начиная с DBASE-IV.
На DBASE-III не работает.
Это так и надо?
← →
sniknik © (2005-07-25 08:38) [48]> Это так и надо?
проверь, открой таблицу текстовым редактором, если значки у удаленных "*" на месте (а куда им дется то ;о))) должно работать...
если есть, а всетаки не работает пришли пример таблици, посмотреть. может и придумаем чего (если не работает).
← →
ANB © (2005-07-25 12:40) [49]
> АМБ (25.07.05 08:28) [47]
В коде, который я тебе выслал, самое главное - это определение рекордов заголовка DBF и полей DBF. В сети есть описание структуры DBF файла. Если в мои рекорды записать из файла инфу - то в полях начдешь много полезного и сможешь определить по какому смещению начинается запись с нужным тебе номером. Я, вроде, комментарии воткнул. * юзается для пометки практически во всех DBF. Минус - если заюзал индекс, то я не знаю, как ты будешь искать номер нужной тебе записи. Если нет - то все просто. Работать должно быстро, если все параметры (смещение первой записи и размер записи) ты определишь заранее (до или сразу после открытия таблицы). Затем все сведется к :
- расчитать позицию нужной записи
- прочитать один байт
- проанализить его.
Все имхо. На исчерпывающий вариант не претендую.
← →
sniknik © (2005-07-25 13:17) [50]во настырные... и все время через задницу норовят сделать. ;о))
все работает и с 3-м dBase тоже (не выдержал, сам сделал таблицу 3-го и проверил), проблема не в версии, проблема в интерпретации, просто проверялось так понимаю на таблице с малым количеством записей, первая была удаленная...
вот вся неопределенность "неопределенно пятнистого грида" вылилась в одно пятно... (на большее не хватает).
впрочем все это уже описывал, не буду повторятся, если хочеш перечитай ветку.
← →
sniknik © (2005-07-25 13:25) [51]кстати способ определить удаленность не единственный (теперь когда практически "заставили" сделать тест, это вижу). но предлагать другое не буду, не вижу смысла. зачем? с одним то не разобрались.
← →
ANB © (2005-07-25 14:11) [52]
> sniknik © (25.07.05 13:17) [50]
> во настырные... и все время через задницу норовят сделать.
> ;о))
- че сразу ругаться то. Через задницу интереснее же. Опять же польза - учимся работать с файлами БД напрямую.
← →
Anatoly Podgoretsky © (2005-07-25 14:22) [53]ANB © (25.07.05 14:11) [52]
учимся работать с файлами БД напрямую
Тупиковый путь.
← →
ANB © (2005-07-25 15:06) [54]
> Anatoly Podgoretsky © (25.07.05 14:22) [53]
- а вдруг пригодится ?
← →
Anatoly Podgoretsky © (2005-07-25 15:19) [55]А попробуй изменить 12 байт в kernel.exe может пригодится.
Зачем чесать левое ухо правой рукой, когда тебе рассказали про нормальные пути? Делать что ли нечего?
← →
АМБ (2005-07-26 10:51) [56]Всем кому еще не надоело….
Не успел я порадоваться, что все заработало как надо (а ведь действительно работало…), как все перестало работать. И теперь работает, по-новому, но не так как надо. А работает следующим образом. Не зависимо от настройки BDE->Configuration->Native->DBASE->LEVEL=3 (или 4), отработка кода, текст которой выше, выдает следующие результаты.
Форма моей программки может менять размер, меняется и размер DBGrid-a. Если размер DBGrid-a такой, что показываются все записи таблицы без скроллинга, то все записи считаются как удаленные. А если размер формы вместе с размером DBGrid-a изменить так, что появляется скроллинг, то все записи считаются не удаленными. Хотя в таблице есть и удаленные и не удаленные записи.
Не знаю, что я мог изменить неаккуратно в BDE или в тексте программки, но знаю, что работало, а теперь не работает. Если кому интересно могу выслать весь исходник своей программки (архив 41 кб) с тестовыми базами (архив 8 кб ).
Для sniknik я выслал сразу, воспользовавшись его приглашением.
← →
sniknik © (2005-07-26 11:27) [57]> Для sniknik я выслал сразу, воспользовавшись его приглашением.
ничего себе сразу ...
предложено (и потом следующим же постом сказал что проверил, значит все, проблема себя исчерпала. неинтересно)
sniknik © (25.07.05 13:17) [50]
получено
Дата: Tue, 26 Jul 2005 10:50:30 +0400 (MSD)
потом в исходниках просто нет кода который обсуждается...!!!??? я код за других не пишу... исправить могбы. может быть. (именно поэтому в ответ выслал только екзешник (с добавкой которую долго пытался донести словами... безушпешно)) все работает. читай еще раз эту ветку, можеш мои посты перечитывать по два раза...
← →
АМБ (2005-07-26 11:42) [58]Для > sniknik . Во-первых, БОЛЬШОЕ СПАСИБО!!!
Во-вторых, "сразу" я имел ввиду не сразу после приглашения, а сразу после моей просьбой разобраться с моим кодом.
А все это время я пыталься выяснить, что я "потерял" и почему программка перестала считать "удаленные" записи и "неудаленные".
Ваш екзешник работает как я и хотел. Это радует.
Правда подсчет записей осталься таким как и был. Это немного огорчает.
Насколько я правильно понял, Вы ввели вычисялемое поле, и по нему уже прорисовываете DBGrid. ЧТо ж буду проповать теперь этот вариант. Хотя нерешенный вопрос о подсчете записей, все-таки висит небольшым, но неприятным грузом.
← →
sniknik © (2005-07-26 11:59) [59]> Правда подсчет записей осталься таким как и был.
я его не трогал.
> Насколько я правильно понял, Вы ввели вычисялемое поле, и по нему уже прорисовываете DBGrid.
нет, именно тут я воспользовался другим способом ([51]).
сдесь это проше как оказалось, но не зная ничего о задаче даже не думал о решении в таком аспекте. до получения исходников. а предлогат теоретическое решение, на проверку, но тоже рабочее (см. [50]).
> Хотя нерешенный вопрос о подсчете записей, все-таки висит небольшым, но неприятным грузом.
обьяснял в первом же своем посте, сдесь похоже то самое.
BDE и компонент на его основе это всетаки не одно и тоже.
← →
АМБ (2005-07-27 08:24) [60]Еще раз БОЛЬШОЕ СПАСИБО > sniknik !!!
Сделал как Вы советовали через вычисляемое поле. Все работает.
Уважаемый > sniknik !
А можно, теперь, узнать и о другом способе?
← →
sniknik © (2005-07-27 08:49) [61]> Сделал как Вы советовали через вычисляемое поле.
покажи.
← →
Anatoly Podgoretsky © (2005-07-27 08:52) [62]Если надо что бы было почти полное подобие xBase то именно через вычислимое поле и надо, там оно является не функцией, а именно полем _DELETED_, вроде такое имя если память не подводит.
Наличие поля упрощает всю остальную обработку.
← →
АМБ (2005-07-27 09:36) [63]
> 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;
не помогает...
← →
sniknik © (2005-07-27 11:33) [64]ладно, допустим это работает... т.к. нет функции MyCalcField, нет такого типа Calculated и это не позволит коду даже скомпилится.
кстати ошибка при повторном открытии у тебя от того, что
tblDBF.FieldDefs[i].CreateField(Self);
это функция. которая возвращает результат (кстати! ;) ... ты его теряеш, но от того что ты на созданные обьекты не обращаеш внимания, они существовать не перестанут...
(в принципе ссылки на них можно и из таблици вытащить, гдето они должны сохранятся)
второй метод о котором я говорил это просто доведенная до логического завершения мысль ANB, он пытался получить информацию из файла (но как тогда связь записей в файле с табличным делать? и зачем если можно проще), я получаю тоже самое из внутреннего буфера самой таблицы ActiveBuffer (строка записи "as is", до разбора на составляющие (поля), в ней признак "*" еще есть.)
все в общемто. думаю достаточно. (кстати тоже не всегда соответствует действительности... если тупо заменить Deleted() в событии по вычисляемому полю на проверку по нему тоже дает неверный результат... странно (может глюк. второйраз проверять не хочется). в событии DrawColumnCell зато соответствие полное)
← →
АМБ (2005-07-27 12:08) [65]Точно... Переносил код через буфер, а он в окошке не помещалься, да и ремарки на русском не переносились, вот и "напортачил".
Конечно: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 12:31) [66]> свободен от нынешней ошибки при переоткрытии таблицы...
ошибка при переоткрытии твоя, метод не причем. созданные обьекты надо уничтожать.
а уж будет или нет... как напишеш. (правда в 1-й строчке ошибку сделать труднее чем в пяти/десяти ;о)))
у тебя еще и в отрисовке эти
TDBGrid(Sender).Canvas.FillRect(Rect);
TDBGrid(Sender).Canvas.TextOut(Rect.Left,Rect.Top,Column.Field.Text);
строки лишние.
← →
АМБ (2005-07-27 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;
Теперь разные таблицы переоткрываются без ошибок и все, вроде бы, пока хорошо.
А насчет лишних линий при отрисовки ячеек, я это взял из примера статей, которые рекомендовали в этом форуме. Подозревал, что они могут быть излишне, но еще не проверял на практике. Сейчас проверил. Вы правы. Работает и без них.
Так что еще раз БОЛЬШОЕ СПАСИБО!
:о))))
← →
АМБ (2005-07-29 10:59) [68]Извините за назойливость... Но мы забыли вторую часть вопроса:
"... а затем, выбрав какую-нибудь запись - восстановить ее, т.е. снять пометку на удаление."
Подскажите, пожалуйста.
← →
ANB © (2005-07-29 11:09) [69]Надо заменить * на пробел
← →
АМБ (2005-07-29 11:23) [70]Да, об этом я догадывалься ;о)
Согласно Вашей методике
> Опять же польза - учимся работать с файлами БД напрямую.
, так, я думаю, и надо делать. Правда, я ее еще не освоил, хотя за исходники спасибо.
А нет ли функций, типа UnDelete?
← →
sniknik © (2005-07-29 11:28) [71]ты в хелп так и не научился заглядывать? ;) BDE-шная функция DbiUndeleteRecord
но подозреваю могут быть опять проблемы ;о)), изза тогоже несоответствия...
а попробуй в ActiveBuffer исправить. получится?
← →
АМБ (2005-07-29 13:53) [72]Да. Вариант с 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;
Проходит без ошибок, но запись не удаляет.
Продолжаю разбираться... Но, если подскажите, то буду рад...:о)
← →
АМБ (2005-07-29 13:55) [73]Прощу прощения. Ошибся.
> но запись не удаляет.
т.е. запись не восстанавливается.
← →
АМБ (2005-07-29 14:04) [74]Спешу поделиться радостью...;о)))
Немного изменил процедуру:
tblDBF.Edit;
sBuffer := tblDBF.ActiveBuffer;
ShowMessage(tblDBF.ActiveBuffer[0]);
tblDBF.ActiveBuffer[0]:=" ";
ShowMessage(tblDBF.ActiveBuffer[0]);
tblDBF.Post;
Все заработало... Пока...
Большое СПАСИБО > sniknik
← →
sweet lou (2005-09-05 14:39) [75]интересные тут такие рассуждения были.......но я так и не понял, как же сделать чтобы в моем гриде удаленные записи отличались другим цветом!!!!
← →
Anatoly Podgoretsky © (2005-09-05 16:00) [76]Так это надо рисовать в OnDrawCell - кстати а ты то тут причем, этот вопрос от АМБ
А тебе надо задать свой вопрос как рисовать строки другим цветом или посмотреть в каком ни будь Чаво, ими просто завален Интернет да и в справке есть пример.
← →
Kacnep © (2005-10-07 11:30) [77]
АМБ (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и часов :((
Блин перепробовал все.
← →
Seg (2005-10-07 11:39) [78]Как организовать просмотр помеченных на удаление записей в DBF таблице? Т.е. сначала, записи обрабатываются tblDBF1.Delete; и становятся невидимы в DBGrid-е. Как сделать их видимыми, да еще и другим цветом, или как-то еще их выделить, а затем, выбрав какую-нибудь запись - восстановить ее, т.е. снять пометку на удаление.
Добавляешь еще одно поле в таблицу например DELETED.
Для удаленных записей устанавливаешь 1, для неудаленных 0.
Таким образом ты можещь показывать
1.Все неудаленные
2.Все удаленные
3.Все удаленные и неудаленные.
4.Ничего не показывать
С обработчиком строк (раскраской) тоже не должно возникнуть проблем.
Ну и установку/отмену статуса строки тоже легко можно реализовать.
← →
Kacnep © (2005-10-07 12:04) [79]Да у меня вопрос не в удаленных зхаписях
а в
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.
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.047 c