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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.04.2009, 20:04
Аватар для rasamaha
rasamaha rasamaha вне форума
Прохожий
 
Регистрация: 28.03.2009
Сообщения: 19
Репутация: 10
По умолчанию Проблема с параметрами процедуры...

Код:
var
  L, S: Integer;

for L:=1 to StringGrid1.RowCount do
        begin
        S:=StrToInt(StringGrid1.Cells[7,L]);
        if S<=14 then
          begin
          Label15.Visible:=true;
          Label15.Caption:='До записи осталось меньше 14 дней!';
           break;                                                                                       
          end;
        end;

Этот код выполняется в нескольких местах: при загрузке таблицы, при изменении содержимого и при добавлении новой записи.
Хочу написать собственную процедуру этой проверки... но не получается... у меня проблема с описанием этой процедуры и с передачей параметров
Я не смог найти материала по написанию собственных функций и процедур, а то что есть в книгах, очень скудный материал...
Помогите пожалуйста, можно на этом примере, можно на собственных...
Куда что писать?
Ответить с цитированием
  #2  
Старый 12.04.2009, 20:27
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Во-первых, ошибка в коде. А именно,
Код:
for L:=1 to StringGrid1.RowCount do
Когда переменная L получит значение, равное StringGrid1.RowCount, произойдет обращение к несуществующей ячейке. Как вы помните, нумерация начинается с нуля и заканчивается значением StringGrid1.RowCount-1.

Во-вторых, не очень понятно, что конкретно вы желаете получить от своей собственной процедуры и чем не устраивает имеющаяся... Ну создайте процедуру и вставьте этот код в нее. Параметры ей, думаю не нужны, если объект StringGrid1 все время один и тот же.
Ответить с цитированием
  #3  
Старый 12.04.2009, 20:40
Аватар для rasamaha
rasamaha rasamaha вне форума
Прохожий
 
Регистрация: 28.03.2009
Сообщения: 19
Репутация: 10
По умолчанию

проблемы были, когда начальное значение L было равно 0, потому что первая строка, заголовочная пустая. а сейчас проблем с проверкой нет,
даже если L=StringGrid.RowCount

Я не знаю что писать в скобках при описании процедуры и что писать в тех же скобках при вызове этой процедуры.

У меня такая проблема уже не впервой...
Скорей всего мне нужно знать, где можно прочитать подробный материал по написанию своих собственных функций и процедур.

А эта функция просто проверяет содержимое определенных ячеек и если значение меньше, то... и если условие на какой-то ячейке выполнено, то выход из цикла...
Ответить с цитированием
  #4  
Старый 12.04.2009, 20:43
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

На этом форуме была тема с кучей книг по Delphi для новичков. В каждой книге по Delphi ОБЯЗАТЕЛЬНО есть статья по написанию процедур и функций. Штудируй))
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #5  
Старый 12.04.2009, 20:48
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

rasamaha, а сюда не заглядывали? =)
И вообще, в нормальных книгах достаточно подробно расписывается материал о создании подпрограмм (процедур и функций)

И все же по поводу ошибки: предлагаю вам заполнить всю седьмую колонку числами, заведомо бОльшими, чем 14. И посмотреть, как там "проблем нет"...
Ответить с цитированием
  #6  
Старый 12.04.2009, 20:48
Аватар для rasamaha
rasamaha rasamaha вне форума
Прохожий
 
Регистрация: 28.03.2009
Сообщения: 19
Репутация: 10
По умолчанию

popyurv, спасибо за совет)) у меня дома пять книг по Делфи, и ...
а вроде не дурак, говорят знакомые))) а написать собственную так и не получилось, вечно выдает ошибку что что-то не так с параметрами или их не достаточно...
я еще раз проштудирую эту тему, может где что упустил...
а лучше попробую еще раз написать и выложить код, чтоб вы посмотрели)
Ответить с цитированием
  #7  
Старый 12.04.2009, 20:51
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Цитата:
Куда что писать?
А что конкретно Вы хотите проверять? Если это известно - то отсюда и отпляшем
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #8  
Старый 12.04.2009, 23:16
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Я так понял вы пытаетесь оптимизировать вашу программу, для чего повторяющиеся блоки кода хотите вынести в процедуры. Ошибки скорее всего у вас возникают потому-что вы нарушаете правила "видимости переменных". Вот с этим наверное и разберитесь в первую очередь, а уже после этого вы поймете имеет ли смысл в вашу процедуру передавать параметры или она без них будет правильно работать.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #9  
Старый 13.04.2009, 03:11
Аватар для rasamaha
rasamaha rasamaha вне форума
Прохожий
 
Регистрация: 28.03.2009
Сообщения: 19
Репутация: 10
По умолчанию

вот код программы:

Код:
unit Tabliza1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, ComCtrls, Menus, DateUtils, Calendar, Mask;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    GroupBox1: TGroupBox;
    ComboBox1: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    DateTimePicker1: TDateTimePicker;
    DateTimePicker2: TDateTimePicker;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N6: TMenuItem;
    Button1: TButton;
    Button2: TButton;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Button3: TButton;
    Edit2: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure SaveDialog1CanClose(Sender: TObject; var CanClose: Boolean);
    procedure DateTimePicker1Change(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{******************************************************************************}

procedure TForm1.FormCreate(Sender: TObject);
begin
  DateTimePicker1.Date:=Date;
  DateTimePicker2.Date:=DateTimePicker1.Date+10;
end;

//Показываем диалог сохранения файла.
procedure TForm1.N3Click(Sender: TObject);
begin
  SaveDialog1.Execute;
end;

//Сохраняем таблицу в файл *.txt
procedure TForm1.SaveDialog1CanClose(Sender: TObject; var CanClose: Boolean);
var
  i, LastRow: Integer;
  SList: TStringList;
begin
  SList := TStringList.Create;
  LastRow := StringGrid1.RowCount - 1;
  try
    for i := 0 to LastRow do
      SList.Add(StringGrid1.Rows[i].CommaText);
      SList.SaveToFile(SaveDialog1.FileName);
    finally
    SList.Free;
  end;
end;

//Заполняем таблицу из файла *.txt
procedure TForm1.N2Click(Sender: TObject);
var
  i, LastRow, CommaPos: Integer;
  FirstStr: string;
  SList: TStringList;
begin
  if not OpenDialog1.Execute then Exit;
  SList := TStringList.Create;
  try
    SList.LoadFromFile(OpenDialog1.FileName);
    StringGrid1.RowCount := SList.Count;
    FirstStr := SList.Strings[0];
    i := 0; CommaPos := Pos(',', FirstStr);
    while CommaPos <> 0 do
    begin
      Delete(FirstStr, 1, CommaPos);
      Inc(i);
      CommaPos := Pos(',', FirstStr);
    end;
    StringGrid1.ColCount := i + 1;
    LastRow := StringGrid1.RowCount - 1;
    for i := 0 to LastRow do
      StringGrid1.Rows[i].CommaText := SList.Strings[i];
  finally
    SList.Free;
end;
end;

//Добавляем строку в StringGrid1
procedure TForm1.Button1Click(Sender: TObject);
var
  rt: Integer;
begin
   with StringGrid1 do
    begin
      if RowCount>2 then
        begin
        rt:=RowCount;
        Edit4.Text:=InttoStr(rt);
        Cells[0,rt-1]:=InttoStr(rt-1);
        Cells[1,rt-1]:=Edit1.Text;
        Cells[2,rt-1]:=ComboBox1.Text;
        Cells[3,rt-1]:=DateToStr(DateTimePicker1.Date);
        DateTimePicker2.Date:=DateTimePicker1.Date+10;
        Cells[4,rcnt-1]:=DateToStr(DateTimePicker2.Date);
        Label14.Caption:=IntToStr(DaysBetween(Date,DateTimePicker2.Date));
        Cells[5,rt-1]:=Label1.Caption;
        RowCount:=RowCount+1;
        end;
      if RowCount=2 then
        begin
        rt:=RowCount-1;
        Edit4.Text:=InttoStr(rt);
        Cells[0,rt]:=InttoStr(rt);
        Cells[1,rt]:=Edit1.Text;
        Cells[2,rt]:=ComboBox1.Text;
        Cells[35,rt]:=DateToStr(DateTimePicker1.Date);
        DateTimePicker2.Date:=DateTimePicker1.Date+10;
        Cells[4,rt]:=DateToStr(DateTimePicker2.Date);
        Label1.Caption:=IntToStr(DaysBetween(Date,DateTimePicker2.Date));
        Cells[5,rt]:=Label14.Caption;
        RowCount:=RowCount+1;
        end;
     end;
end;

//
procedure Lka (Sg: TStringGrid);
var
L, S: Integer;
StringGrid1: TStringGrid;
Label2: TLabel; 
 begin

  for L:=1 to StringGrid1.RowCount do
        begin
        S:=StrToInt(StringGrid1.Cells[5,L]);
        if S<=10 then
          begin
          Label2.Visible:=true;
          Label2.Caption:='до записи осталось меньше 10 дней!';
           break;
          end;
        end;
   end;
//При изменении даты DateTimePicker1 высчитываем дату следующей записи
//                                    и кол-во дней до следующей записи
procedure TForm1.DateTimePicker1Change(Sender: TObject);
begin
   DateTimePicker2.Date:=DateTimePicker1.Date+10;
   Label14.Caption:=IntToStr(DaysBetween(Date,DateTimePicker2.Date));
end;

//Удаляем строку со здвигом
procedure SGDeleteRow(SG: TStringGrid; RowToDelete: Integer);
var
  i: Integer;
begin
   if (RowToDelete > 0) and (RowToDelete < SG.RowCount) then
    begin
    i:=RowToDelete;
      while i < SG.RowCount do
        begin
        SG.Rows[i].Assign(SG.Rows[i+1]);
        SG.Cells[0,i]:=IntToStr(i);
        i:=i+1;
        end;
      end;
    SG.RowCount := SG.RowCount - 1;

end;

procedure TForm1.Button3Click(Sender: TObject);
var RowToDelete: Integer;
begin
  if StringGrid1.RowCount <=2 then
  ShowMessage('Нельзя удалить все строки из списка!')
  else
  begin
  RowToDelete:=StringGrid1.Selection.Top;
  SGDeleteRow(StringGrid1,RowToDelete);
  end;
end;



//Переносим данные субъекта из строки таблицы в панель редактирования}
procedure TForm1.StringGrid1Click(Sender: TObject);
var RowToEdit: Integer;
begin
  RowToEdit:=StringGrid1.Selection.Top;
        Edit1.Text:=StringGrid1.Cells[1,RowToEdit];
        ComboBox3.Text:=StringGrid1.Cells[2,RowToEdit];
        if  StringGrid1.Cells[5,RowToEdit] = '' then
           begin
           DateTimePicker1.Date:=Date;
           DateTimePicker2.Date:=DateTimePicker1.Date+10;
           Label1.Caption:=IntToStr(DaysBetween(Date,DateTimePicker2.Date));
           end
          else
           begin
           DateTimePicker1.Date:=StrToDate(StringGrid1.Cells[5,RowToEdit]);
           DateTimePicker2.Date:=DateTimePicker1.Date+10;
           Label1.Caption:=StringGrid1.Cells[5,RowToEdit];
           end;
end;



//Обновляем отредактированную строку, переносим данные в таблицу
procedure TForm1.Button2Click(Sender: TObject);
var nst: Integer;
begin
   with StringGrid1 do
     begin
      nst:=StrToInt(Edit4.Text);
        Cells[0,nst]:=InttoStr(nst);
        Cells[1,nst]:=Edit1.Text;
        Cells[2,nst]:=ComboBox1.Text;
        Cells[3,nst]:=DateToStr(DateTimePicker1.Date);
        Cells[4,nst]:=DateToStr(DateTimePicker2.Date);
        Cells[5,nst]:=Label1.Caption;
     end;
     Edit4.Text:='';
   Edit1.Text:='';
   ComboBox1.ItemIndex:= -1;
   DateTimePicker1.Date:=Date;
   DateTimePicker2.Date:=DateTimePicker1.Date+10;
   Label1.Caption:=IntToStr(DaysBetween(Date,DateTimePicker2.Date));
   Lka;
end;

// Закрываем программу
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var buttomSel: Integer;

begin
  buttomSel:= MessageDlg('Сохранить список перед закрытием?'
                                          ,mtCustom, [mbOk], 0);
  // Показ типа выбранной кнопки
  if buttomSel = mrOK     then
     SaveDialog1.Execute;
end;

end.

есть панель редактирования со Editoм, ComboBoxом и календарями.
Моя собственная процедура Lka, не работает...

что я тут не так сделал?

Последний раз редактировалось rasamaha, 13.04.2009 в 03:20.
Ответить с цитированием
  #10  
Старый 13.04.2009, 09:21
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

rasamaha, во-первых, ваша собственная процедура Lka принимает параметр Sg, который нигде не использует. Отсюда скорейший вывод — параметры ей не нужны, т.е. следует переписать ее как-то так:
Код:
procedure Lka;
var
L, S: Integer;
// и так далее .............
Во-вторых, не очень понятно, зачем вы внутри этой процедуры объявляете переменную StringGrid1 типа TStringGrid, которая, между прочим, требует вызова конструктора Create для инициализации (а иначе не будет работать), и к тому же у вас уже есть компонент на форме компонент StringGrid1, имеющий то же самое имя... Я все же предполагаю, что вы работаете именно с той StringGrid, что лежит на форме? Поэтому объявление переменной StringGrid1 из процедуры тоже следует выкинуть. То же самое касается переменной Label2 в вашей процедуре. Итого:
Код:
procedure Lka;
var
  L, S: Integer;
begin
  for L:=1 to Form1.StringGrid1.RowCount - 1 do
  begin
    S := StrToInt(Form1.StringGrid1.Cells[5,L]);
    if S <= 10 then
    begin
      Form1.Label2.Visible:=true;
      Form1.Label2.Caption:='до записи осталось меньше 10 дней!';
      break;
    end;
  end;
end;
Остальное практически не смотрю, т.к. слишком много компонентов на форме. Если что, прикладывайте содержимое dfm-файла.
Ответить с цитированием
  #11  
Старый 14.04.2009, 15:06
Аватар для glaZZ
glaZZ glaZZ вне форума
Прохожий
 
Регистрация: 18.11.2008
Сообщения: 26
Репутация: 10
По умолчанию

Для работоспособности процедуры ее бы неплохо было еще и объявить:
Код:
...
procedure Button3Click(Sender: TObject);
procedure StringGrid1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Lka (Sg: TStringGrid);

private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Да и описание процедуры в implementation делается следующим образом:
Код:
procedure TForm1.Lka (Sg: TStringGrid);
var
L, S: Integer;
StringGrid1: TStringGrid;
Label2: TLabel; 
 begin

  for L:=1 to StringGrid1.RowCount do
        begin
        S:=StrToInt(StringGrid1.Cells[5,L]);
        if S<=10 then
          begin
          Label2.Visible:=true;
          Label2.Caption:='до записи осталось меньше 10 дней!';
           break;
          end;
        end;
   end;
Ответить с цитированием
  #12  
Старый 14.04.2009, 15:20
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

glaZZ, процедура Lka не обязана быть методом объекта Form1. И тогда она может не объявляться, если описана раньше в коде, чем происходит ее вызов.
Ответить с цитированием
  #13  
Старый 14.04.2009, 15:37
Аватар для glaZZ
glaZZ glaZZ вне форума
Прохожий
 
Регистрация: 18.11.2008
Сообщения: 26
Репутация: 10
По умолчанию

Nyctos Kasignete, не буду спорить - для определенных случаев можно и не объявлять, но в большинстве случаев лучше сделать так, как я написал
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter