pnv82
Newbie | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору FastReport 4.6 Баг и его частичный фикс: При печати больших(размерами от 0,5мх2м) отчетов, в режиме разбиения не меньшие страницы, не совсем верно отрабатывает SplitPage(a, b, c, d: Extended; var x, y: Integer; var NeedRotate: Boolean);, иногда недопечатывая часть данных(листов). После некоторых копаний выяснилось, что не учитывается тот факт, что при большом кол-ве листов, поля принтера добавляют такую величину сдвига, что часть данных не помещается на листах, кол-во которых рассчитывается без учета полей. Но повторяется это не всегда, т.к. листов должно быть действительно много Замена TrySplit на след. код частично решает проблему: procedure TrySplit; var DiffX,DiffY:Extended; const AvgPrinterMargin=11; // усредненная величина полей страницы, по хорошему ее нужно получать для каждого принтера... begin // что значит проверка if Abs(Trunc(b / d) * d - b) < 11 then - неизвестно // вычисляем первичное кол-во страниц - берем ближайшее большее целое // т.к. отсечь кусочек картинки мы не можем, вне зависимости от ее размера x := Ceil(a / c); y := Ceil(b / d); // добавляем место для полей принтера DiffX := (x*2-2)*AvgPrinterMargin; DiffY := (y*2-2)*AvgPrinterMargin; // если места хватает даже с полями, то оставляем как есть // иначе добавляем необходимое кол-во листов if(x*c<a+DiffX) then x := x + Ceil(DiffX/c); if(y*d<b+DiffY) then y := y + Ceil(DiffY/d); end; Index: D:/work/uhta/components/FastReport/Source/frxPreviewPages.pas =================================================================== --- D:/work/uhta/components/FastReport/Source/frxPreviewPages.pas (revision 20) +++ D:/work/uhta/components/FastReport/Source/frxPreviewPages.pas (revision 77) @@ -143,7 +143,7 @@ uses frxPreview, Printers, frxPrinter, frxPrintDialog, frxXMLSerializer, frxUtils, - ShellApi, frxDMPClass, frxRes; + ShellApi, frxDMPClass, frxRes, Math; type THackComponent = class(TfrxComponent); @@ -1463,16 +1463,27 @@ tempC: Extended; procedure TrySplit; + var + DiffX,DiffY:Extended; + const + AvgPrinterMargin=11; begin - if Abs(Trunc(a / c) * c - a) < 11 then - x := Round(a / c) - else - x := Trunc(a / c) + 1; + // что занчит проверка if Abs(Trunc(b / d) * d - b) < 11 then - неизвестно - if Abs(Trunc(b / d) * d - b) < 11 then - y := Round(b / d) - else - y := Trunc(b / d) + 1; + // вычисляем первичное кол-во страниц + x := Ceil(a / c); + y := Ceil(b / d); + + // добавляем место для полей принтера + DiffX := (x*2-2)*AvgPrinterMargin; + DiffY := (y*2-2)*AvgPrinterMargin; + + // если места хватает даже с полями + if(x*c<a+DiffX) then + x := x + Ceil(DiffX/c); + + if(y*d<b+DiffY) then + y := y + Ceil(DiffY/d); end; begin Добавлено: Неочевидное поведение: Опять таки, при печати больших отчетов и их разбиении на страницы такое логичное действие как задание печати конкретной страницы по номеру становится достаточно неочевидным - номер страницы относится не к получаемым страницам, а к оригинальным. Другими словами, когда у меня есть отчет из одной страницы, например, 1 на 1 метр, и я печатаю его разбивая на А3 у меня нет никакой возможности отпечатать одну из этих разбитых страничек, что бы увидеть - правильно ли оно мне побилось - будут печататься все страницы подряд. Добавлено: FastReport 4.6 При переходе на версию 4.6, в которой изменилась работа с путями к шаблонам, столкнулись с неприятным поведением - после редактирования отчета путь к файлу шаблона прописывается абсолютный, даже если шаблон лежит в каталоге приложения, и соотвественно на машине, где приложение установлено по другому пути, шаблон не находится, даже если он есть в каталоге приложения. Причем в procedure TfrxReport.SetParentReport(const Value: String); даже выполняется проверка на абсолютный путь, и в каталоге приложения шаблон ищется только для относительных путей. Такое изменение поломало работу существующих приложений после перекомпиляции их с новой версией. Имхо стоит засчитать такое поведение багом, и поправить. { check relative path, exclude network path } if (Length(fName) > 1) and (fName[2] <> ':') and not ((fName[1] = '\') and (fName[2] = '\')) then begin fName := ExtractFilePath(SaveFileName) + Value; if not FileExists(fName) then fName := GetApplicationFolder + Value; end; для себя просто убрали проверку на абсолютный путь, уж не знаю, насколько это правильно. |