добавить новую страницу

отредактировано 20:26 Раздел: FastReport .NET
Добрый день, формирую отчет. И в зависимости от параметра, мне надо создать N-ое кол-во страниц. Как программно это реализовать?
Заранее спасибо за ответы.
«1

Комментарии

  • отредактировано 20:26
    ilyaae написал: »
    Добрый день, формирую отчет. И в зависимости от параметра, мне надо создать N-ое кол-во страниц. Как программно это реализовать?
    Заранее спасибо за ответы.
    Можешь в цикле в событии StartReport выполнить Report.Pages.Add(new ReportPage());
  • отредактировано 20:26
    CodeMAP написал: »
    Можешь в цикле в событии StartReport выполнить Report.Pages.Add(new ReportPage());
    Спасибо. О цикле думал. Разбираться с репортингом под .net только начинаю и так понимаю, что большинство событий, обрабатываются скриптом. А инструкция скудненькая.
  • отредактировано 20:26
    ilyaae написал: »
    Спасибо. О цикле думал. Разбираться с репортингом под .net только начинаю и так понимаю, что большинство событий, обрабатываются скриптом. А инструкция скудненькая.
    Зарегистрировался на форуме FastReport 8 лет назад и только начал разбираться :) интересненько. Хотя я и сам регистрировался давно, вон оказывается 7 лет назад, а знаю этот генератор отчётов довольно поверхностно. Ну мне для моих задач хватает. А что у тебя за интересная надобность создавать руками страницы? Расскажи, если не секрет, может это как-то по другому можно сделать?
  • отредактировано 20:26
    CodeMAP написал: »
    Зарегистрировался на форуме FastReport 8 лет назад и только начал разбираться :) интересненько. Хотя я и сам регистрировался давно, вон оказывается 7 лет назад, а знаю этот генератор отчётов довольно поверхностно. Ну мне для моих задач хватает. А что у тебя за интересная надобность создавать руками страницы? Расскажи, если не секрет, может это как-то по другому можно сделать?
    Ну у нас использовался до недавнего времени fastreport vcl 4, под 7 Delphi. Сейчас пробую демо под .net.
    А задача следующая: есть тираж, который разбит на паллеты и необходимо печатать на эти паллеты этикетки.

    private void Page1_StartPage(object sender, EventArgs e)
    {
    int i;
    int label = ((Int32)Report.GetParameterValue("NumberOfLabels"));

    for(i=1;i<label;i++)
    {
    Report.Pages.Add(new ReportPage());
    }
    }
    выскакивает ошибка:
    В экземпляре объекта не задана ссылка на объект.
    System.NullReferenceException: В экземпляре объекта не задана ссылка на объект.
    в FastReport.Code.AssemblyDescriptor.InvokeEvent(String name, Object[] parms)
    в FastReport.Engine.ReportEngine.RunReportPage(ReportPage page)
    в FastReport.Engine.ReportEngine.RunReportPages()
    в FastReport.Engine.ReportEngine.RunReportPages(ReportPage page)
    в FastReport.Engine.ReportEngine.Run(Boolean runDialogs, Boolean append, Boolean resetDataState, ReportPage page)
    в FastReport.Report.Prepare(Boolean append)
    в FastReport.Design.ReportTab.Preview()

    Если переменной int label = ... указывать явное значение, все ок.
    NumberOfLabels - является параметром в репорте, которому присваивается значение из внешнего приложения fr.SetParameterValue("NumberOfLabels",allLabels);.


  • отредактировано 20:26
    ilyaae написал: »
    int label = ((Int32)Report.GetParameterValue("NumberOfLabels"));
    Если заменить на(берем значение элемента с формы)
    int label = NumberOfLabels.Value;

    то ошибка следующая
    Ошибка CS0266: Неявное преобразование типа "object" в "int" невозможно. Существует явное преобразование (отсутствует приведение?)
  • отредактировано 20:26
    И как то не обратил внимание сразу, при выполнении кода
    for(i=1;i<label;i++)
    {
    Report.Pages.Add(new ReportPage());
    }
    создается новая чистая страница отчета, а мне надо дублирование с изменение только поля label(номер этикетки)
  • отредактировано 20:26
    Коллега, я тоже в полиграфии тружусь. :)

    поясни, что значит
    написал:
    Если заменить на(берем значение элемента с формы)
    int label = NumberOfLabels.Value;
    что в этом случае такое NumberOfLabels? это какой-то контрол на форме диалога в репорте? или это тот же параметр?

    дальше, ошибка
    написал:
    В экземпляре объекта не задана ссылка на объект.
    System.NullReferenceException: В экземпляре объекта не задана ссылка на объект.
    выскакивает похоже на присвоении
    написал:
    int label = ((Int32)Report.GetParameterValue("NumberOfLabels"));
    это может быть либо по тому, что ошибся в написании имени параметра :) , либо параметру не присвоено значение. У меня с вот таким кодом всё норм работает. Это в программе:
    написал:
    Report _report = new Report();
    _report.Load(Application.StartupPath+ @\test.frx);
    _report.SetParameterValue("Param", int.Parse(textBox_listQnt.Text));
    _report.Show();
    Это в репорте
    написал:
    int i;
    int label = ((Int32)Report.GetParameterValue("Param"));

    for(i=1;i<label;i++)
    {
    Report.Pages.Add(new ReportPage());
    }

    Я тебе даже прикреплю исходники, попробуй запустить у себя

    А ещё расскажи как ты данные о этикетках в отчёте получаешь. Можно ведь у бэнда (раздела) "Данные" поставить свойство "Формировать новую страницу" и тогда каждая новая запись из источника данных (таблицы например) будет на новом листе.

    В общем смотри в программе: Кнопка "Отчёт #1 (новые страницы)" открывает test.frx, куда через параметр "Param" передаётся из программы кол-во листов и в самом отчёте создаются новые страницы.
    Кнопка Отчёт #2 (с данными) открывает test2.frx - там я создал источник данных, таблицу с одним столбцом, куда записал значения 1, 2, 3. В секции Данные выставил свойство "Формировать новую страницу", поместил туда текстовое поле и данные в него подставляются из таблицы. Каждая новая запись выводится на новом листе.
    PS возьми на заметку удобную фишку - в программе сделано так, что при щелчке мышкой по кнопке, с зажатым контролом на клавиатуре, отчёт открывается в дизайнере. Очень удобно дорабатывать или искать косяки. Что бы открытый в дизайнере отчёт построить, нажимай Ctrl+P (П английское). При этом в нём будут все данные и переданные параметры.
    Исходники тут https://yadi.sk/d/BLvwalTXqvaju
  • отредактировано 20:26
    ilyaae написал: »
    И как то не обратил внимание сразу, при выполнении кода
    for(i=1;i<label;i++)
    {
    Report.Pages.Add(new ReportPage());
    }
    создается новая чистая страница отчета, а мне надо дублирование с изменение только поля label(номер этикетки)
    Тогда однозначно смотри в сторону моего второго варианта. Там у тебя точно всё на листе будет повторяться, кроме номера этикетки
  • отредактировано 20:26
    CodeMAP написал: »
    Тогда однозначно смотри в сторону моего второго варианта. Там у тебя точно всё на листе будет повторяться, кроме номера этикетки
    Спасибо, сейчас посмотрю
  • отредактировано 20:26
    CodeMAP написал: »
    Коллега, я тоже в полиграфии тружусь. :)
    Можно сказать, что коллеги. Бумажная промышленность.
    CodeMAP написал: »
    поясни, что значит
    что в этом случае такое NumberOfLabels? это какой-то контрол на форме диалога в репорте? или это тот же параметр?
    Это параметр в репортинге, который принимает значение из внешней программы.
    CodeMAP написал: »
    А ещё расскажи как ты данные о этикетках в отчёте получаешь. Можно ведь у бэнда (раздела) "Данные" поставить свойство "Формировать новую страницу" и тогда каждая новая запись из источника данных (таблицы например) будет на новом листе.
    Кол-во этикеток - расчетное. Тираж / кол-во на паллете = кол-во этикеток. И соответственно печатать мы можем все или выбранный диапазон.
    CodeMAP написал: »
    PS возьми на заметку удобную фишку - в программе сделано так, что при щелчке мышкой по кнопке, с зажатым контролом на клавиатуре, отчёт открывается в дизайнере. Очень удобно дорабатывать или искать косяки. Что бы открытый в дизайнере отчёт построить, нажимай Ctrl+P (П английское). При этом в нём будут все данные и переданные параметры.
    Исходники тут https://yadi.sk/d/BLvwalTXqvaju
    Спасибо!
  • отредактировано 20:26
    Для понимания что должно выйти
    https://drive.google.com/open?id=0B7PCj2TZT...QXl3c0tjNXhsdzA
    Проблему так и не решил с передачей значения параметра, переменной
    int label = ((Int32)Report.GetParameterValue("NumberOfLabels")); =[А вот полученное значение переменной, не присваивается]!!!!
  • отредактировано 20:26
    ilyaae написал: »
    Для понимания что должно выйти
    https://drive.google.com/open?id=0B7PCj2TZT...QXl3c0tjNXhsdzA
    Проблему так и не решил с передачей значения параметра, переменной
    int label = ((Int32)Report.GetParameterValue("NumberOfLabels")); =[А вот полученное значение переменной, не присваивается]!!!!
    Странно, сейчас посмотрю твой отчёт. А то, что я тебе прислал - работает у тебя? Запусти из папки \bin\Debug\ файл test.exe и попробуй
  • отредактировано 20:26
    CodeMAP написал: »
    Странно, сейчас посмотрю твой отчёт. А то, что я тебе прислал - работает у тебя? Запусти из папки \bin\Debug\ файл test.exe и попробуй
    Подключил твой отчёт в свою программу - всё работает :)
    Смотри, проверяй https://yadi.sk/d/ddBxP6OXqwAHo
    На кнопку №1 повесил загрузку твоего файла отчёта.

    Пару замечаний сделаю.
    1. для красоты переменную i лучше объявлять в самом операторе for
    for(int i=0;i < label ;i++)
    
    Она тогда будет использоваться только в нём и нигде более.

    2. что бы получить корректное значение страниц надо либо начинать i с 0
    for(int i=0;i < label ;i++)
    
    либо условие выполнения цикла делать не меньше, а меньше либо равно
    for(int i=1;i <= label ;i++)
    

    3. В самом отчёте все статичные поля [CustName], [Address], [ItemNameSt] и [ProdId] лучше сделай в бэнде "Заголовок страницы". и можешь в них прямо в дизайнере, а не в коде, прописать значения. Они будут успешно повторяться на всех листах.

    Смотри в общем в переделанном файле отчёта
  • отредактировано 20:26
    CodeMAP написал: »
    Подключил твой отчёт в свою программу - всё работает :)
    Смотри, проверяй https://yadi.sk/d/ddBxP6OXqwAHo
    На кнопку №1 повесил загрузку твоего файла отчёта.

    Пару замечаний сделаю.
    1. для красоты переменную i лучше объявлять в самом операторе for
    for(int i=0;i < label ;i++)
    
    Она тогда будет использоваться только в нём и нигде более.

    2. что бы получить корректное значение страниц надо либо начинать i с 0
    for(int i=0;i < label ;i++)
    
    либо условие выполнения цикла делать не меньше, а меньше либо равно
    for(int i=1;i <= label ;i++)
    

    Все на скорую руку, в цикле с 1 и перебирать до <=

    3. В самом отчёте все статичные поля [CustName], [Address], [ItemNameSt] и [ProdId] лучше сделай в бэнде "Заголовок страницы". и можешь в них прямо в дизайнере, а не в коде, прописать значения. Они будут успешно повторяться на всех листах.

    Это поля динамические, по этой причине так их и присвоил. Так же по причине того, что на этикетке кол-ва этикеток находится в середине, мне надо использовать только какой то один бэнд. DataBand подходит. Так как он позволяет формировать новую страницу. У заголовка есть так же такое свойство, но как то не корректно отрабатывает.

    Смотри в общем в переделанном файле отчёта

    Да, твой отрабатывает без проблем проект, запускаю у себя предварительный просмотр с дизайнера, ничего не меняя, ошибка:

    В экземпляре объекта не задана ссылка на объект.
    System.NullReferenceException: В экземпляре объекта не задана ссылка на объект.
    в FastReport.Code.AssemblyDescriptor.InvokeEvent(String name, Object[] parms)
    в FastReport.Engine.ReportEngine.Run(Boolean runDialogs, Boolean append, Boolean resetDataState, ReportPage page)
    в FastReport.Report.Prepare(Boolean append)
    в FastReport.Design.ReportTab.Preview()
  • отредактировано 20:26
    Ну вроде как понятна причина. Мне надо это все делать под 2-м фрайворком
  • отредактировано 20:26
    ilyaae написал: »
    Ну вроде как понятна причина. Мне надо это все делать под 2-м фрайворком
    а почему именно под вторым?
  • отредактировано 20:26
    CodeMAP написал: »
    а почему именно под вторым?
    Пытаюсь вызвать печать с под ERP Dynamics ax 2009, а она дружит со сборками второго framework
  • отредактировано 20:26
    Готово!!! Проблема банальна. Одно что должно быть под 2-м фв, а второе - не внимательность. Передавал параметры, перед открытием шаблона.
    Спасибо за поддержку.
  • отредактировано 20:26
    ilyaae написал: »
    Готово!!! Проблема банальна. Одно что должно быть под 2-м фв, а второе - не внимательность. Передавал параметры, перед открытием шаблона.
    Спасибо за поддержку.
    Пожалуйста :)
  • отредактировано 20:26
    CodeMAP написал: »
    Пожалуйста :)
    Есть еще вопрос, может делал такое.
    Мне надо массив значений передать в репорт. Например: Создаю на стороне приложения селект и этот набор данных надо принять на стороне репортинга.
    Можно конечно в репортинге создать подключение, источник данных. Но это будет затратно для отчетника.
  • отредактировано 20:26
    ilyaae написал: »
    Есть еще вопрос, может делал такое.
    Мне надо массив значений передать в репорт. Например: Создаю на стороне приложения селект и этот набор данных надо принять на стороне репортинга.
    Можно конечно в репортинге создать подключение, источник данных. Но это будет затратно для отчетника.
    Если я тебя правильно понял, тебе надо просто зарегистрировать твой источник данных в репорте:
    _report.RegisterData();
    там куча перегрузок, можешь передать DataSet, DataTable или просто любое перечисление, например List
  • отредактировано 20:26
    CodeMAP написал: »
    Если я тебя правильно понял, тебе надо просто зарегистрировать твой источник данных в репорте:
    _report.RegisterData();
    там куча перегрузок, можешь передать DataSet, DataTable или просто любое перечисление, например List
    Так то оно так,источник надо зарегистрировать в аксапте и передать в репортинг. Пока не получается.
  • отредактировано 20:26
    Shalomb написал: »
    А почему не использовать сцепки SQL например Inner join для размножения записей и тогда отдав репорту DataSet он только отпечатает.
    Ситуация следующая, мне надо сформировать набор данных на стороне приложения и зарегистрировать в датасет в репортинге.

    List listByCode = new List( Types::String ) ;
    ;
    listByCode.addStart( 'Mum' ) ;
    listByCode.addEnd( 'washed' ) ;
    listByCode.addEnd( 'a' ) ;
    listByCode.addEnd( 'frame') ;

    fr.RegisterData(listByCode,"ListCode");
    Ругается на RegisterData - Аргумент "1" несовместим с требуемым типом.
  • отредактировано 20:26
    За аксапту не скажу, я в Visual Studio пишу. Вот такой код у меня работает без проблем

    List<string> listByCode = new List<string>();

    listByCode.Add("Mum");
    listByCode.Add("washed");
    listByCode.Add("a");
    listByCode.Add("frame");

    _report.RegisterData(listByCode, "ListCode");

    List<type> должен быть строго типизированный, с явно указанным типом значений
  • отредактировано 20:26
    CodeMAP написал: »
    За аксапту не скажу, я в Visual Studio пишу. Вот такой код у меня работает без проблем

    List<string> listByCode = new List<string>();

    listByCode.Add("Mum");
    listByCode.Add("washed");
    listByCode.Add("a");
    listByCode.Add("frame");

    _report.RegisterData(listByCode, "ListCode");

    List<type> должен быть строго типизированный, с явно указанным типом значений

    Как то туплю.
    Хорошо, зарегистрировал набор данных(предположим). Дальше в Visual Studio вызов отчета _report.Show();
    А в какой момент Visual Studio передает в репортинг значения? Получается, что надо передать еще _report.GetDataSource("ListCode");
    А как визуально разместить контролы на форме, если они формируются кодом и в репортинге нет источника и таблиц ?
  • отредактировано April 2016
    ilyaae написал: »
    Как то туплю.
    Хорошо, зарегистрировал набор данных(предположим). Дальше в Visual Studio вызов отчета _report.Show();
    А в какой момент Visual Studio передает в репортинг значения? Получается, что надо передать еще _report.GetDataSource("ListCode");
    А как визуально разместить контролы на форме, если они формируются кодом и в репортинге нет источника и таблиц ?

    Всё намного проще :) Регистрируешь данные RegisterData(), вызываешь дизайнер отчёта _report.Design(); В дизайнере, в менюшке верхней находишь "Выбрать данные для отчёта" и откроется окно, где ты увидишь зарегистрированные твои данные. Это же окно можно вызвать из окна "Данные" (справа, там же где свойства объектов) там кнопочка "Действия" -> "Выбрать данные для отчёта". Поставь галочку рядом с переданным именем источника данных. После этого в этом окне "Данные" ты увидишь свой источник данных, а оттуда поля хоть мышкой перетаскивыай в отчёт.
  • отредактировано 20:26
    Вот видюшку состряпал. https://yadi.sk/d/uJMtjeRhr6Sz9
    Не пугайся, там exe файл, но это видюшка :)
    Какой-то только непонятный глюк - когда у тебя List типа string то в отчёте видим не значения элементов, а их длину в символах... а если List<int> передавать то норм, значения видим. напишу в поддержку, пусть разъяснять почему так.
    Лучше сделай DataTable, там работает как надо и можешь без проблем несколько столбцов записывать и передавать в отчёт
  • отредактировано April 2016
    CodeMAP написал: »
    Вот видюшку состряпал. https://yadi.sk/d/uJMtjeRhr6Sz9
    Не пугайся, там exe файл, но это видюшка :)
    Какой-то только непонятный глюк - когда у тебя List типа string то в отчёте видим не значения элементов, а их длину в символах... а если List<int> передавать то норм, значения видим. напишу в поддержку, пусть разъяснять почему так.
    Лучше сделай DataTable, там работает как надо и можешь без проблем несколько столбцов записывать и передавать в отчёт
    Спасибо. У меня появилось Выбрать данные для отчета, но без полей, только элемент таблицы. Уже лучше. Получилось таким образом:
    System.Data.DataSet dataSet;
    ;
    dataSet = new System.Data.DataSet();
    dataSet.ReadXml(@c:\Card.xml);
    Но мне нужен источник таблиц приложения, разбираюсь
  • отредактировано 20:26
    А что такое "источник таблиц приложения"? :)
    о поводу передачи List<string> в поддержке мне вот что ответили:
    написал:
    Здравствуйте! Вы можете передать в отчёт список бизнес-объектов(классов):

    class YourObj
    {
    public int id{get;set;}
    public string name { get; set; }
    }
    .....
    List<YourObj> listByCode = new List<YourObj>();

    YourObj bobj = new YourObj();
    bobj.id = 0;
    bobj.name = "Name1";
    listByCode.Add(bobj);

    bobj = new YourObj();
    bobj.id = 1;
    bobj.name = "Name2";
    listByCode.Add(bobj);

    bobj = new YourObj();
    bobj.id = 2;
    bobj.name = "Name3";
    listByCode.Add(bobj);

    bobj = new YourObj();
    bobj.id = 3;
    bobj.name = "Name4";
    listByCode.Add(bobj);

    _report.RegisterData((listByCode), "ListCode");

    Т.е. ты объявляешь свой класс с неким набором полей, потом делаешь список с типом элементов - этот твой класс, и передаёшь в отчёт
  • отредактировано 20:26
    CodeMAP написал: »
    А что такое "источник таблиц приложения"? :)
    о поводу передачи List<string> в поддержке мне вот что ответили:
    Т.е. ты объявляешь свой класс с неким набором полей, потом делаешь список с типом элементов - этот твой класс, и передаёшь в отчёт
    Ну мне надо каким то чудесным образом dataSet присвоить значение таблицы или может запроса и в дальнейшем зарегистрировать в отчете :)

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.