|
|
Регистрация | << Правила форума >> | 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
|
|||
|
|||
Спасибо...пойду , куда послали.
|
#7
|
|||
|
|||
Ну выкладывай полный код форм. Может еще потребуются какие-то модули. Я посмотрю.
|
#8
|
|||
|
|||
Цитата:
Ну как бы я с удовольствием.... но скорее всего это не возможно, может только часть. Компонента ExpressQuantumGrid 3.2.2 Может подскажите, какие переменные вывести в отладчике. На форме, где все работает не получается прогнать аналогичную ситуацию по F7. Там всегда при открытии отображаются записи и чтобы установить фильтр когда их не будет....устала рука даже по F8. А как сделть чтобы останов срабатывал на втором проходе не знаю, хотя наверна такая возможность есть. |
#9
|
|||
|
|||
Форма, где все работает, интересна только как образец.
Форма, где возникает ошибка - собсвенно то, где надо искать отличие от формы, где все работает. В сам компонент необходимости лезть я не вижу пока, т.к. он работает, что и демонстрирует форма, где все ок. Как я сказал ранее, скорее всего одна из переменных в том вызове просто не проинициализированна. Вот эту разницу и надо найти. |
#10
|
|||
|
|||
Изучая матчасть, наткнулся на это - https://www.gunsmoker.ru/2009/05/access-violation.html может кому будет интересно
|
#11
|
|||
|
|||
Угу, читали
Думаю, что в твоем случае это вариант 7. |
#12
|
|||
|
|||
Форма где появляется ошибка
|
#13
|
|||
|
|||
Ну смотри.
Переменная FilterValues в этой форме не описана, соответственно, где она инициализируется неизвестно. Т.е. при некотором описании переменной там может быть мусор в указателе. Соответсвенно, обращение к ней может привести к AV. Тоже самое с переменной Node. Теперь смотрим на форму, где все ок. Там тоже нет таких переменных или они там описаны локально (в этом случае локальная декларация имеет более высокий приоритет, чем декларация в другом модуле). Потом можно еще проверить что будет происходить в случае, если сначала вызвать форму, где все ОК, а потом проблемную - возникнет ли ошибка. |
#14
|
|||
|
|||
Сейчас сделаю архив работающей формы. пароль тот же Она первая и запускается и весит параллельно (разные окна)
|
#15
|
|||
|
|||
Форма где все хорошо
|