Ацесс виолейшн !
Привет.
Используем Fast Report 4.7.66 для Дельфи 7.
Замучала одна неприятная ошибка...
При подготовке отчета, если в TfrxDBDataset прописано поле (и оно используется в отчете) - которого в запросе не окажется - вылетаешь Access Violation.
Вот сделайте эти простые шаги чтобы получить ошибку
1. В TOraQuery (или его аналогах) напишите любой запрос с двумя полями. Вот такой например
Select 1 as S1, 2 as S2
from dual
2. Обновите связаный TfrxDBDataset - чтобы он подцепил эти два поля.
3. В Отчетнике киньте простой мастер-бенд, привяжите его к TfrxDBDataset и киньте 2 мемки чтобы вывести оба поля.
4. Исправте запрос - убрав одно из полей.
Select 1 as S1
from dual
НЕ обновляйте TfrxDBDataset !!!!!!! В нем должна остатся ссылка на уже отсутсвующее поле
5. Запустите отчет. Вылетает Acess Violation.
Уж очень неприятен этот ацесс виолейшн. Пока поймешь откуда вообще ошибка, пока поймешь что проблема в том, что идет ссылка на несуществующее поле......
Пожалуйста - исправьте эту ошибку - точнее сделайте вывод Exception'а... А то очень уж муторно искать что за ацесс виолейшн...
Ошибка вываливается вот сюда:
frxDBSet.pas
function TfrxDBDataset.GetValue(Index: String): Variant;
var
i: Integer;
v: Variant;
begin
if not FInitialized then
Open;
i := Fields.IndexOf(Index);
if i <> -1 then
begin
{$IFDEF Delphi6}
if TField(Fields.Objects) is TFMTBCDField then
begin
if TField(Fields.Objects).IsNull then
v := Null
else if BCDToCurrency then
v := TField(Fields.Objects).AsCurrency
else
v := TField(Fields.Objects).AsFloat
end
else
{$ENDIF}
if TField(Fields.Objects) is TLargeIntField then
begin
{ TLargeIntField.AsVariant converts value to vt_decimal variant type
which is not supported by Delphi }
if TField(Fields.Objects).IsNull then
v := Null
else
{$IFDEF Delphi6}
v := TLargeIntField(Fields.Objects).AsLargeInt
{$ELSE}
v := TField(Fields.Objects).AsInteger
{$ENDIF}
end
{$IFDEF Delphi6}
else if TField(Fields.Objects) is TSQLTimeStampField then
v := TSQLTimeStampField(Fields.Objects).AsDateTime
{$ENDIF}
else
v := TField(Fields.Objects).Value <<<< Тут и вываливается
end
else
begin
v := Null;
ReportRef.Errors.Add(ReportRef.CurObject + ': ' +
frxResources.Get('dbFldNotFound') + ' ' + UserName + '."' + Index + '"');
end;
Result := v;
end;
Используем Fast Report 4.7.66 для Дельфи 7.
Замучала одна неприятная ошибка...
При подготовке отчета, если в TfrxDBDataset прописано поле (и оно используется в отчете) - которого в запросе не окажется - вылетаешь Access Violation.
Вот сделайте эти простые шаги чтобы получить ошибку
1. В TOraQuery (или его аналогах) напишите любой запрос с двумя полями. Вот такой например
Select 1 as S1, 2 as S2
from dual
2. Обновите связаный TfrxDBDataset - чтобы он подцепил эти два поля.
3. В Отчетнике киньте простой мастер-бенд, привяжите его к TfrxDBDataset и киньте 2 мемки чтобы вывести оба поля.
4. Исправте запрос - убрав одно из полей.
Select 1 as S1
from dual
НЕ обновляйте TfrxDBDataset !!!!!!! В нем должна остатся ссылка на уже отсутсвующее поле
5. Запустите отчет. Вылетает Acess Violation.
Уж очень неприятен этот ацесс виолейшн. Пока поймешь откуда вообще ошибка, пока поймешь что проблема в том, что идет ссылка на несуществующее поле......
Пожалуйста - исправьте эту ошибку - точнее сделайте вывод Exception'а... А то очень уж муторно искать что за ацесс виолейшн...
Ошибка вываливается вот сюда:
frxDBSet.pas
function TfrxDBDataset.GetValue(Index: String): Variant;
var
i: Integer;
v: Variant;
begin
if not FInitialized then
Open;
i := Fields.IndexOf(Index);
if i <> -1 then
begin
{$IFDEF Delphi6}
if TField(Fields.Objects) is TFMTBCDField then
begin
if TField(Fields.Objects).IsNull then
v := Null
else if BCDToCurrency then
v := TField(Fields.Objects).AsCurrency
else
v := TField(Fields.Objects).AsFloat
end
else
{$ENDIF}
if TField(Fields.Objects) is TLargeIntField then
begin
{ TLargeIntField.AsVariant converts value to vt_decimal variant type
which is not supported by Delphi }
if TField(Fields.Objects).IsNull then
v := Null
else
{$IFDEF Delphi6}
v := TLargeIntField(Fields.Objects).AsLargeInt
{$ELSE}
v := TField(Fields.Objects).AsInteger
{$ENDIF}
end
{$IFDEF Delphi6}
else if TField(Fields.Objects) is TSQLTimeStampField then
v := TSQLTimeStampField(Fields.Objects).AsDateTime
{$ENDIF}
else
v := TField(Fields.Objects).Value <<<< Тут и вываливается
end
else
begin
v := Null;
ReportRef.Errors.Add(ReportRef.CurObject + ': ' +
frxResources.Get('dbFldNotFound') + ' ' + UserName + '."' + Index + '"');
end;
Result := v;
end;
Комментарии
Объясните плиз популярно как обновицо
- удалите FR;
- удалите все *frx*.dcu, *fs*.dcu, frx*.bpl, fs*.bpl из Borland\Projects\Bpl и Windows\system32, также удалите папки, в которых ещё остались файлы FR;
- установите последний билд;
Проблема с DisplayFormat исчезла - УРААААА. А то я так извращался что просто жесть (нужно было три формата одной мемке, так приходилось на бенд три ряда мемок кидать - каждая со своим форматом, и динамически визиблить их, меняя высоту у бенда... Короче муть).
А вот проблема с аццесс виолейшн осталась.
Ребят - вы планируете ее убирать то ?
Я вроде приложил как ее с эмулировать.... Если чего могу скрины сделать и приложить....
Жду, надеюсь )
Просто я работаю над отчетом с кучей мастеров и деталей... И данные передаются через процедуру через sys_refcursor.
Проблема лишь в том, что серверной частью занимаюсь не я - ну и сами понимаете кто то иногда чего то забывает на сервере прописать блин в селект - и летят блин ацесс виолейшины...
Чего бы хотелось - очень бы хотелось чтобы сообщалось имя отсутствубщего поля... А то сейчас поиски идут методом тыка... точнее удаления по одному полю и последующему запуску отчета на предмет "заработало ?".... Прям как по минному полю шаг вперед проверка еще шаг вперед - заработало ааа урааа я нашел его !
PS Версия 4.9 у мну