FastReport: автоматический перевод словаря данных

© 2002 Виталий Кубекин

Многие программисты используют генераторов отчетов FastReport в своих программах. Достаточно часто, они дают возможность конечному пользователю изменять шаблоны документов. Данная возможность генератора отчетов FastReport позволяет пользователям наиболее полно использовать возможности программы. Но дизайнер документов можно немного усовершенствовать. Собственно об одном таком усовершенствовании и пойдет речь в данной статье.

Итак, что будем совершенствовать? Совершенствовать будем работу со "Словарем данных" генератора отчетов FastReport. Начнем с одного из мастеров дизайнера шаблона документов.


Рис.1.

Рис.2.

На рис.1 можно увидеть, как выглядит мастер "Вставка поля БД" в генераторе отчетов FastReport. Ничего непонятного программисту здесь нет, а что тут может быть непонятного? На форме "DataModule1" находится таблица "Table1", а в ней есть список полей, которые можно добавить в отчет. Но как должен себя чувствовать стандартный пользователь (например, бухгалтер с 10 летним стажем), когда увидит это окно. Да можно сказать, что "такой пользователь" в дизайнер отчетов и не полезет. Но даже человеку "близкому" к компьютерам эта запись ничего не скажет. Даже если будет написано "Data.Personal" это ничего не меняет. Вот если бы было написано "Персонал", и список полей бы не на шокирующим для обыкновенного пользователя английском языке, а на русском было бы совершенно другое дело. Как это сделать?

Сделать в FastReport это очень просто достаточно зайти в "Словарь данных" и сопоставить "DataModule1.Table1" - "Персонал", "EmpNo"-"Номер", "LastName"-"Фамилия","FirstName"-"Имя". После такого изменения мастер "Вставка поля БД" примет вид как на рис. 2. Согласитесь так он выглядит намного лучше и понятнее.

Вроде все просто и аккуратно кроме одного, все эти изменения необходимо делать вручную и для каждого DataSet-а и в каждом отчете. А что если DataSet-ов скажем 100, а отчетов скажем 50, то изменить это вручную становится титаническим трудом. Вот если бы программа сама правильно перед использованием каждого отчета заполняла "Словарь данных". Написать процедуру для автоматического заполнения "Словаря данных" FastReport не очень сложно. При написании могут возникнуть следующие вопросы.

Первый вопрос - как получить доступ к "Словарю данных" генератора отчетов FastReport? Как это сделать написано в FAQ к FastReport.

Вопрос второй - где взять "перевод" на каждое английское название поля таблицы? Ответ очень прост. В типе TField есть property DisplayLabel, в нем находится наименование поля для отображения в Grid-ах и т.д. (я думаю про это все в курсе). Так вот никто не мешает воспользоваться этими данными.

Вопрос третий - где взять наименование таблицы. Этот вопрос немного сложнее и решать его можно по-разному. Во многих базах данных для таблиц существует поле description(описание) можно его заполнять. Можно завести специальную таблицу. Варианты могут быть разные.

Итак, приступим к написанию процедур. Первая процедура заполняет "Словарь данных" для одного DataSet.

//====================================
//Входные параметры
//Dictionary - "Словарь данных" FastReport
//DataSet - объект класса TDataSet или производного от него класса (например, TTable)
//TableNameRus - русское наименование таблицы

procedure FR_Rename(var Dictionary: TfrDataDictionary; var DataSet: TDataset; TableNameRus: string);
var
  a: integer;
begin
  //Если DataSet открыт, то продолжаем,
  //если закрыт то исключаем его вообще из "словаря данных"
  if DataSet.Active = true then
    begin
      with Dictionary do
        begin
          //Переименовываем DataSet
          FieldAliases.Variable[ DataSet.Owner.Name + '.' + DataSet.Name ] := TableNameRus;
          for a := 0 to DataSet.FieldDefs.Count - 1 do
            if DataSet.FindField( DataSet.FieldDefs[a].Name ) <> nil then
              begin
                //Этой строчкой мы исключаем те строки из "словаря данных"
                //которые мы не хотим в нем видеть
                //Принцип очень прост, если displaylabel = Name
                //(например 'EmpNo'<>'Номер' или 'EmpNo'='EmpNo')
                //то поле исключается

                if DataSet.FindField( DataSet.FieldDefs[a].Name ).Displaylabel <>DataSet.FieldDefs[a].Name then
                   //Устанавливаем русское наименование поля
                  FieldAliases.Variable[ DataSet.Owner.Name + '.' + DataSet.Name + '.' + DataSet .FieldDefs[a].Name] := DataSet.FindField(DataSet.FieldDefs[a].Name).Displaylabel
                //Исключаем поле из "Словаря данных"
                else FieldAliases.Variable[DataSet.Owner.Name + '.' + DataSet.Name + '.' + DataSet.FieldDefs[a].Name] := ''
              end
              //Исключаем поле из "Словаря данных" если оно не найдено в Fields
              else FieldAliases.Variable[DataSet.Owner.Name + '.' + DataSet.Name + '.' + DataSet.FieldDefs[a].Name] := '';
            end;
          end
        //Исключение DataSet из "Словаря данных"
        else Dictionary.DisabledDatasets.Add(data.Owner.Name+'.'+DataSet.Name);
end;
//====================================

Эта функция возвращает наименование таблицы.

//====================================
Function GetDataSetName(Name: string):string;
Begin
  if Name = 'Table1'
    then Result := 'Персонал'
    else if Name = 'Table2'
      then Result := 'Страна'
      else Result := Name;
End;
//====================================

Эта процедура переводит все DataSet, которые она найдет на форме и которые будут открыты. Закрытые DataSet исключаются из "Словаря данных".

//====================================
//Входные параметры
//Dictionary - "Словарь данных" FastReport
//Form - форма на которой находятся DataSet

procedure FR_DataModule_Rename(var Dictionary: TfrDataDictionary;var Form: TForm);
var
  a: integer;
  DataSet: TDataSet;
Begin
  //Перебираем все компоненты формы
  for a := 0 to Form.ComponentCount - 1 do
  if (Form.Components[a] is TDataSet) then
    begin
      //Если класс компонента TDataSet или его потомок
      DataSet := TDataSet(Form.Components[a]);
      //Перевод DataSet
      FR_Rename(Dictionary,DataSet, GetDataSetName(DataSet.Name));
    end;
end;
//====================================

Желающие могут скачать исходные тексты примера (4.93K)

По всем вопросам обращайтесь по адресу vtl@msx.ru.

Copyright© 2002 Виталий Кубекин  Специально для Delphi Plus

2011123456789101112
2010123456789101112
2009123456789101112
2008123456789101112
2007123456789101112
2006123456789101112
2005123456789101112
2004123456789101112
2003123456789101112
2002123456789101112
2001123456789101112
2000123456789101112
1999123456789101112

Последние статьи
Литература