Форум по 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 я так понимаю)

Код:
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,053
Версия 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

Код:
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  
Старый 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,053
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, проблема точно не в функции IsValueInFilter. Хотя она такая нафиг не нужна. Достаточно сделать
Код:
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,053
Версия 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,053
Версия 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,053
Версия 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 Кбайт, 1 просмотров)
Ответить с цитированием
  #13  
Старый 28.05.2024, 08:14
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,053
Версия 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 Кбайт, 2 просмотров)
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter