Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как изменить формат вывода времени в TDBGrid в Delphi для отображения "чч:мм"

Delphi , Компоненты и Классы , TDBGrid

 

При работе с базами данных в Delphi, особенно при использовании компонентов FireDAC и TDBGrid, разработчики часто сталкиваются с необходимостью кастомизации отображения данных. В данной статье рассмотрим проблему корректного отображения времени в формате "чч:мм" при работе с полем типа TIME(7) в Microsoft SQL Server.

Проблема

Как видно из обсуждения на форуме, пользователь столкнулся со следующей ситуацией: - Используется Delphi 12.2 с FireDAC - Подключение к MS SQL Server 2008 - В таблице имеется поле Hour типа TIME(7) - При получении данных все поля автоматически преобразуются в WideString - Не удается установить DisplayFormat для корректного отображения времени

Причины проблемы

Основная причина, как выяснилось в ходе обсуждения, связана с используемым драйвером ODBC. Старые версии драйверов (до ODBC 18) не всегда корректно распознают тип TIME(7) и автоматически преобразуют его в WideString.

Решения

1. Использование статических полей и DisplayFormat

Первый и наиболее правильный способ - создание статических полей для запроса:

// Вручную создаем поле в Query
var
  TimeField: TTimeField;
begin
  TimeField := TTimeField.Create(FDQuery1);
  TimeField.FieldName := 'Hour';
  TimeField.DataSet := FDQuery1;
  TimeField.DisplayFormat := 'hh:nn'; // nn для минут (mm - это месяц)
end;

Однако, как показал опыт пользователя, этот метод может не сработать, если драйвер неправильно определяет тип данных.

2. Использование CAST в SQL-запросе

Альтернативный подход - изменение типа данных прямо в SQL-запросе:

// Изменяем исходный запрос
const
  sql_Base =
    'SELECT '+
    '  m.ID, m.ForWho, m.Dates, m.Category, m.Sum, m.Notes, '+
    '  CAST(m.Hour AS VARCHAR(8)) AS Hour, '+
    '  cat.Name AS Categories, t.Name AS City,'+
    '  c.Name AS FirmName, c.EIK AS FirmEIK, c.Address AS FirmAddress, '+
    '  c2.Name AS ToFirmName '+
    'FROM CD_Main m '+
    '  LEFT JOIN CD_Category cat ON (cat.ID = m.Category) '+
    '  LEFT JOIN CD_Town t ON (t.ID = m.Town) '+
    '  LEFT JOIN CD_Company c ON (c.ID = m.Firma) '+
    '  LEFT JOIN CD_Company c2 ON (c2.ID = m.ToFirm)';

3. Обработка события OnGetText

Если предыдущие методы не работают, можно обработать событие OnGetText для поля:

procedure TForm1.FDQuery1HourGetText(Sender: TField; var Text: string;
  DisplayText: Boolean);
begin
  if not Sender.IsNull then
    Text := Copy(Sender.AsString, 1, 5) // Берем первые 5 символов (чч:мм)
  else
    Text := '';
end;

Не забудьте назначить обработчик события:

FDQuery1.FieldByName('Hour').OnGetText := FDQuery1HourGetText;

4. Обновление драйвера ODBC

Как советовали в обсуждении, можно попробовать установить более новый драйвер ODBC (версии 18 или выше), но это требует Delphi 11.2 или новее.

// Настройка соединения для использования нового драйвера
FDConnection1.Params.Values['ODBCDriver'] := 'ODBC Driver 18 for SQL Server';

Альтернативное решение: вычисляемое поле

Если ни один из методов не работает, можно добавить вычисляемое поле:

// В событии AfterOpen запроса
procedure TForm1.FDQuery1AfterOpen(DataSet: TDataSet);
var
  CalcField: TStringField;
begin
  CalcField := TStringField.Create(FDQuery1);
  CalcField.FieldKind := fkCalculated;
  CalcField.FieldName := 'FormattedHour';
  CalcField.Size := 5;
  CalcField.DataSet := FDQuery1;

  FDQuery1.FieldByName('FormattedHour').OnGetText := GetFormattedHourText;
end;

procedure TForm1.GetFormattedHourText(Sender: TField; var Text: string;
  DisplayText: Boolean);
begin
  if not FDQuery1.FieldByName('Hour').IsNull then
    Text := Copy(FDQuery1.FieldByName('Hour').AsString, 1, 5)
  else
    Text := '';
end;

Заключение

Проблема с отображением времени в TDBGrid может быть вызвана различными факторами, но в большинстве случаев ее можно решить одним из предложенных способов. Оптимальным решением является либо обновление драйверов ODBC, либо использование CAST в SQL-запросе. Если эти варианты недоступны, обработка события OnGetText предоставляет надежное решение, хотя и менее элегантное.

Не забывайте, что при работе с временными типами в SQL Server важно учитывать версию сервера и используемые драйверы, так как они могут влиять на поведение FireDAC при получении метаданных о типах полей.

Создано по материалам из источника по ссылке.

Статья описывает способы изменения формата вывода времени в TDBGrid в Delphi для отображения в формате "чч:мм" при работе с полем типа TIME(7) в Microsoft SQL Server.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TDBGrid ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-02 03:42:48/0.003558874130249/0