Особенно интересует Refresh для связки Master-Detail.
Nomadicотвечает:
Старо как мир, и нет ничего военного:
procedureRefreshQuery(Query: TQuery; F: boolean);
varB: TBookMark;
begin
withQuery do ifQuery.Active then begin
B := GetBookMark;
try
Close;
Unprepare; {Если не поставить этого, то если используется select SP, то иногда последующая операция вешает сервер. Кто скажет почему?!}
Active:=True;
ifF then begin
try
GotoBookMark(B)
except onEDatabaseError doFirst;
end
end elseFirst;
finally
FreeBookmark(B);
end;
end;
end;
Уфф! Кажется, лучше уже не сделать. :)
dbtables можно опционально пропатчить (см. в конце), чтобы иметь такой вот рyлезный Detail query.
Update for dbtables.pas
New interface function DoRefreshQuery can Refresh TQuery component in master-detail scheme and alone.
TQuery.RefreshParams should be updated
functionGetFieldNamesStr(DataSet: TDataSet): String;
varI: Integer;
begin
Result := '';
withDataSet do forI := 0 toFieldCount - 1 do begin
Result := Result + Fields[ I ].FieldName + ';';
end;
end;
procedureDoRefreshQuery(Query: TQuery; KeyFields: String; BookMarkSearch: Boolean);
var
Fields: TList;
KeyValues: Variant;
KeyNames: String;
Bmk: TBookmark;
I: Integer;
BookmarkFound: Boolean;
CanLocate: Boolean;
begin
Fields := TList.Create;
ifKeyFields = '' thenKeyFields := GetFieldNamesStr(Query);
try
Query.GetFieldList(Fields, KeyFields);
forI := Fields.Count - 1 downto0 do withTField(Fields[I]) do
ifCalculated orLookup thenFields.Delete(I);
CanLocate := Fields.Count > 0;
ifCanLocate then begin
if Fields.Count = 1 thenKeyValues := TField(Fields[0]).Value
else begin
KeyValues := VarArrayCreate([0, Fields.Count - 1], varVariant);
KeyValues[0] := TField(Fields[0]).Value;
end;
KeyNames := TField(Fields[0]).FieldName;
forI := 1 toFields.Count - 1 do begin
KeyNames := KeyNames + ';' + TField(Fields[I]).FieldName;
KeyValues[I] := TField(Fields[I]).Value;
end;
end;
finally
Fields.Free;
end;
withQuery do begin
Bmk := nil;
DisableControls;
try
BookmarkFound := False;
ifBookMarkSearch thenBmk := GetBookmark;
Close;
Open;
ifAssigned(Bmk) then try
GotoBookMark(Bmk);
BookmarkFound := True;
except
end;
if notBookmarkFound andCanLocate thenLocate(KeyNames, KeyValues, []);
finally
EnableControls;
Screen.Cursor := crDefault;
FreeBookmark(Bmk);
end;
end;
end;
procedureTQuery.RefreshParams;
varDataSet: TDataSet;
begin
DisableControls;
try
ifFDataLink.DataSource <> nil then begin
DataSet := FDataLink.DataSource.DataSet;
ifDataSet <> nil then
ifDataSet.Active and(DataSet.State <> dsSetKey) then
DoRefreshQuery(Self, GetFieldNamesStr(Self), False);
end;
finally
EnableControls;
end;
end;
Как заставить BDE сохранять в БД поле времени с сотыми долями секунды?
Nomadicотвечает:
Если руками, то в BDE Administrator (BDE Configuration Utility).
Если при инсталляции твоей программы, то –
В пункте Make Registry Changes InstallShield'а создай ключ
HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\TIME\MILSECONDS=TRUE
Запись буфера BDE на диск
Общее:
Сделанные в таблице изменения непосредственно на диск не записываются до тех пор, пока таблица не будет закрыта. Потеря питания или сбой в системе может привести к потере данных и прочим неприятностям. Чтобы избежать этого, существует два прямых вызова Database Engine, дающих один и тот же результат. Эти функции – DbiUseIdleTime и DbiSaveChanges.
DbiSaveChanges(hDBICur):
DbiSaveChanges сохраняет на диске все обновления, находящиеся в буфере таблицы, связанной с курсором (hDBICur). Может быть вызвана из любого места программы. Например, можно при каждом обновлении записи сохранять на диске все изменения (добавьте dbiProcs в список используемых модулей):
Читать дальше