functionAgeStr(aDate: TDateTime): string;
var
DaysOld: Double;
Years, Months: Integer;
begin
DaysOld:= Date – aDate;
Years:= Trunc(DaysOld / 365.25);
DaysOld:= DaysOld – (365.25 * Years);
Months:= Trunc(DaysOld / 30.41);
Result:= Format('%d лет, %d месяцев',[Years, Months]);
end;
В моем случае метод OnCalcFields выглядит так:
procedureTEntryForm.TableNameOrderCalcFields(DataSet: TDataset);
begin
TableNameOrderAge.AsString := AgeStr(TableNameOrderDateOfBirth.AsDateTime);
end;
Как пересчитать все вычисляемые поля (Calculated fields) без переоткрытия TDataSet?
Nomadicотвечает:
Resync([rmExact, rmCenter]);
Как создать вычисляемые поля во время исполнения программы (Calculated fields at RunTime)?
Nomadicотвечает:
Смотрите книгу "Developing Custom Delphi Components" от Рэя Конопки.
Здесь немного исправленный пример из этой книги
functionTMyClass.CreateCalcField( constAFieldName: string; AFieldClass: TFieldClass; ASize: Word): TField;
begin
Result := FDataSet.FindField( AFieldName ); // Field may already exists!
ifResult<> nil thenExit;
ifAFieldClass = nil then
begin
DBErrorFmt( SUnknownFieldType, [AFieldName] );
end;
Result := FieldClass.Create( Owner );
withResult do
try
FieldName := AFieldName;
if(Result isTStringField) or(Result isTBCDField) or(Result isTBlobField) or(Result isTBytesField) or(Result isTVarBytesField) then
begin
Size := ASize;
end;
Calculated := True;
DataSet := FDataset;
Name := FDataSet.Name + AFieldName;
except
Free; // We must release allocated memory on error!
raise;
end;
end;
Хитрости многопользовательского доступа к БД
Вот некоторые хитрости, могущие помочь в разработке баз многопользовательского доступа:
В модуле DBIPROCS Delphi 1.0 и в BDE.INT 2.0 существует классная функция с именем DBISETLOCKRETRY(n).
Синтаксис – DBISetLockRetry(n), где n – количество секунд ожидания перед повторной попыткой вставки, редактирования или другой операцией с таблицей. DBISetLockRetry(-1) будет бесконечно пытаться получить доступ к вашей таблице.
Хорошее место для вызова функции – обработчик события TableAfterOpen. В этом случае все, что вам нужно сделать, это:
DBISetLockRetry(x);
Если вы используете Delphi 1.0, не забудьте включить в вашу программу DBIProcs. В Delphi 2.0 включите BDE.
Мой заказчик и я разработали многопользовательскую базу данных по вашему рецепту, до этого наши пользователи получали сообщения «File is Locked» (файл заблокирован), «Table is Busy» (таблица занята), «Record Locked» (запись заблокирована) и др. Мы также пробовали Session.Netdir, но он не помог нам. Поскольку мы добавили в код эту строку, никаких блокировок не было. Частота обращений пользователей к базе достаточно велика (80 kpm). Мы разработали «измеритель скорости доступа» с 2 открытыми сессиями на двух компьютерах в сети Novell 4.1. Две сессии занимались вставкой, две другие редактированием, а мы сами занимались посылкой данных с частотой около 65 записей в минуту в течение операций редактирования и 85 в течение вставки. Сеть чуть не захлебнулась от такой работы. Утилизация файлового сервера была до нас около 60%. Не плохо для всего! Я думаю Borland необходимо задокументировать такой подход, чтобы другие не становились хакерами типа нас! :)
Эти требования обязательны при разработке многопользовательских приложений Delphi с использованием файлов Dbase или Paradox.
– Ted Bulmanski
Выполнение запросов к базе данных в фоне
Тема: Выполнение запросов к базе данных в фоновом потоке
Данный документ объясняет как выполнить запрос в фоновом режиме, используя класс TThread. Для получения общей информации о классе TThread, пожалуйста обратитесь к документации Borland и электронной справке. Для понимания данного документа вам необходимо иметь представление о том, как работать с компонентами для работы с базами данных, поставляемых в комплекте с Delphi 2.0.
Для осуществления потокового запроса необходимо выполнение двух требований. Во-первых, потоковый запрос должен находиться в своей собственной сессии с использованием отдельного компонента TSession. Следовательно, на вашей форме должен находиться компонент TSession, имя которого должно быть назначено свойству SessonName компонента TQuery, используемого для выполнения потокового запроса. Для каждого используемого в потоке компонента TQuery вы должны использовать отдельный компонент TSession. При использовании компонента TDataBase, для отдельного потокового запроса должен также использоваться отдельный TDataBase. Второе требование заключается в том, что компонент TQuery, используемый в потоке, не должен подключаться в контексте это потока к TDataSource. Это должно быть сделано в контексте первичного потока.
Читать дальше