Fastreport.data.dictionary метод Merge

отредактировано 15:20 Раздел: FastReport .NET
Обнаружилась интересная бага:
            //Создание данных для отчета
            DataSet ds = new DataSet("dset");
            DataTable dt1 = new DataTable("dtable 1");
            DataTable dt2 = new DataTable("dtable 2");
            DataColumn dcID1 = new DataColumn("Id", typeof(int));
            DataColumn dcName1 = new DataColumn("Name", typeof(string));
            DataColumn dcID2 = new DataColumn("Id", typeof(int));
            DataColumn dcName2 = new DataColumn("NName", typeof(string));
            dt1.Columns.Add(dcID1);
            dt1.Columns.Add(dcName1);
            dt2.Columns.Add(dcID2);
            dt2.Columns.Add(dcName2);

            for (int i = 0; i < 10; i++)
            {
                DataRow dr1 = dt1.NewRow();
                dr1[0] = i;
                dr1[1] = "Name 1" + i;
                dt1.Rows.Add(dr1);
                DataRow dr2 = dt2.NewRow();
                dr2[0] = 9 - i;
                dr2[1] = "Name " + (i - 1);
                dt2.Rows.Add(dr2);
            }
            ds.Tables.Add(dt1);
            ds.Tables.Add(dt2);
            ds.Relations.Add(new DataRelation("1rel", dt1.Columns[0], dt2.Columns[0]));

            //Создаем отчет 1
            FastReport.Report first = new FastReport.Report();
            //Регистрируем данные
            first.RegisterData(ds, ds.DataSetName);
            first.Design(); //данные переданы и доступны в отчете
            //Создем отчет 2
            FastReport.Report second = new FastReport.Report();
            //Сливаем словари 1 и 2
            second.Dictionary.Merge(first.Dictionary);
            second.Design(); //даннае успешно "сливаются", НО
            first.Design(); //данных в словаре первого отчета уже нет!

после завершения метода Merge словарь отчета second содержит данные из словаря первого отчета, но при этом в словаре первого зарегистрированных данных уже нет :)

Комментарии

  • отредактировано 15:20
    Да, так и есть. Метод Merge обслуживает соответствующую команду в окне "Данные" и поэтому просто переносит данные из старого словаря в новый:
        public void Merge(Dictionary source)
        {
          ObjectCollection sourceObjects = source.ChildObjects;
          foreach (Base c in sourceObjects)
          {
            Base my = FindByName(c.Name);
            if (my != null)
              my.Dispose();
            c.Parent = this;
          }
          ReRegisterData();
        }
    
  • отредактировано 15:20
    значить не бага... фича.
    Но в моем случае это разные словари разных отчетов. ИМХО как-то некорректно, что операция Merge затрагивает источник. Вообщем задача сводится к тому, чтоб из имеющегося словаря получить его независимую копию.

    Команды окна данных сейчас посмотрел, тоже не все понятно:
    Жмем: Данные -> Действия -> Новый словарь данных
    потом: Пункт меню Данные -> выбрать данные для отчета.... =>
    Окошко выбора таблиц пустое
    Далее: Данные -> Действия -> Открыть словарь данных => выбираем какой-нибудь сохраненный до этого словарь (отличный от того, что изначально передавался в отчет)
    Данные -> выбрать данные для отчета.... => содержит таблицы и только что открытого словаря, и таблицы исходного... т.е. создается новый словарь и "сливается" с данными зарегистрированными в отчете?
  • отредактировано 15:20
    Кое-что исправил. Можете проверить на очередной сборке.
  • отредактировано March 2009
    Посмотрел, словари теперь нормально сливаются. Но
    ...
    //Сливаем словари 1 и 2
                second.Dictionary.Merge(first.Dictionary);
                second.Design();
    
    после запуска дизайнера в отчете second в окне "выбрать данные для отчета..." у таблиц отсутствуют связи (точнее единственная связь "1rel"). В словаре она присутствуют, но в дизайнере не отображаются.
  • отредактировано 15:20
    Да, есть такой момент. Поправил, очередная версия соберется ночью.
  • отредактировано March 2009
    Вот еще момент, тоже видимо связан с изменениями объекта Dictionary:
               ....
               //Создаем отчет 1
                FastReport.Report first = new FastReport.Report();
                //Регистрируем данные (см. 1й пост)
                first.RegisterData(ds, ds.DataSetName);
               
                //Создем отчет 2
                FastReport.Report second = new FastReport.Report();
                //Сливаем словари 1 и 2
                second.Dictionary.Merge(first.Dictionary);
                second.Design(); 
                //В дизайнере на DataBand кладем поле из какой-нибудь таблицы
                //DataBand привязывается к этой таблице
                //Еще раз сливаем словари
                second.Dictionary.Merge(first.Dictionary);
                second.Design(); //Все добавленные при первом редактировании объекты отчета second остались,
                //но пропала привызка DataBand`ов к данным
    
    т.е. второй вызов second.Dictionary.Merge(first.Dictionary) затрагивает привязку данных.
    и еще вопрос, не планируется экспорт документов в doc (или OpenXML).
  • отредактировано 15:20
    Да, такая выбрана стратегия замещения данных с одинаковыми именами. Если в словаре уже есть элемент с таким же именем, то он берется из второго словаря, а исходный элемент удаляется. При этом, естественно, становятся неактуальными ссылки на него. Пофиксить это уже невозможно.
  • отредактировано 15:20
    Экспорт планируется, но не скоро, в порядке очередности.
  • отредактировано 15:20
    AlexTZ написал: »
    Да, такая выбрана стратегия замещения данных с одинаковыми именами. Если в словаре уже есть элемент с таким же именем, то он берется из второго словаря, а исходный элемент удаляется. При этом, естественно, становятся неактуальными ссылки на него. Пофиксить это уже невозможно.
    "факир был пьян, и фокус не удался..."
    Хотел сделать, чтоб данные хранились только в одном словаре (у этого словаря StoreData == true), и при необходимости передавались бы в отчеты из него. Т.е. имеется группа отчетов, построенная по одним и тем же данным. В некоторых отчетах может использоваться только часть таблиц из общих данных. Для обновления данных всей группы необходимо обновить только общий словарь из базы данных. Тогда, например, если база данных недоступна, отчеты все равно можно строить и отображать по ранее загруженным данным из общего словаря.
  • отредактировано 15:20
    Да, типичный пример того, как фичи используются не по назначению :)
    Св-во StoreData я сделал, чтобы облегчить себе отладку отчетов. Ф-я Merge вообще была сделана "для галочки"...
  • отредактировано 15:20
    StoreData - очень полезная фича для обеспечения автономности отчетов. А вот с Merge да, я погорячился... встретил знакомое название метода и решил использовать. Вообщем спасибо за ответы, буду дальше сильно думать.

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

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