SLAVICK, отличный календарь! Перерыл кучу, и остановился на этом.
Начал подгонять под свои нужды... В результате - перелопатил почти весь код, который стал еще меньше, А функциональность, универсальность и скорость работы возросли в разы! Может кому пригодится...
Добавлены: - прокрутка по годам; - всплывающие списки выбора месяца и года; - ограничения по минимальному году и конечной дате; - мелочи...
P.S. Если нужны комментарии или помощь в подключении - могу помочь... (пока еще помню что к чему :D)
SLAVICK, отличный календарь! Перерыл кучу, и остановился на этом.
Начал подгонять под свои нужды... В результате - перелопатил почти весь код, который стал еще меньше, А функциональность, универсальность и скорость работы возросли в разы! Может кому пригодится...
Добавлены: - прокрутка по годам; - всплывающие списки выбора месяца и года; - ограничения по минимальному году и конечной дате; - мелочи...
P.S. Если нужны комментарии или помощь в подключении - могу помочь... (пока еще помню что к чему :D)SSL
перелопатил почти весь код, который стал еще меньше,
ну с учетом дополнений - вырос почти на 1тыс. символов. Еще пропало выделение сегодняшней даты - как по мне это важно.
Давно сделал себе возможность растягивания формы и программного изменения размеров - см. ссылку. Применил и на Ваш вариант - так интереснее, чем не масштабируемый.
перелопатил почти весь код, который стал еще меньше,
ну с учетом дополнений - вырос почти на 1тыс. символов. Еще пропало выделение сегодняшней даты - как по мне это важно.
Давно сделал себе возможность растягивания формы и программного изменения размеров - см. ссылку. Применил и на Ваш вариант - так интереснее, чем не масштабируемый.SLAVICK
ну с учетом дополнений - вырос почти на 1тыс. символов.
Немного некорректно выразился, (из-за краткости), - под уменьшением размера кода я подразумевал конечно исходник, без учета дополнений, особенно, в его главной функциональной части, которую постоянно дергаем - процедуры Refresh и MouseMove. (С этого работа начиналась. Дополнения появились позже.) Но важнее, (для меня), - конечно не его размер, (это скорей попутный незначимый бонус), а оптимизация и существенно возросшая скорость работы. При этом мои дополнения на это никак не повлияли - остались в рамках...
При неизменности идеи: - полностью изменены алгоритмы построения и заполнения матрицы календаря, исключив ВСЕ проверки из циклов кода Refresh! (А их там было очень много.) А вне циклов работают всего 2 простые проверки на всю процедуру.
- Убран ненужный промежуточный 3-х мерный массив, - календарь сразу создается и обрабатывается на своем основном массиве.
- Сами циклы стали короче на 1 ряд (-1 строка х 7 столбцов), т.к. заголовок, (дни недели), создается 1 раз при инициализации, и больше не участвует в циклах Refresh и MouseMove. Т.е. в основном массиве календаря его просто нет.
- В результате, стало меньше проверок и в коде MouseMove, а оставшиеся тоже оптимизированы.
- Попутно, в блок инициализации календаря была вынесена вся "боевая" раскраска календаря (Fore/Back...), таким образом можно оперативно/интуитивно управлять цветом любых частей, а при необходимости - легко добавить новые.
- Добавлена "рамка прицела" - выделяющая дату под курсором.
ну с учетом дополнений - вырос почти на 1тыс. символов.
Немного некорректно выразился, (из-за краткости), - под уменьшением размера кода я подразумевал конечно исходник, без учета дополнений, особенно, в его главной функциональной части, которую постоянно дергаем - процедуры Refresh и MouseMove. (С этого работа начиналась. Дополнения появились позже.) Но важнее, (для меня), - конечно не его размер, (это скорей попутный незначимый бонус), а оптимизация и существенно возросшая скорость работы. При этом мои дополнения на это никак не повлияли - остались в рамках...
При неизменности идеи: - полностью изменены алгоритмы построения и заполнения матрицы календаря, исключив ВСЕ проверки из циклов кода Refresh! (А их там было очень много.) А вне циклов работают всего 2 простые проверки на всю процедуру.
- Убран ненужный промежуточный 3-х мерный массив, - календарь сразу создается и обрабатывается на своем основном массиве.
- Сами циклы стали короче на 1 ряд (-1 строка х 7 столбцов), т.к. заголовок, (дни недели), создается 1 раз при инициализации, и больше не участвует в циклах Refresh и MouseMove. Т.е. в основном массиве календаря его просто нет.
- В результате, стало меньше проверок и в коде MouseMove, а оставшиеся тоже оптимизированы.
- Попутно, в блок инициализации календаря была вынесена вся "боевая" раскраска календаря (Fore/Back...), таким образом можно оперативно/интуитивно управлять цветом любых частей, а при необходимости - легко добавить новые.
- Добавлена "рамка прицела" - выделяющая дату под курсором.
главная фишка: быстрое изменение размеров календаря.
Ну так у нас разные задачи.
Мои:
1. Код должен быть максимально легким, (быстрым), и, по возможности, универсальным для возможности его дальнейшей адаптации к разным задачам. (Почему и был выбран именно ваш код! Он достаточно легкий, хорошо читается и легко обрабатывается/дорабатывается - что и было выполнено, прежде всего, в его основе. Т.е. мой вариант - это, скорей, самодостаточная в своей основе, оптимальная/универсальная болванка для возможных дальнейших улучшений.)
2. Масштабируемость/динамичнось изменения размеров меня как раз не интересовала. Скорей наоборот - мой календарь должен быть, по возможности, максимально миниатюрным, и не иметь проблем со шрифтами. (Последние неизбежно появляются при изменении размеров различных контролов или просто их перемещения - давний глюк MS - отдельная тема. И, к сожалению, обе версии ваших календарей этим страдают.)
пропало выделение сегодняшней даты - как по мне это важно.
Не понял... На скрине выше видно, - текущая дата выделена рыжим цветом. Кроме того, при наведении курсора, в ваших календарях как раз текущая дата никак не отмечается, в моем - выделяется рамкой/"прицелом". Только ее основной цвет фона не стал менять, так же как у вас.
главная фишка: быстрое изменение размеров календаря.
Ну так у нас разные задачи.
Мои:
1. Код должен быть максимально легким, (быстрым), и, по возможности, универсальным для возможности его дальнейшей адаптации к разным задачам. (Почему и был выбран именно ваш код! Он достаточно легкий, хорошо читается и легко обрабатывается/дорабатывается - что и было выполнено, прежде всего, в его основе. Т.е. мой вариант - это, скорей, самодостаточная в своей основе, оптимальная/универсальная болванка для возможных дальнейших улучшений.)
2. Масштабируемость/динамичнось изменения размеров меня как раз не интересовала. Скорей наоборот - мой календарь должен быть, по возможности, максимально миниатюрным, и не иметь проблем со шрифтами. (Последние неизбежно появляются при изменении размеров различных контролов или просто их перемещения - давний глюк MS - отдельная тема. И, к сожалению, обе версии ваших календарей этим страдают.)
пропало выделение сегодняшней даты - как по мне это важно.
Не понял... На скрине выше видно, - текущая дата выделена рыжим цветом. Кроме того, при наведении курсора, в ваших календарях как раз текущая дата никак не отмечается, в моем - выделяется рамкой/"прицелом". Только ее основной цвет фона не стал менять, так же как у вас.SSL
не не глюк сначала не понял - просто я сделал конечную дату не сегодня - а 2100 год - закомментил/раскомментил строки в Вашем файле. Так вот при изменении финишной даты - не подсвечивает. См. Файл. На быстродействии - действительно, возможно будет быстрее. Я свой первоначальный код писал на скорую руку, особо не оптимизируя.
не не глюк сначала не понял - просто я сделал конечную дату не сегодня - а 2100 год - закомментил/раскомментил строки в Вашем файле. Так вот при изменении финишной даты - не подсвечивает. См. Файл. На быстродействии - действительно, возможно будет быстрее. Я свой первоначальный код писал на скорую руку, особо не оптимизируя.SLAVICK
А... мой косяк! Я сначала ограничивал календарь только по годам, а под конец решил добавить ограничитель по конкретной конечной дате, но не проверил варианты. Получилась подгонка.
В Refresh за ненадобностью выбросил двоичный флаг, и в последнем блоке заменил проверки:
[vba]
Код
'=== Выделение только активных дней до указанного или последнего числа месяца If DateSerial(Year_, Month_, Day(gFinishDate)) = gFinishDate Then Finish = stDay + 6 + Day(gFinishDate) Else Finish = stDay + 6 + Day(DateSerial(Year_, Month_ + 1, 1) - 1) End If
For i = stDay + 7 To Finish With cmdLots(i).DBt .ForeColor = MainFColor .BackColor = MainBColor End With Next
'=== Выделение текущего дня If DateSerial(Year_, Month_, Day(Date)) = Date Then Finish = stDay + 6 + Day(Date) cmdLots(Finish).DBt.ForeColor = ThisDayFColor 'Цвет шрифта cmdLots(Finish).DBt.BackColor = ThisDayBColor 'Фон End If
' Repaint
[/vba]
Попутно добавил возможность изменения цвета шрифта текущего дня и удалил за ненадобностью в конце Repaint.
А... мой косяк! Я сначала ограничивал календарь только по годам, а под конец решил добавить ограничитель по конкретной конечной дате, но не проверил варианты. Получилась подгонка.
В Refresh за ненадобностью выбросил двоичный флаг, и в последнем блоке заменил проверки:
[vba]
Код
'=== Выделение только активных дней до указанного или последнего числа месяца If DateSerial(Year_, Month_, Day(gFinishDate)) = gFinishDate Then Finish = stDay + 6 + Day(gFinishDate) Else Finish = stDay + 6 + Day(DateSerial(Year_, Month_ + 1, 1) - 1) End If
For i = stDay + 7 To Finish With cmdLots(i).DBt .ForeColor = MainFColor .BackColor = MainBColor End With Next
'=== Выделение текущего дня If DateSerial(Year_, Month_, Day(Date)) = Date Then Finish = stDay + 6 + Day(Date) cmdLots(Finish).DBt.ForeColor = ThisDayFColor 'Цвет шрифта cmdLots(Finish).DBt.BackColor = ThisDayBColor 'Фон End If
' Repaint
[/vba]
Попутно добавил возможность изменения цвета шрифта текущего дня и удалил за ненадобностью в конце Repaint.
Ну тут все просто. Если подсчитать кол-во проверок "If" только в циклах, (а это одна из самых тормозных операций), то в процедуре Refresh, которую дергаем при каждом изменении месяца или года, получается 50 явных. С учетом основной составной проверки, уже = 100.
+ пересоздание 49 контролов при каждом вызове: Set .DBt = MyCalendar.Fr1.Controls.Add... - тоже не быстрая процедура. (Это все то, что вообще отсутствует в моей модернизации и циклы уменьшены до 42 за счет удаления из них заголовка календаря + по мелочи...)
Ну а практически, - на моем компе i7-5820K, (правда видеокарта сейчас древняя, нормальная полетела), например, если зажать любую стрелку прокрутки по месяцам или годам, и прогнать календарь несколько раз туда-сюда, начинаются весьма заметные тормоза даже при перемещении курсора по календарю, как буд-то внутри начинаются какие-то переполнения или зацикливания. Это значит, что на слабых компах тормоза могут быть заметны и без таких издевательств. Если поставить таймер, не сомневаюсь что разница будет, т.к. после модернизации тормозов таким образом добиться мне не удавалось, а сама прокрутка, сразу, даже визуально, - заметно быстрее.
Ну и если есть возможность сделать код более оптимальным, то было бы странно этого не сделать. Тем более, с учетом дальнейших апгредов/наворотов, при расширении кода, тормоза имеют свойства накапливаться и обнаруживать себя совершенно непонятным образом...
Ну тут все просто. Если подсчитать кол-во проверок "If" только в циклах, (а это одна из самых тормозных операций), то в процедуре Refresh, которую дергаем при каждом изменении месяца или года, получается 50 явных. С учетом основной составной проверки, уже = 100.
+ пересоздание 49 контролов при каждом вызове: Set .DBt = MyCalendar.Fr1.Controls.Add... - тоже не быстрая процедура. (Это все то, что вообще отсутствует в моей модернизации и циклы уменьшены до 42 за счет удаления из них заголовка календаря + по мелочи...)
Ну а практически, - на моем компе i7-5820K, (правда видеокарта сейчас древняя, нормальная полетела), например, если зажать любую стрелку прокрутки по месяцам или годам, и прогнать календарь несколько раз туда-сюда, начинаются весьма заметные тормоза даже при перемещении курсора по календарю, как буд-то внутри начинаются какие-то переполнения или зацикливания. Это значит, что на слабых компах тормоза могут быть заметны и без таких издевательств. Если поставить таймер, не сомневаюсь что разница будет, т.к. после модернизации тормозов таким образом добиться мне не удавалось, а сама прокрутка, сразу, даже визуально, - заметно быстрее.
Ну и если есть возможность сделать код более оптимальным, то было бы странно этого не сделать. Тем более, с учетом дальнейших апгредов/наворотов, при расширении кода, тормоза имеют свойства накапливаться и обнаруживать себя совершенно непонятным образом...SSL