Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 16.05.2024, 10:01
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Ошибка при заполнении TreeList

Просьба о помощи к уважаемым форумчанам! Руководство попросило исправить ошибки в программе (что то я уже исправил), и вот с очередной ошибкой зашел в тупик (понятно что все это от нехватки знаний, я не программист DELPHI, немного на VFP). Теперь о проблеме.

Пусть имеется два грида на разных формах (где все работатет- пусть будет FormaOK, а где ошибка, назовем FormaErr). На каждой расположен grid с вожможностью сортировки и фильтрации по колонкам в заголовке столбца.

На форме FormOK, если Grid не отображает записи (нет в выборке записей), при нажатии на фильтр, чтобы изменить параметры, список раскрывается все хорошо и там (наверно по умолчанию) есть строки Все....Расширенный и т.д

На форме FormErr, если Grid не отображает записи (нет в выборке записей), при нажатии на фильтр, чтобы изменить параметры, выходит ошибка (Access violatiion ...по такому то адресу), а если изначально grid отображает хоть какие то записи - и в этом случае все работает нормально, фильтр раскрывается.

При ошибке указывется на UNIT dxTL(TreeList я так понимаю)

Код:
1
2
3
4
5
6
7
function TdxTreeListNode.GetString(Column:Integer):string;
begin
try
Result:=FOwner.GetNodeString(Self,Column);
exept
end;
end;

Помогите разобраться пожалуйста, куда копать?
Ответить с цитированием
  #2  
Старый 16.05.2024, 21:30
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,094
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, есть подозрение, что код пытается получить список колонок из грида. А когда там нет записей, то нет и колонок (почему - надо смотреть, например, если запрос вернул пустой результат, то грид не подключается, например). Я бы смотрел в сторону того, что бы изменить код на получения колонок из DataSet (TTable/TQuery/etc).
А вообще, если в одной форме все работает правильно, а другой та же функция не работает, то просто попробуй сравнить код. AccessViolation говорит о том, что происходит обращение к несозданному объекту, или уже удаленному. Так что тут главное понять куда код "ломится", ну а поправить уже будет просто.
Ответить с цитированием
  #3  
Старый 17.05.2024, 08:06
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Вот код по событию EnumFilterValues в gride на форме FormaERR

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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 (закрасил * не для общего обозрения)

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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() (вот тут кажется и проблема)

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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  
Старый 17.05.2024, 08:21
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Да, спасибо что откликнулись! Визуально колонки есть на форме(шапка никуда не делась, выбор фильтра доступен). А может ли на это влиять настройки свойства OptionBehavior? У грида на форме FormaErr они шире (Больше true по позициям).
Ответить с цитированием
  #5  
Старый 17.05.2024, 10:50
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,094
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, проблема точно не в функции IsValueInFilter. Хотя она такая нафиг не нужна. Достаточно сделать
Код:
1
if FilterValues.IndexOf(Node.Strings[AColumn.Index]) > -1 ...
Тут либо в Node нет значения, либо в FilterValues.
Или они указывают на несуществуюший объект. Смотри где они описываются и инициализируются. Возможна ситуация, когда FilterValues описана в какой-то секции, где не происходит инициализация. В таком случае в указателе может быть какое-то значение, поэтому сравнение с Nil не проходит, но объект все-равно не существует. Проверяй как описана эта переменная в обеих формах и где она может быть проинициализированна.
Ответить с цитированием
  #6  
Старый 17.05.2024, 13:08
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо...пойду , куда послали.
Ответить с цитированием
  #7  
Старый 19.05.2024, 07:41
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,094
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну выкладывай полный код форм. Может еще потребуются какие-то модули. Я посмотрю.
Ответить с цитированием
  #8  
Старый 23.05.2024, 08:38
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Ну выкладывай полный код форм. Может еще потребуются какие-то модули. Я посмотрю.

Ну как бы я с удовольствием.... но скорее всего это не возможно, может только часть. Компонента ExpressQuantumGrid 3.2.2

Может подскажите, какие переменные вывести в отладчике. На форме, где все работает не получается прогнать аналогичную ситуацию по F7. Там всегда при открытии отображаются записи и чтобы установить фильтр когда их не будет....устала рука даже по F8. А как сделть чтобы останов срабатывал на втором проходе не знаю, хотя наверна такая возможность есть.
Ответить с цитированием
  #9  
Старый 23.05.2024, 20:22
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,094
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

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

Как я сказал ранее, скорее всего одна из переменных в том вызове просто не проинициализированна. Вот эту разницу и надо найти.
Ответить с цитированием
  #10  
Старый 24.05.2024, 15:01
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Изучая матчасть, наткнулся на это - https://www.gunsmoker.ru/2009/05/access-violation.html может кому будет интересно
Ответить с цитированием
  #11  
Старый 25.05.2024, 00:10
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,094
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Угу, читали
Думаю, что в твоем случае это вариант 7.
Ответить с цитированием
  #12  
Старый 27.05.2024, 16:33
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Форма где появляется ошибка
Вложения
Тип файла: zip F_err.zip (144.5 Кбайт, 2 просмотров)
Ответить с цитированием
  #13  
Старый 28.05.2024, 08:14
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,094
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну смотри.
Переменная FilterValues в этой форме не описана, соответственно, где она инициализируется неизвестно. Т.е. при некотором описании переменной там может быть мусор в указателе. Соответсвенно, обращение к ней может привести к AV. Тоже самое с переменной Node.
Теперь смотрим на форму, где все ок. Там тоже нет таких переменных или они там описаны локально (в этом случае локальная декларация имеет более высокий приоритет, чем декларация в другом модуле).
Потом можно еще проверить что будет происходить в случае, если сначала вызвать форму, где все ОК, а потом проблемную - возникнет ли ошибка.
Ответить с цитированием
  #14  
Старый 28.05.2024, 09:24
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Сейчас сделаю архив работающей формы. пароль тот же Она первая и запускается и весит параллельно (разные окна)
Ответить с цитированием
  #15  
Старый 28.05.2024, 09:34
VolgaLEG VolgaLEG вне форума
Прохожий
 
Регистрация: 16.05.2024
Сообщения: 18
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Форма где все хорошо
Вложения
Тип файла: zip Fok.zip (68.4 Кбайт, 3 просмотров)
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:58.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025