22.3. Датасторадж-форматы

Если мы хотим, чтобы данные текстового поля с именем 'item_Name' в приложении отображались другим цветом, нужно создать класс датасторадж-формата, перекрыть в нем виртуальный метод, возвращающий цвет текста, вернуть нужный цвет и на старте приложения создать прототип этого класса для нашего имение поля:

type
  TmyDataStorageFieldFormat = class(TdfSimpleDataFormat)
  public
    function GetFontColor(_RecNo: Integer): TColor; override;
  end;
   
function TmyDataStorageFieldFormat.GetFontColor(_RecNo: Integer): TColor;
begin
  Result := clGreen;
end;
     
TMyDataStorageFieldFormat.CreateGenerator('item_Name');
      

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

Вызовы методов датасторадж-форматов очень многочисленны при отображении данных, поэтому необходимо заботиться об эффективности кода.

При отображении данных поля формат может обращаться к данным других полей набора. Например, для отображения складского объема формат использует дополнительные поля meit_Rate и meit_Format:

function TdfMeasuredValue.GetRate(RecNo: Integer): Double;
var
  F: TssDataStorageField;
begin
  F := FormatStringFields.FieldByName(GetRateFieldName, Self);
  if Assigned(F) and not F.IsNull[RecNo] {нет доступа, например} then begin
    Result := F.AsFloat[RecNo];
...
  end else
    Result := 1;
      

Для беспрепятственного отображения данных пользовательских запросов, датасторадж-форматы не генерируют исключений в случае неправильно написанного запроса. Это является задачей разработчика форматов. В приведенном выше примере проверяется наличие поля Rate и возможность пустого значения в нем. На случай отсутствия поля или значения предусмотрено дефолтное поведение Result := 1.

Подробнее о соглашениях в запросах написано далее. При запуске Менеджера из-под среды разработки формат возвращает текст таких ошибок вместе с данными:

Поиск прототипа в глобальном списке производится по совпадению начала имени поля. Если он не найден, выполняется поиск по типу данных. Общее для типов данных поведение обеспечивается отдельным списком прототипов, созданных конструктором CreateGeneratorByDataType.

Для поля с суффиксом все дополнительные поля должны возвращаться с тем же суффиксом:

SELECT T1.idit_Volume, T2.meit_Rate, T2.meit_Format,
  T3.idit_Volume 'idit_Volume_Rest', T4.meit_Rate 'meit_Rate_Rest',
  T4.meit_Format 'meit_Format_Rest'