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;
для себя просто убрали проверку на абсолютный путь, уж не знаю, насколько это правильно.