var
Form1: TForm1;
implementation
{$R *.DFM}
procedureTForm1.FormCreate(Sender: TObject);
begin
Session.Open; // В это вpемя сессия ещё не откpыта
CBack := TBDECallback.Create(Session {Hапpимеp}, nil, cbINPUTREQ, @CBRegBuf, SizeOf(CBBuf), CBFunc, False); // Опpеделили Callback
Table1.Open;
//^^^^^^^^^^^ - здесь возможна ошибка с индексом, etc.
end;
procedureTForm1.FormDestroy(Sender: TObject);
begin
CBack.Free; // Освобождаем CallBack
end;
functionTForm1.CBFunc(CBInfo: Pointer): CBRType;
begin
withPCBInputDesc(CBInfo)^ do caseeCbInputId of
cbiMDXMissing {, cbiDBTMissing - можно ещё и очищать BLOB-поля}:
begin
iSelection := 3; // Hомеp ваpианта ответа (1-й - откpыть только
// для чтения, 2-й - не откpывать, 3-й - отсоединить индекс).
// Возможный источник непpиятностей: а вдpуг в последующих веpсиях
// BDE номеpа будут дpугими?
Result := cbrCHKINPUT; // Обpабатывать введённый ответ
end;
end;
end;
end.
=== Callback.pas ===
PS: конечно, это лишь пример, делающий минимум необходимого. В рамках данного письма невозможно дать какое-то описание BDE Callbacks. Информацию я взял из BDE32.HLP, BDE.INT и DB.PAS. В VCL.HLP совсем ничего нет по этому поводу.
Вообще, руки бы оторвал тем, кто писал справку по Дельфям: я неделю мучался с сабжем, пока случайно не набрёл на Callbacks.
Определение удаления записей в .DBF
Взято из "Dtopics Database 1.10 from 3K computer Consultancy":
Dbase в BDE имеет большее количество ситуаций 'особого случая', чем таблицы SQL и Paradox, поскольку данный формат поддерживает выражения в индексах и прочие характеристики, например:
1. Создание и пересоздание индекса
– DbiRegenIndexes( Table1.Handle ); { Регенерация всех индексов }
– создание индекса (зависит от того, существует ли выражение или нет)
if((Pos('(',cTagExp) + Pos('+',cTagExp)) > 0) thenTable1.AddIndex(cTagName, cTagExp, [ixExpression]) ( <���– ixexpression – _литерал_)
elseTable1.AddIndex(cTagName, cTagExp, []);
2. Связки Master/Detail в выражениях дочерних индексов
– вызов процедуры BDE DbiLinkDetailToExp() вместо обычной DbiLinkDetail()
3. Пакование таблиц
withTable1 doStrPCopy(TName, TableName);
Result := DBIPackTable(DbHandle, Handle, TName, szDBASE, TRUE);
4. Задание видимости удаленных записей – вкл/выкл (например, dBase SET DELETED ON/OFF)
DbiSetProp( hDBIObj(Table1.Handle), curSOFTDELETEON, LongInt(bValue));
5. Задание частичного/полного соответствия символов – вкл/выкл (например, dBase SET EXACT ON/OFF)
DbiSetProp( hDBIObj(Table1.Handle), curINEXACTON, LongInt(bValue));
<���– Конец –>
Ну и теперь сами вопросы:
<���– Начало –>
«Как мне увидеть записи dBASE, помеченные для удаления?»
В обработчике события AfterOpen вызовите приведенную ниже функцию. Включите DBITYPES, DBIERRS, DBIPROCS в список используемых модулей. Для вызова функции передайте ей в качестве аргумента имя TTable и TRUE/FALSE в зависимости от необходимости показа/скрытия удаленных записей. Пример:
procedureTForm1.Table1AfterOpen(DataSet: TDataset);
begin
SetDelete(Table1, TRUE);
end;
procedureSetDelete(oTable:TTable; Value: Boolean);
var
rslt: DBIResult;
szErrMsg: DBIMSG;
begin
try
Table.DisableControls;
try
rslt := DbiSetProp(hDBIObj(oTable.Handle), curSOFTDELETEON,LongInt(Value));
ifrslt <> DBIERR_NONE then
begin
DbiGetErrorString(rslt, szErrMsg);
raiseException.Create(StrPas(szErrMsg));
end;
exceptonE: EDBEngineError doShowMessage(E.Message);
onE: Exception doShowMessage(E.Message);
end;
finally
Table.Refresh;
Table.EnableControls;
end;
end;
«Могу ли я создать в табличной сетке колонку, в которой будут показываться записи, помеченные для удаления из таблицы dBASE?»
Создайте вычисляемое поле, затем в обработчике события таблицы OnCalcField замените его таким образом:
procedureTForm1.Table1CalcFields(DataSet: TDataset);
var
RCProps : RecProps;
Result : DBIResult;
begin
Result := DbiGetRecord(Table1.Handle, dbiNo
Рукописи не горят…
Определение номера записи в таблице dBASE
Таблицы dBASE применяют довольно статическую систему нумерации записей. Номер записи для данной записи (извините за тавтологию) отражает физическую позицию в табличном файле. Эти номера записей не изменяются вследствие фильтрации, упорядочивания данных или сортировки. К примеру, первая запись, хранящаяся в .DBF файле, будет иметь номер записи 1. Возможно, после некоторого упорядочивания индекса, запись будет последней из 100 записей. В этом случае запись должна оставаться с тем же номером, а не номером 100, отражающим новую позицию в сортированном наборе данных. Это противоречит таблицам Paradox, где соблюдается последовательная нумерация. Последовательная нумерация Paradox похожа на нумерацию записей dBASE, за исключением большей гибкости и отражению в номере записи ее текущей позиции в наборе данных. То есть, запись может не всегда иметь номер, установленный для нее фильтром набора данных, уменьшившим общее число записей, или при активном индексе, из-за чего может измениться отображаемый порядок записи.
Читать дальше