Обращение к разработчикам: Нашел несколько багов
ultima
С-Петербург
Хотел бы обратить внимание разработчиков на некоторые обнаруженные баги:
1. Некоректный Destroy
если в процессе выполнения метода TfrxReport.PrepareReport попытаться выполнить TfrxReport.Free то происходит Access Violation. Если использовать модальное окно, то такую ошибку воспроизвести трудно, а если TfrxPreview то элементарно ...
не нашел место где она возникает .... (я использую frxReport.OldStyleProgress=true, есть подозрение что из-за этого все, там разная обработка ... )
в продолжение этой проблемы, в методе TfrxPreview.UpdatePages есть проверка
if FLocked or (PageCount = 0) then Exit; так вот при вызове TfrxReport.PrepareReport вроде бы не происходит установки блокировки, и вооще мне не очень понятна логика объявления
публичных методов TfrxPreview.Lock; TfrxPreview.Unlock; при этом блокировка однократная, и НЕТ СВОЙСТВА LOCKED
раз они в public, то есть блокировку можно поставить/снять снаружи, то как минимум надо было бы предусмотреть свойство для проверки есть блокировка или нет, и возможно предусмотреть множественную блокировку, пока счетчик блокировок не дойдет до 0, то считается что блокировка есть. По крайней мере в проекте, над которым я работаю, используется именно такой способ, причем блокировка пересылается по всем дочерним фреймам ....
Далее в методе TfrxPreviewWorkspace.MouseMove тоже есть проверка
if (FPageList.Count = 0) or Locked or FIsThumbnail then Exit; но блокировка то не стоит, и по крайней мере в режиме отладки и, возможно, на медленных компьютерах, проявляется такой баг, что при перемещении мыши начинает отрабатывать этот метод, и программа входит в бесконечный цикл ...
2. Не баг а огромное пожелание, очень хотелось бы, чтобы при экспорте, хотя бы в Excel/Calc агрегатные функции оставались агрегатными, а не экспортировались как числа/строки. Знаю, что реализовать тяжело, было бы просто, сам бы исправил, учитывая метод экспорта через промежуточную матрицу, но возможно, например к TfrxMemoView, подцепить Tlist и в него писать все TfrxMemoView которые будут сумироваться, и при экспорте искать эти компоненты. и при экспорте писать '=SUM(B1+C2+D5)'. Учитывая, что 1 TfrxMemoView соотвествует 1 ячейка в Excel/Calc. в OO-Calc также в принципе, но в русском и англ MS Excel функции названы по разному SUM vs. СУММА вообщем не все так просто ...
3. Огромная просьба обновить справку, я очень долго парился пока нашел недокументированное свойство TfrxReport.EnabledDataSets, ну надо мне держать 2 созданных TfrxReport в программе, а точне пока 2 и зачем мне в дизайнере видеть чужие frxReport.DataSets ??? которые у меня и называются одинакого ...
Ну не все же покупают версию с исходниками, и что им делать, я то ладно, сам разбирусь как нибудь, поматерюсь прадва при этом ...
4. Компонент TfrxPreview в DesignTime ведет себя некорректно, например если привязать к TfrxReport TfrxPreview, и поставить в true свойство TfrxReport.DataSet.Active = true, а затем false то получиться интересное поведение ;-)
И куда пропало свойство TfrxPreview.Visible ??? Хотя я решил не использовать TfrxPreview в Wysiwyg, поэтому просто для информации ... (Я еще не видел превьюшек которые бы меня устраивали, и ваша не самый плохой вариант ... )
метод TfrxPreview.Clear не приводит TfrxPreview к первоначальному состоянию, по умолчанию нет ни одной страницы вроде.
И еще у меня такое чувство в разных местах вы используете PageNo := 1; vs PageNo := 0; для идентификации пустого отчета ...
TfrxPreview.Clear задает PageNo := 0; а в других местах PageNo := 1;
1. Некоректный Destroy
если в процессе выполнения метода TfrxReport.PrepareReport попытаться выполнить TfrxReport.Free то происходит Access Violation. Если использовать модальное окно, то такую ошибку воспроизвести трудно, а если TfrxPreview то элементарно ...
не нашел место где она возникает .... (я использую frxReport.OldStyleProgress=true, есть подозрение что из-за этого все, там разная обработка ... )
в продолжение этой проблемы, в методе TfrxPreview.UpdatePages есть проверка
if FLocked or (PageCount = 0) then Exit; так вот при вызове TfrxReport.PrepareReport вроде бы не происходит установки блокировки, и вооще мне не очень понятна логика объявления
публичных методов TfrxPreview.Lock; TfrxPreview.Unlock; при этом блокировка однократная, и НЕТ СВОЙСТВА LOCKED
раз они в public, то есть блокировку можно поставить/снять снаружи, то как минимум надо было бы предусмотреть свойство для проверки есть блокировка или нет, и возможно предусмотреть множественную блокировку, пока счетчик блокировок не дойдет до 0, то считается что блокировка есть. По крайней мере в проекте, над которым я работаю, используется именно такой способ, причем блокировка пересылается по всем дочерним фреймам ....
Далее в методе TfrxPreviewWorkspace.MouseMove тоже есть проверка
if (FPageList.Count = 0) or Locked or FIsThumbnail then Exit; но блокировка то не стоит, и по крайней мере в режиме отладки и, возможно, на медленных компьютерах, проявляется такой баг, что при перемещении мыши начинает отрабатывать этот метод, и программа входит в бесконечный цикл ...
2. Не баг а огромное пожелание, очень хотелось бы, чтобы при экспорте, хотя бы в Excel/Calc агрегатные функции оставались агрегатными, а не экспортировались как числа/строки. Знаю, что реализовать тяжело, было бы просто, сам бы исправил, учитывая метод экспорта через промежуточную матрицу, но возможно, например к TfrxMemoView, подцепить Tlist и в него писать все TfrxMemoView которые будут сумироваться, и при экспорте искать эти компоненты. и при экспорте писать '=SUM(B1+C2+D5)'. Учитывая, что 1 TfrxMemoView соотвествует 1 ячейка в Excel/Calc. в OO-Calc также в принципе, но в русском и англ MS Excel функции названы по разному SUM vs. СУММА вообщем не все так просто ...
3. Огромная просьба обновить справку, я очень долго парился пока нашел недокументированное свойство TfrxReport.EnabledDataSets, ну надо мне держать 2 созданных TfrxReport в программе, а точне пока 2 и зачем мне в дизайнере видеть чужие frxReport.DataSets ??? которые у меня и называются одинакого ...
Ну не все же покупают версию с исходниками, и что им делать, я то ладно, сам разбирусь как нибудь, поматерюсь прадва при этом ...
4. Компонент TfrxPreview в DesignTime ведет себя некорректно, например если привязать к TfrxReport TfrxPreview, и поставить в true свойство TfrxReport.DataSet.Active = true, а затем false то получиться интересное поведение ;-)
И куда пропало свойство TfrxPreview.Visible ??? Хотя я решил не использовать TfrxPreview в Wysiwyg, поэтому просто для информации ... (Я еще не видел превьюшек которые бы меня устраивали, и ваша не самый плохой вариант ... )
метод TfrxPreview.Clear не приводит TfrxPreview к первоначальному состоянию, по умолчанию нет ни одной страницы вроде.
И еще у меня такое чувство в разных местах вы используете PageNo := 1; vs PageNo := 0; для идентификации пустого отчета ...
TfrxPreview.Clear задает PageNo := 0; а в других местах PageNo := 1;
Комментарии
Блокировка устанавливается при печати , экспорте , сохранении, загрузке отчета.
Смысл счетчика не понятен, можете объясните подробней зачем он ?
3. Учтем.
4. Сделал, ничего не произошло ....
Clear Уже исправлен.
> PageNo := 0;
Поправим, но даже в этом случае FPageNo будет установлен в 1 (функция SetPageNo)
Вот за Report.Engine.StopReport спасибо, учту, не знал ... очень хорошо , я уже полгода занимаюсь Fast-Report'om, меня на отчеты посадили, у нас коллективная разработка ;-)
а на счет счетчика, это было просто предложение, я не уверен что вам нужно его использовать, просто предположил, что раз методы Lock и UnLock в public то есть их можно поменять в любом месте программы, то возможно представить ситуации когда их отменят и проверка не сработает, и это полезно если методы выполняемые одновременно ставят или снимают блокировку, например я могу по таймеру выполнить UnLock а отчет например долгий, и при MouseMove блокировки не будет, хотя это граничные случаи, может и не нужно ...
Мне все-таки трудно представить ситуацию с использованием счетчика , а если делать Unlock по таймеру , то и счетчик не поможет
А вывести св-во для FLocked в pulic не помешает - сделаем.
Версия 4.3.26
Еще по поводу TfrxReport.Engine.StopReport у меня не получилось его использовать,
Есть конечно свойство TfrxReport.Engine.Running , но не хотелось бы в каждом месте программы проверять эти блокировки, да и использовать таймер для окончания выполнения TfrxReport.Engine.Run тоже не хочется, потому что отчет может быть доглим, и пользователь увидет зависшую программу
Сделал тестовый пример, но постараюсь описать словами,
1. создаю динамически TfrxReport и TfrxPreview
2. запускаю по кнопке frxReport.ShowReport при OldStyleProgress = True
3. на форме расположена картинка, и в событии OnMouseDown выполняется код
if assigned(frxReport1) and
frxReport1.Engine.Running then
begin
frxReport1.Engine.StopReport;
freeAndNil(frxPreview1);
freeAndNil(frxReport1);
end;
Проблема появляется если в момент окончания внутреннего PrepareReport пользователь нажмет на кнопку (а примере заменил на OnMouseMove для простоты), frxReport1 и frxPreview1 будут убиты,
Обработка мыши доступна в момент когда отрабатывает TfrxProgress.Execute ( Application.ProcessMessages; frxProgress.pas строка #121)
т.е. будет выполнен FEngine.Run (frxClass.pas #8707) он вроде нормально выполняется, но при выполнении Finalize; (frxEngine.pas #334) -> PreviewPages.Finish; (frxEngine.pas #287) -> Report.InternalOnProgressStop(ptRunning); (frxPreviewPage.pas #795) -> Application.ProcessMessages; (frxClass.pas #9108)
и вот тут то и срабатывает обработчик на MouseDown (MouseMove) который и убъет frxReport и frxPreview
а дальше -> Running := False; (frxEngine.pas #288) -> if Assigned(FOnEndDoc) then (frxClass.pas #8709)
т.е. объект реально уничтожен, ссылки остались на неправильные участки памяти, и в произвольном месте вылетает ошибка.
Пример практически реальный, в нашем проекте используется такая схема, т.е. возможно придет событие от MouseDown на картинке (которая для пользователя кнопка) для закрытия текущего фрейма и открытия нового, и ждать не хочется, отчет то может быть и на 10 минут, на примере CrossTable я уже такие создавал ....
И frxReport1.Engine.StopReport; не помогает ???
Тестовый пример в комплекте ....
ЗЫ: Как я понял, при использовании frxReport1.Engine.StopReport отчет прекращает делать новые страницы, но продолжит выполнять ShowPreparedReport, создаст Preview и покажет то что успел сделать, т.е. если у меня печатается прайс, и в нем 100 страниц, а я прервал на 10, то пользователь увидит 10 с нормальной шапкой и концовкой.
Получается нельзя удалить frxReport никак, пока полностью не отработал ShowReport
Вроде бы при выплнении frxReport.Free не происходит frxReport.Engine.Free