Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.01.2010, 19:11
Аватар для XIO
XIO XIO вне форума
Новичок
 
Регистрация: 06.12.2007
Сообщения: 77
Репутация: 32
Вопрос Оптимизация реализации календаря (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;
OpenEvents корректирует запрос, задавая нужную дату в условиях Where и таким образом выводит события за выбранную дату.

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

Вообще конечно работает и не дурно. Почти не заметно большой нагрузки на комп. Но просто не нравится мне такое решение и все тут. Не оптимально оно.

Кто может подкинуть более рациональную идею? Буду очень благодарен. Заранее спасибо
__________________
"Люди никогда не видят то, существование чего им кажется невозможным." ©Терри Пратчетт
Ответить с цитированием
  #2  
Старый 23.01.2010, 19:33
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Можно несколько оптимизировать, если формировать список дат при старте приложения. Тогда пропадет необходимость постоянного обращения к БД за датами.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 23.01.2010, 20:09
Аватар для XIO
XIO XIO вне форума
Новичок
 
Регистрация: 06.12.2007
Сообщения: 77
Репутация: 32
По умолчанию

Цитата:
Сообщение от Страдалецъ
Можно несколько оптимизировать, если формировать список дат при старте приложения. Тогда пропадет необходимость постоянного обращения к БД за датами.
Каюсь, забыл упомянуть что список дат через запрос формируется действительно только при старте программы, а так же если были изменены данные в главной таблице (дни рождения) либо в таблицах напоминаний, событий, праздников. То есть выполнение запросов происходит не так часто. Но сам перебор датаСета смущает.
Наверное было бы проще для машины, если бы формировать запрос такой что бы в одной строке все даты через запятую, и поиск осуществлять в строке, но не факт что будет оптимальнее, кроме того как такой запрос в Аксессе написать не представляю. В Оракле легко, а тут

В любом случае спасибо за помощь
__________________
"Люди никогда не видят то, существование чего им кажется невозможным." ©Терри Пратчетт
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 03:24.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter