Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.03.2014, 21:52   #1
PaHaNjkee
Delphi 10 Seattle
Пользователь
 
Аватар для PaHaNjkee
 
Регистрация: 01.11.2010
Сообщений: 90
По умолчанию Проблема с функцией

Вообщем на форме 2 кнопочки и PageControl с двумя TabSheets. При нажатии на кнопку которая лежит на TabSheet1 создается GroupBox и в нём Edit (сколько нажатий, столько и создаётся)
Код:
CreateGB(NumQuest, sTabSheet1, GBQuest, EditQuest);
При создании формы указал размер массива:
Код:
var
  GBQuest: array of TsGroupBox;
  EditQuest: array of TsEdit;
  NumQuest: Integer;

const
  MAX_QUESTIONS: integer = 6;

procedure TForm3.FormCreate(Sender: TObject);
begin
  NumQuest := 0;
  NumAnswer := 0;
  SetLength(GBQuest,MAX_QUESTIONS+1);
  SetLength(EditQuest,MAX_QUESTIONS+1);
end;
Нажимаю на кнопку создаётся один GroupBox, затем нажимаю второй раз и исключение.. "Access violation at adress .. "
Код:
if NumQuest < MAX_QUESTIONS then begin
    NumQuest := NumQuest + 1;
    CreateGB(NumQuest, sTabSheet1, GBQuest, EditQuest);
  end;
Вот сама функция:
Код:
function TForm3.CreateGB(Num: Integer; TB: TsTabSheet; GB: Array of TsGroupBox; Ed: Array of TsEdit): string;
var
  CountChars, i: integer;
  tmp: String;
begin
  CountChars := Length(Chars);
  if Num <= MAX_QUESTIONS then begin
    GB[Num] := TsGroupBox.Create(self);
    with GB[Num] do begin
      Parent := TB;
      for i := 1 to 3 do
        tmp := Chars[Random(CountChars)+1];
      Name := tmp+IntToStr((random(100)*Num));
      Caption := 'Quest '+IntToStr(Num);
      Height := 65;
      Width := 313;
      Left := 0;
      if Num <= 1 then
        Top := StartTop
      else
        Top := GB[Num-1].Top + 74;
    end;
    if Num >= 6 then begin
      Form3.Height := Form3.Height + 74;
      sPageControl1.Height := sPageControl1.Height + 74;
    end;
    Ed[Num] := TsEdit.Create(self);
    with Ed[Num] do begin
      Parent := GB[Num];
      for i := 1 to 3 do
        tmp := Chars[Random(CountChars)+1];
      Name := tmp+IntToStr((random(100)*Num));
      Text := '';
      Height := 21;
      Width := 297;
      Left := 8;
      Top := 24;
    end;
  end;
end;
Ругается как я понял на эту строчку:
Код:
Top := GB[Num-1].Top + 74;
Но почему? Размер массива я указал при создании формы, т.е. если я создаю первый GroupBox, переменная := 1, потом переменная := 2 и он не может найти GBQuest[1]? Что за бред?
Изображения
Тип файла: jpg Безымянный.jpg (34.0 Кб, 140 просмотров)

Последний раз редактировалось PaHaNjkee; 25.03.2014 в 21:56.
PaHaNjkee вне форума Ответить с цитированием
Старый 25.03.2014, 22:03   #2
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,872
По умолчанию

Динамические массивы индексируются с 0, а элемент GB[0] никто не создавал.
northener вне форума Ответить с цитированием
Старый 25.03.2014, 22:07   #3
PaHaNjkee
Delphi 10 Seattle
Пользователь
 
Аватар для PaHaNjkee
 
Регистрация: 01.11.2010
Сообщений: 90
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Динамические массивы индексируются с 0, а элемент GB[0] никто не создавал.
Да, не спорю, но есть же проверка
Код:
if Num <= 1 then
  Top := StartTop
else
  Top := GB[Num-1].Top + 74;
Т.е. если переменная переменная > 1, то этот массив никак не будет равняться 0

Странно, так работает
Код:
Top := GB[Num].Top + 74;
Но мне нужно узнать Top предыдущего GroupBox'а

Последний раз редактировалось Stilet; 25.03.2014 в 22:41.
PaHaNjkee вне форума Ответить с цитированием
Старый 25.03.2014, 22:14   #4
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,872
По умолчанию

А что будет когда Num станет равно MAX_QUESTIONS?
northener вне форума Ответить с цитированием
Старый 25.03.2014, 22:17   #5
PaHaNjkee
Delphi 10 Seattle
Пользователь
 
Аватар для PaHaNjkee
 
Регистрация: 01.11.2010
Сообщений: 90
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
А что будет когда Num станет равно MAX_QUESTIONS?
Просто GroupBox не будет создаваться и все.
Может функция с массивами не может возвращать String? Я уже просто низнаю, что ему не нравится.
Код:
function TForm3.CreateGB(Num: Integer; TB: TsTabSheet; GB: Array of TsGroupBox; Ed: Array of TsEdit): string;
PaHaNjkee вне форума Ответить с цитированием
Старый 25.03.2014, 22:32   #6
XE5
Заблокирован
 
Регистрация: 02.03.2014
Сообщений: 439
По умолчанию

Цитата:
Сообщение от PaHaNjkee Посмотреть сообщение
Странно, так работает
Код:
Top := GB[Num].Top + 74;
Но мне нужно узнать Top предыдущего GroupBox'а
Код:
if Num > Low(GB) then
  Top := GB[Num -1].Top + 74;
P.S. Совет. Если глобально объявлены два, или более массива одинакового размера, то гораздо удобнее создать тип Record, занести туда нужные элементы, и объявить один массив Record записей, вместо двух массивов. Так же советую не задавать размерность массива при старте программы, а увеличивать его длину по мере внесения новых записей.

Последний раз редактировалось XE5; 25.03.2014 в 22:34.
XE5 вне форума Ответить с цитированием
Старый 25.03.2014, 22:37   #7
PaHaNjkee
Delphi 10 Seattle
Пользователь
 
Аватар для PaHaNjkee
 
Регистрация: 01.11.2010
Сообщений: 90
По умолчанию

Цитата:
Сообщение от XE5 Посмотреть сообщение
Код:
if Num > Low(GB) then
  Top := GB[Num -1].Top + 74;
P.S. Совет. Если глобально объявлены два, или более массива одинакового размера, то гораздо удобнее создать тип Record, занести туда нужные элементы, и объявить один массив Record записей, вместо двух массивов. Так же советую не задавать размерность массива при старте программы, а увеличивать его длину по мере внесения новых записей.
Спасибо, учту. Помоему понял в чем проблема. Я не указал размер динамического массива GB.
PaHaNjkee вне форума Ответить с цитированием
Старый 25.03.2014, 22:39   #8
XE5
Заблокирован
 
Регистрация: 02.03.2014
Сообщений: 439
По умолчанию

Вы не слышите о чём я Вам говорю. Не нужно указывать размерность массива при старте программы. Учитесь динамически менять размерность по мере надобности.
if Num <= MAX_QUESTIONS then begin
SetLength(GB, Length(GB) + 1);
GB[Num] := TsGroupBox.Create(self);


А лучше так.

Код:
if Num > Length(GB) then begin // если индекс вышел за размер массива
SetLength(GB, Length(GB) + 1); // увеличиваем длину массива
GB[Num] := TsGroupBox.Create(self); // инициализируем последний элемент массива

Последний раз редактировалось XE5; 25.03.2014 в 22:46.
XE5 вне форума Ответить с цитированием
Старый 25.03.2014, 22:43   #9
PaHaNjkee
Delphi 10 Seattle
Пользователь
 
Аватар для PaHaNjkee
 
Регистрация: 01.11.2010
Сообщений: 90
По умолчанию

Теперь не могу назначить длину массива, пишет, мол, не совместимые типы.
Код:
SetLength(GB, Length(GB) + 1);
Код:
[Error] Unit3.pas(62): Incompatible types
PaHaNjkee вне форума Ответить с цитированием
Старый 25.03.2014, 22:52   #10
XE5
Заблокирован
 
Регистрация: 02.03.2014
Сообщений: 439
По умолчанию

Нельзя менять длину массива, переданного в процедуру, как параметр. Уберите из имени процедуры массивы, и обращайтесь к ним напрямую. Всё будет работать. Либо так.

function TForm3.CreateGB(Num: Integer; TB: TsTabSheet; var GB: Array of TsGroupBox; Ed: Array of TsEdit): string;
XE5 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ПРоблема с функцией! dpmkh Общие вопросы Delphi 6 12.10.2012 18:42
проблема с функцией Madmaxisss Паскаль, Turbo Pascal, PascalABC.NET 5 23.08.2012 13:46
проблема с функцией Си blain Помощь студентам 1 19.02.2012 21:06
Проблема с функцией MeTeOpA C# (си шарп) 6 11.07.2011 00:07