|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
Ошибка при заполнении TreeList
Просьба о помощи к уважаемым форумчанам! Руководство попросило исправить ошибки в программе (что то я уже исправил), и вот с очередной ошибкой зашел в тупик (понятно что все это от нехватки знаний, я не программист DELPHI, немного на VFP). Теперь о проблеме.
Пусть имеется два грида на разных формах (где все работатет- пусть будет FormaOK, а где ошибка, назовем FormaErr). На каждой расположен grid с вожможностью сортировки и фильтрации по колонкам в заголовке столбца. На форме FormOK, если Grid не отображает записи (нет в выборке записей), при нажатии на фильтр, чтобы изменить параметры, список раскрывается все хорошо и там (наверно по умолчанию) есть строки Все....Расширенный и т.д На форме FormErr, если Grid не отображает записи (нет в выборке записей), при нажатии на фильтр, чтобы изменить параметры, выходит ошибка (Access violatiion ...по такому то адресу), а если изначально grid отображает хоть какие то записи - и в этом случае все работает нормально, фильтр раскрывается. При ошибке указывется на UNIT dxTL(TreeList я так понимаю) Код:
function TdxTreeListNode.GetString(Column:Integer):string; begin try Result:=FOwner.GetNodeString(Self,Column); exept end; end; Помогите разобраться пожалуйста, куда копать? |
#2
|
|||
|
|||
Ну, есть подозрение, что код пытается получить список колонок из грида. А когда там нет записей, то нет и колонок (почему - надо смотреть, например, если запрос вернул пустой результат, то грид не подключается, например). Я бы смотрел в сторону того, что бы изменить код на получения колонок из DataSet (TTable/TQuery/etc).
А вообще, если в одной форме все работает правильно, а другой та же функция не работает, то просто попробуй сравнить код. AccessViolation говорит о том, что происходит обращение к несозданному объекту, или уже удаленному. Так что тут главное понять куда код "ломится", ну а поправить уже будет просто. |
#3
|
|||
|
|||
Вот код по событию EnumFilterValues в gride на форме FormaERR
Код:
procedure TMailForm.dxDBGridArxivEnumFilterValues(Sender: TObject; AColumn: TdxDBTreeListColumn; var AValue: Variant; var ADisplayText: string; var ARepeatEnumeration: Boolean); var LookKey: string; LookIndex: Integer; begin try // finally if FilterValues = nil then FilterValues := TStringList.Create; if Node = nil then Node := TdxDBGrid(Sender).TopVisibleNode; // Далее появляется ошибка if IsValueInFilter(FilterValues, Node.Strings[AColumn.Index]) then begin Node := TdxDBGrid(Sender).GetNextVisible(Node); Exit; end else FilterValues.Add(Node.Strings[AColumn.Index]); ADisplayText := Node.Strings[AColumn.Index]; if TdxDBGrid(Sender).Columns[AColumn.Index].Field.FieldKind <> fkLookup then AValue := Node.Values[AColumn.Index] else begin LookKey := TdxDBGrid(Sender).ColumnByFieldName(AColumn.FieldName).Field.KeyFields; LookIndex := TdxDBGrid(Sender).FindColumnByFieldName(LookKey).Index; AValue := Node.Values[LookIndex]; end; Node := TdxDBGrid(Sender).GetNextVisible(Node); if Node = nil then begin FilterValues.Free; FilterValues := nil; ARepeatEnumeration := False; end; finally Inc(FilterDropCount); if FilterDropCount > 100 then begin FilterValues.Free; FilterValues := nil; Node := nil; FilterDropCount := 0; ARepeatEnumeration := False; end; end; end; Для сравнения, далее код из формы по событию EnumFilterValues, где все работает FormaOK (закрасил * не для общего обозрения) Код:
procedure TMainForm.dxDBGrid_PersonEnumFilterValues(Sender: TObject; AColumn: TdxDBTreeListColumn; var AValue: Variant; var ADisplayText: string; var ARepeatEnumeration: Boolean); var LookKey: string; LookIndex: Integer; begin try // finally if FilterValues = nil then FilterValues := TStringList.Create; if Node = nil then Node := TdxDBGrid(Sender).TopVisibleNode; // Тут все проходит if IsValueInFilter(FilterValues, Node.Strings[AColumn.Index]) then begin Node := TdxDBGrid(Sender).GetNextVisible(Node); Exit; end else FilterValues.Add(Node.Strings[AColumn.Index]); ADisplayText := Node.Strings[AColumn.Index]; if TdxDBGrid(Sender).Columns[AColumn.Index].Field.FieldKind <> fkLookup then AValue := Node.Values[AColumn.Index] else begin LookKey := TdxDBGrid(Sender).ColumnByFieldName(AColumn.FieldName).Field.KeyFields; LookIndex := TdxDBGrid(Sender).FindColumnByFieldName(LookKey).Index; AValue := Node.Values[LookIndex]; end; if AColumn.FieldName = 'LLP_PERSONS_RESULT' then begin if AValue = 'D' then ADisplayText := 'Отработан'; if AValue = 'W' then ADisplayText := 'Ожидание'; end; if AColumn.FieldName = 'ISMAKET' then begin case AValue of 0: ADisplayText := 'Отсутствует'; 1: ADisplayText := 'Фрагмент'; 2: ADisplayText := 'Полный'; end; end; if AColumn.FieldName = 'SOURCE_OOPP' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := '**********'; end; end; if AColumn.FieldName = 'SOURCE_SZVK' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := '********'; end; end; if AColumn.FieldName = 'SOURCE_PENS' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := '*********'; end; end; if AColumn.FieldName = 'SOURCE_PTK' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := '******************'; end; end; if AColumn.FieldName = 'SOURCE_ZAGS' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := '*******************'; end; end; if AColumn.FieldName = 'SOURCE_MANUAL' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := 'Ручной ввод'; end; end; if AColumn.FieldName = 'SOURCE_CZN' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := '***************'; end; end; if AColumn.FieldName = 'CMN_SOURCE_DREG' then begin case AValue of 0: ADisplayText := ''; 1: ADisplayText := 'Данные из другого региона'; end; end; if AColumn.FieldName = 'SOURCE_ASV' then begin if VarIsNull(AValue) then AValue := 0; case AValue of 0: ADisplayText := ''; 1: ADisplayText := '********************'; end; end; Node := TdxDBGrid(Sender).GetNextVisible(Node); if Node = nil then begin FilterValues.Free; FilterValues := nil; ARepeatEnumeration := False; end; CurColumn := AColumn.FieldName; finally Inc(FilterDropCount); if FilterDropCount > MAX_DROP_COUNT then begin FilterValues.Free; FilterValues := nil; Node := nil; FilterDropCount := 0; ARepeatEnumeration := False; end; end; end; Пользовательская функция IsValueInFilter() (вот тут кажется и проблема) Код:
function IsValueInFilter(FValues: TStringList; S: string): Boolean; var i: Integer; res: Boolean; begin res := False; for i := 0 to FValues.Count-1 do begin if FValues[i] = S then begin res := True; Break; end; end; Result := res; end; |
#4
|
|||
|
|||
Да, спасибо что откликнулись! Визуально колонки есть на форме(шапка никуда не делась, выбор фильтра доступен). А может ли на это влиять настройки свойства OptionBehavior? У грида на форме FormaErr они шире (Больше true по позициям).
|
#5
|
|||
|
|||
Ну, проблема точно не в функции IsValueInFilter. Хотя она такая нафиг не нужна. Достаточно сделать
Код:
if FilterValues.IndexOf(Node.Strings[AColumn.Index]) > -1 ... Или они указывают на несуществуюший объект. Смотри где они описываются и инициализируются. Возможна ситуация, когда FilterValues описана в какой-то секции, где не происходит инициализация. В таком случае в указателе может быть какое-то значение, поэтому сравнение с Nil не проходит, но объект все-равно не существует. Проверяй как описана эта переменная в обеих формах и где она может быть проинициализированна. |
#6
|
|||
|
|||
Спасибо...пойду , куда послали.
|