Сортировка по дате в Tdbf

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
Petrakoff Sergey
новенький
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Сортировка по дате в Tdbf

Сообщение Petrakoff Sergey »

Не удается отсортировать записи по дате при использовании компонента Tdbf.
Если указать

Код: Выделить всё

Dbf2.IndexFieldNames:= 'DATPRIH'

где 'DATPRIH' - это имя поля типа ftDate, то сортировка не происходит.
Пытаюсь создать индекс

Код: Выделить всё

Dbf2.AddIndex('IND_DATPRIH', 'DATPRIH', []);

Выдается ошибка - "Invalid index type: can only be string or float"
А если сделать преобразование

Код: Выделить всё

var
  date_string: string;
begin
  date_string:= DateToStr(Dbf2.FieldByName('DATPRIH').AsDateTime);
  Dbf2.AddIndex('IND_DATPRIH', date_string, []);

Выдается ошибка - "Missing operator between '01,02' and '01,02'"
Как же отсортировать базу по дате?
sign
энтузиаст
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Сообщение sign »

Срочно переходите на MySQL.
И не будет у вас никаких проблем.
Я как перешёл, так прям другой жизнью зажил.
Petrakoff Sergey
новенький
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Сообщение Petrakoff Sergey »

Спасибо за совет! Но мне нужен ответ по существу!
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Petrakoff Sergey писал(а):Выдается ошибка - "Invalid index type: can only be string or float"

Логично предположить, что когда Вы создаёте индекс, нужно тип Date преобразовать в тип String:

Код: Выделить всё

Dbf2.AddIndex('IND_DATPRIH', 'DTOS(DATPRIH)', []);
sign
энтузиаст
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Сообщение sign »

Petrakoff Sergey писал(а):Спасибо за совет! Но мне нужен ответ по существу!

Ну, тогда лёгких вам граблей на вашем нелёгком пути.
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Сообщение Ichthyander »

Серьезно, я сам намучился с этим DBF. Тоже не слушал поначалу более опытных )) Если Вам нужна локальная база данных используйте, к примеру, SQLite. В DBF преобразовывал дату-время в строки для сортировки
Petrakoff Sergey
новенький
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Сообщение Petrakoff Sergey »

Vadim писал(а):Логично предположить, что когда Вы создаёте индекс, нужно тип Date преобразовать в тип String:

Код: Выделить всё

Dbf2.AddIndex('IND_DATPRIH', 'DTOS(DATPRIH)', []);

Спасибо! Так работает. Но остаются непонятки. В частности, я впервые вижу вызов функции таким образом. Более "привычно" выглядит вызов таким образом

Код: Выделить всё

Dbf2.AddIndex('IND_DATPRIH', DTOS('DATPRIH'), []);
На что Lazarus вежливо сообщает, что не знает такой функции

Код: Выделить всё

unit1.pas(63,36) Error: Identifier not found "DTOS"

Во-вторых, почему не прокатывает способ, которым я пытался делать вначале, т.е.

Код: Выделить всё

date_string:= DateToStr(Dbf2.FieldByName('DATPRIH').AsDateTime);
  Dbf2.AddIndex('IND_DATPRIH', date_string, []);

Где-то на этом форуме видел, что мол не стоит использовать функцию DTOS(), она вроде устарела.
Кроме того, на этом же форуме наткнулся на тему "TDBF.Filter по двум значениям" и там увидел пример установки фильтра

Код: Выделить всё

    Dbf1.Filter:='(DTOS(Data)>"'+DataStrNach+'") and (DTOS(Data)<"'+DataStrKon+'")';

От обилия кавычек, двойных и одинарных, зарябило в глазах.
Где можно почитать про то, как надо правильно расставлять эти кавычки? Понимаю, что вопрос слишком "наивный". Не ругайте меня сильно! Я только начал изучать БД и вообще Lazarus.
Что касается, почему я вначале остановил свой выбор на DBF - трудно однозначно ответить, что повлияло на мой выбор.
Во всяком случае, я уже достаточно "глубоко" влез в это дело. Сворачивать с полпути не в моем характере. В дальнейших моих планах и SQLite и FireBird и, конечно же, MYSQL.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Petrakoff Sergey писал(а): Но остаются непонятки. В частности, я впервые вижу вызов функции таким образом. Более "привычно" выглядит вызов таким образом
Dbf2.AddIndex('IND_DATPRIH', DTOS('DATPRIH'), []);
На что Lazarus вежливо сообщает, что не знает такой функции

Lazarus Вас упрекает совершенно справедливо. ;) Потому, что название этой функции обрабатывает парсер компонента TDbf и потом уже преобразовывает в стандартную FreePascal'евскую функцию преобразования даты в строку. Это сделано для обратной совместимости со старыми базами, т.к. индексное выражение хранится прямо в файле индекса самым обычным текстом. Можете посмотреть, если хотите, открыв файл индекса в каком-нибудь текстовом редакторе.
Petrakoff Sergey писал(а):Во-вторых, почему не прокатывает способ, которым я пытался делать вначале, т.е.
Код: Выделить всё
date_string:= DateToStr(Dbf2.FieldByName('DATPRIH').AsDateTime);
Dbf2.AddIndex('IND_DATPRIH', date_string, []);

Именно по причине, которую я описал выше. ;)
Petrakoff Sergey писал(а):Где-то на этом форуме видел, что мол не стоит использовать функцию DTOS(), она вроде устарела.

Если Вы категорически настаиваете на использовании DBF, то иной альтернативы построить индекс, не по числовому или строковому полю, у Вас нет.
Petrakoff Sergey писал(а):От обилия кавычек, двойных и одинарных, зарябило в глазах.

Ничего не поделаешь. Фильтр в TDbf - это строка. Строка в Паскале всегда пишется в одинарных кавычках. Значения в фильтре - это ещё одна строка и их тоже надо брать в кавычки. Как раз в данном случае выражение более понятно, т.к. мы ясно видим, где строка паскалевская, а где та, которая уже относится к DBF-файлу.
Petrakoff Sergey писал(а):Где можно почитать про то, как надо правильно расставлять эти кавычки?

Вы опоздали на добрых 20 лет. :)
Если коротко, то где какие ставить кавычки я Вам объяснил выше:
1) Всё фильтрующее выражение - это строка Паскаля. Эта строка должна быть в одинарных кавычках.
2) Те строковые значения полей, которые находятся внутри строки фильтра, должны быть в двойных кавычках.
Соответственно, если Вы получаете значения поля для фильтра с помощью какой либо стандартной функции FreePascal, то должны это значение обрамить двойными кавычками. А раз двойные кавычки - это строка Паскаль, то они должны быть обрамлены ещё и одинарными кавычками.
Это самое простое "почитать". ;)
sign
энтузиаст
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Сообщение sign »

Petrakoff Sergey писал(а):Что касается, почему я вначале остановил свой выбор на DBF - трудно однозначно ответить, что повлияло на мой выбор.
Во всяком случае, я уже достаточно "глубоко" влез в это дело. Сворачивать с полпути не в моем характере. В дальнейших моих планах и SQLite и FireBird и, конечно же, MYSQL.

Если вы собираетесь переходит в будущем на нормальные базы, то нафига вам вообще DBF?
Что бы что?
Чтоб потом вспоминать как кошмарный сон?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

sign писал(а):Что бы что?
Чтоб потом вспоминать как кошмарный сон?

Чтобы на новых БД испытать облегчение, граничащее с оргазмом. :D
ViruZ
постоялец
Сообщения: 175
Зарегистрирован: 30.05.2005 17:41:12
Откуда: Украина
Контактная информация:

Сообщение ViruZ »

sign писал(а):

Код: Выделить всё

Dbf2.AddIndex('IND_DATPRIH', DTOS('DATPRIH'), []);

Вы пропустили кавычки:

Код: Выделить всё

Dbf2.AddIndex('IND_DATPRIH', 'DTOS(DATPRIH)', []);

должно работать.
Petrakoff Sergey
новенький
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Сообщение Petrakoff Sergey »

Я пока изучаю БД "просто так", для себя. В будущем, может быть, будет легче найти работу, если буду знать не только MySQL, но и другие, в том числе и DBF. А то, что начал с DBF, произошло в значительной степени случайно и отчасти по незнанию. Поэтому, наверное, правы и sign
sign писал(а):Чтоб потом вспоминать как кошмарный сон?
и Vadim
Vadim писал(а):Чтобы на новых БД испытать облегчение, граничащее с оргазмом. :D
Ответить