Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001
Пакование таблиц dBASE II
Упаковка таблиц dBASE требует вызова BDE функции DbiPackTable. Пример ее использования показан ниже, включая проверку на ошибки. Чтобы воспользоваться функцией DbiPackTable, вызывающий модуль должен в своей секции uses иметь модули-обертки BDE DbiTypes, DbiErrs и DbiProcs.
При неудачном вызове DbiPackTable, сообщение об ошибке не генерится. Для того, чтобы понять как функция сработала, вам необходимо проверить возвращаемое ею значение. В случае успешного выполнения возвращаемое значение равно DBIERR_NONE. Любое другое значение указывает на ошибку, а с помощью него можно определить саму ошибку, ее причину, и наметить действия, необходимые для ее устранения.
Вот сам пример:
procedure TForm1.Button1Click(Sender: TObject);
var
Error: DbiResult;
ErrorMsg: String;
Special: DBIMSG;
begin
table1.Active := False;
try
Table1.Exclusive := True;
Table1.Active := True;
Error := DbiPackTable(Table1.DBHandle, Table1.Handle, nil, szdBASE, True);
Table1.Active := False;
Table1.Exclusive := False;
finally
Table1.Active := True;
end;
case Error of
DBIERR_NONE: ErrorMsg := 'Успешно';
DBIERR_INVALIDPARAM: ErrorMsg := 'Указанное имя таблицы или указатель на имя таблицы ' +'равен NULL';
DBIERR_INVALIDHNDL: ErrorMsg := 'Указанный дескриптор базы данных или курсора ' +'неверен или равен NULL';
DBIERR_NOSUCHTABLE: ErrorMsg := 'Таблица с таким именем не существует';
DBIERR_UNKNOWNTBLTYPE: ErrorMsg := 'Неизвестный тип таблицы';
DBIERR_NEEDEXCLACCESS: ErrorMsg := 'Таблица открыта не в эксклюзивном режиме';
else
DbiGetErrorString(Error, Special);
ErrorMsg := '[' + IntToStr(Error) + ']: ' + Special;
end;
MessageDlg(ErrorMsg, mtWarning, [mbOk], 0);
end;
Пакование таблиц dBASE III
Для упаковки таблицы dBASE, открытой с помощью TTable, воспользуйтесь функцией BDE DbiPackTable. Для этого достаточно сделать две операции:
1. Добавьте в секцию uses следующие модули:
{ Для Delphi 1.0: } DBITYPES, DBIPROCS и DBIERRS;
{ Для Delphi 2.0: } BDE;
2. Затем вызовите BDE функцию DbiPackTable следующим образом:
Check(DbiPackTable(Table1.DbHandle, Table1.Handle, Nil, szDBASE, TRUE));
Примечания:
• Таблица должна быть открыта в эксклюзивном режиме.
• При вызове функций API BDE используйте процедуру Check. Check в случае ошибки при вызове BDE генерирует исключительную ситуацию.
Пакование таблиц dBASE IV
Nomadic советует:
Для dBase:
uses DbiProcs;
with table do
begin
OldState := Active;
Close;
Exclusive := True;
Open;
DbiPackTable(DBHandle, Handle, nil, nil, True);
{^ здесь можно добавить check()}
Close;
Exclusive := False;
Active := OldState;
{ при желании можно сохранить закладку }
end;
Pavel Kulchenko
(2:465/66)
Пример для Paradox:
Uses BDE; // for d3, для d2 не помню (что-то типа dbiprocs и еще что-то)
// для пpимеpа
tLog : TTable; // таблица, юзающая d:dblog.db
var
TblDesc: CRTblDesc;
rslt: DBIResult;
Dir: String; //имеется в виду huge string т.е. {$h+}
hDb: hDbiDb;
begin
tLog.Active := False; //деактивиpуем TTable
SetLength(Dir, dbiMaxNameLen + 1);
DbiGetDirectory(tLog.DBHandle, False, PChar(Dir));
SetLength(Dir, StrLen(PChar(Dir)));
DbiOpenDatabase(nil, nil, dbiReadWrite, dbiOpenExcl, nil, 0, nil, nil, hDb);
DbiSetDirectory(hDb, PChar(Dir));
FillChar(TblDesc, sizeof(CRTblDesc), 0);
StrPCopy(TblDesc.szTblName, 'd:dblog.db');
// здесь должно быть полное имя файла
//котоpое можно: а) ввести pуками;
//б) вытащить из пpопеpтей таблицы;
//в) вытащить из алиаса;
//г) см. FAQ
StrCopy(TblDesc.szTblType, szParadox);
//BTW тут может и szDBase стоять
TblDesc.bPack := TRUE;
DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, false);
DbiCloseDatabase(hDb);
end;
// можно еще чеки ввести, но облом :-)
Показ удаленных записей в таблице dBASE
В таблицах dBASE записи не удаляются до тех пор, пока таблица не будет упакована. Пока же это не произойдет, удаленные записи остаются в таблице, только имеют при этом флажок "к удалению". Для того, чтобы показать эти существующие, но не отображаемые записи, существует функция ShowDeleted(), которая использует функцию BDE API DbiSetProp(), показывающая записи, помеченные к удалению. При использовании этой функции нет необходимости закрывать и вновь открывать таблицу. ShowDeleted() в качестве параметров передается TTable и логическое значение. Логический параметр указывает на необходимость показа удаленных записей.
Демонстрационный проект:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, DB, DBTables;
type
TForm1 = class(TForm)
Table1: TTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
CheckBox1: TCheckBox;
procedure CheckBox1Click(Sender: TObject);
public
procedure ShowDeleted(Table: TTable; ShowDeleted: Boolean);
end;
var
Form1: TForm1;
implementation
uses DBITYPES, DBIERRS, DBIPROCS;
{$R *.DFM}
procedure TForm1.ShowDeleted(Table: TTable; ShowDeleted: Boolean);
var
rslt: DBIResult;
szErrMsg: DBIMSG;
begin
Table.DisableControls;
try
Check(DbiSetProp(hDBIObj(Table.Handle), curSOFTDELETEON, LongInt(ShowDeleted)));
finally
Table.EnableControls;
end;
Table.Refresh;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
ShowDeleted(Table1, CheckBox1.Checked);
end;
end.
Пароль на dBASE-файлы
Delphi 1
dBase-файлы не поддерживают пароли. Естественно, вы можете создать свои собственные методы поддержки паролей. Но это будет работать только с вашими приложениями. Боюсь, что при наличии тысяч читателей/конверторов dBase, этот способ не годится.
Показ меток 'удаленных' записей в dBASE-файлах
Delphi 1
Для начала вы должны включить SoftDeletes, после чего вы сможете просматривать записи, помеченные к удалению. В противном случае, вы их не увидите. По умолчанию, для файлов DBF, SoftDeletes установлен в False. Вот логика работы:
procedure TForm1.Button1Click(Sender: TObject);
var
B: BOOL;
W: Word;
begin
Check(DbiSetProp(hDBIObj(Table1.Handle), curSOFTDELETEON, longint(True)));
{ Проверяем, что это работает }
Check(DbiGetProp(hDBIObj(Table1.Handle), curSOFTDELETEON, @B, sizeof(B), W));
if B = False then Label2.Caption := 'Не помечена'
else Label2.Caption := 'Помечена';
end;
Когда указатель на запись указывает на запись, которую вы хотите удалить, используйте следующую логику:
Table1.UpdateCursorPos;
Check(DbiUndeleteRecord(Table1.Handle));
Метод UpdateCursorPos устанавливает основной курсор BDE на позицию курсора текущей записи, который существуют только для того, чтобы все работало правильно. Вам нужно только вызвать этот метод прямым вызовом одной из BDE API функций (такой как, например, DbiUndeleteRecord).
Ну и, наконец, чтобы все работало, поместите модули DBIPROCS и DBITYPES с список USES.
DB2
Как заставить работать DB2 через протокол IPX?
Nomadic отвечает:
Связь Win-клиента c DB2 в сети Netware
Hастройка доступа к DB2
1. Связь с использованием протокола IPX/SPX.Возможны два варианта доступа:
• через сервер NETWARE;
• прямая адресация.
1.1. Конфигурация для доступа через сервер.Замечание: Проверялся доступ через сервера NW 3.11 и 3.12. Для 4.х нужно еще разобраться.
1.1.1. DB2 Сервер
• должна быть установлена OS/2 Warp или OS/2 Warp Connect;
• включена поддержка NETWARE;
• в CONFIG.SYS в переменную среды DB2COMM добавить (через запятую) IPXSPX и перезагрузить систему;
• создать командный файл DBIPXSET.CMD следующего вида:
db2 update dbm cfg using fileserver objectname dbserver