|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Оптимизация реализации календаря (Access DB, MonthCalendar)
Доброго времени суток, коллеги.
Есть задачка, по идеи банальнейшая. Но что-то не могу найти этого самого банального решения что бы оно было оптимальным. Задача: Реализовать календарик, в котором будут подсвечиваться те даты, на которые привязаны различные события (Дни Рождения, События, Праздники). И соответственно при выборе подсвеченной даты отобразить в TDBGrid события которые привязаны к выбранной дате. Даты событий, хранятся в базе данных. В качестве БД используется MS Access. Было у меня несколько попыток реализации, были и не работающие корректно и жутко тормозящие. Сейчас нашёл более менее реальное решение, но мне оно не нравится только потому что с ростом данных в базе, скорость отработки на мой взгляд будет падать на глазах. Мой способ. В качестве календаря использую MonthCalendar из набора компонент AlthaSkins. (он мне больше импанирует чем стандартный, более приятный юзабилити.) У календаря есть событие со следующим кодом: Код:
procedure TfmMainWin.smcCalendarGetCellParams(Sender: TObject; Date: TDateTime; AFont: TFont; var Background: TColor); begin //Подсветим на календаре даты когда будут дни рождения, события, праздники, if (data.qDatesHB.Active) and (data.qDatesHB.RecordCount > 0) then begin data.qDatesHB.First; while not data.qDatesHB.Eof do begin If (DayOf(data.qDatesHB.Fields[0].AsDateTime) = DayOf(Date)) and (MonthOf(data.qDatesHB.Fields[0].AsDateTime) = MonthOf(Date)) then begin Background := clYellow; Break; end; data.qDatesHB.Next; end; end; //Подсветим на календаре даты когда будут напоминания. if (data.qRemDates.Active) and (data.qRemDates.RecordCount > 0) then begin data.qRemDates.First; while not data.qRemDates.Eof do begin If DateOf(data.qRemDates.Fields[0].AsDateTime) = Date then begin Background := clYellow; Break; end; data.qRemDates.Next; end; end; end; При этом qDatesHB и qRemDates это TADOQuery с запросами: Код:
data.qDatesHB.SQL.Text := 'Select DISTINCT Date1 From Subject '+ ' Union All '+ ' Select DISTINCT DateDo '+ ' From Holyday '+ ' Union All '+ ' Select DISTINCT DateEvent ' + ' From Event '; data.qRemDates.SQL.Text := ' Select DISTINCT Date1 From Reminder '; Ну и соответственно при изменении даты в календаре по событию делаем так: Код:
procedure TfmMainWin.smcCalendarChange(Sender: TObject); begin if (Assigned(data)) then data.OpenEvents(smcCalendar.CalendarDate); end; Весь затык в событии smcCalendarGetCellParams, слишком не оптимально в цикле прокручивать строки DataSet'а, да ещё получается прокручивать его как минимум столько раз сколько дней в месяца и так каждый раз при переходе на новый месяц. Вообще конечно работает и не дурно. Почти не заметно большой нагрузки на комп. Но просто не нравится мне такое решение и все тут. Не оптимально оно. Кто может подкинуть более рациональную идею? Буду очень благодарен. Заранее спасибо "Люди никогда не видят то, существование чего им кажется невозможным." ©Терри Пратчетт |
#2
|
||||
|
||||
Можно несколько оптимизировать, если формировать список дат при старте приложения. Тогда пропадет необходимость постоянного обращения к БД за датами.
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#3
|
||||
|
||||
Цитата:
Наверное было бы проще для машины, если бы формировать запрос такой что бы в одной строке все даты через запятую, и поиск осуществлять в строке, но не факт что будет оптимальнее, кроме того как такой запрос в Аксессе написать не представляю. В Оракле легко, а тут В любом случае спасибо за помощь "Люди никогда не видят то, существование чего им кажется невозможным." ©Терри Пратчетт |