После установки версии 3.16 отчеты, ранее нормально работающие, перестали открываться. Ошибка: Could not convert variant of type (Null) into type (OleStr). Данные для отчета берутся из MS SQL через TADODataset.
Все следы предыдущей версии выкорчеваны полностью? Более подробное описание проблемы на support сбросьте, чтобы можно было её смоделировать. Или, лучше, простенький пример сами набросайте и отошлите.
procedure TForm1.Button1Click(Sender: TObject);
begin
ADODataset1.ConnectionString:=...; //Формируем строку подключения к SQL-серверу через SQLOLEDB
ADODataset1.CommandText:='select Field1, Field2 from table1';
ADODataset1.Open;
frxReport1.ShowReport(); //Как только доходит до записи, содержащей NULL - возникает ошибка.
end;
Порывшись в исходниках, нашел:
В модуле frxDBSet в функции TfrxDBDataset.GetDisplayText есть такие строки:
{$IFDEF Delphi5}
if TField(Fields.Objects) is TWideStringField then
s := TField(Fields.Objects).Value
else
{$ENDIF}
s := TField(Fields.Objects).DisplayText;
Value с типом Variant присваивается переменной s типа WideString. Естественно, если Value равно Null, будет ошибка.
Порывшись в исходниках, нашел:
В модуле frxDBSet в функции TfrxDBDataset.GetDisplayText есть такие строки:
{$IFDEF Delphi5}
if TField(Fields.Objects) is TWideStringField then
s := TField(Fields.Objects).Value
else
{$ENDIF}
s := TField(Fields.Objects).DisplayText;
Value с типом Variant присваивается переменной s типа WideString. Естественно, если Value равно Null, будет ошибка.
А ещё если бы вы посмотрели хелп, то после того наверняка нашли бы в исходниках frxClass.pas строки которые разрешит Вашу проблему автоматически:
if FEngineOptions.ConvertNulls and (Value = Null) then
case ds.FieldType[fld] of
fftNumeric: Value := 0;
fftString: Value := '';
fftBoolean: Value := False;
end;
Result := True;
Для этого в EngineOptions репорта выставите опцию ConvertNulls в true.
Комментарии
Вот простенький пример:
...
TForm1 = class(TForm)
ADODataSet1: TADODataSet;
frxDBDataset1: TfrxDBDataset;
Button1: TButton;
frxReport1: TfrxReport;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
ADODataset1.ConnectionString:=...; //Формируем строку подключения к SQL-серверу через SQLOLEDB
ADODataset1.CommandText:='select Field1, Field2 from table1';
ADODataset1.Open;
frxReport1.ShowReport(); //Как только доходит до записи, содержащей NULL - возникает ошибка.
end;
Порывшись в исходниках, нашел:
В модуле frxDBSet в функции TfrxDBDataset.GetDisplayText есть такие строки:
{$IFDEF Delphi5}
if TField(Fields.Objects) is TWideStringField then
s := TField(Fields.Objects).Value
else
{$ENDIF}
s := TField(Fields.Objects).DisplayText;
Value с типом Variant присваивается переменной s типа WideString. Естественно, если Value равно Null, будет ошибка.
{$IFDEF Delphi5}
if TField(Fields.Objects) is TWideStringField then
s := VarToWideStr(TField(Fields.Objects).Value)
if FEngineOptions.ConvertNulls and (Value = Null) then
case ds.FieldType[fld] of
fftNumeric: Value := 0;
fftString: Value := '';
fftBoolean: Value := False;
end;
Result := True;
Для этого в EngineOptions репорта выставите опцию ConvertNulls в true.
Fix от AlexTZ помог.