Лидеры рейтинга

ID: 226425

Konstantin Shvetski

Мастер-Эксперт

960

Россия, Северодвинск


ID: 259041

Алексеев Владимир Николаевич

Мастер-Эксперт

548

Россия, пос. Теплоозёрск, ЕАО


ID: 401284

Михаил Александров

Академик

354

Россия, Санкт-Петербург


ID: 137394

Megaloman

Мастер-Эксперт

312

Беларусь, Гомель


ID: 400669

epimkin

Профессионал

275


ID: 400484

solowey

Профессор

73


ID: 401888

puporev

Профессор

53

Россия, Пермский край


8.1.6

02.01.2021

JS: 2.2.2
CSS: 4.2.0
jQuery: 3.5.1


 

Создание программ на языках Pascal, Delphi и Lazarus.

Администратор раздела: Зенченко Константин Николаевич (Старший модератор)


Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 269
Gluck
Статус: 6-й класс
Рейтинг: 222
puporev
Статус: Профессор
Рейтинг: 53
 

Перейти к консультации №:
 

Консультация онлайн # 199693
Раздел: • Pascal / Delphi / Lazarus
Автор вопроса: Ericsson (Посетитель)
Дата: 23.11.2020, 10:36
Поступило ответов: 0

Здравствуйте! Прошу помощи в следующем вопросе:
Delphi
Посчитать сумму к оплате в StringGrid : стоимость путевки на одного человека * количество взрослых и детей (на ребенка с учетом скидки в 20%).
Нужно чтобы когда вводишь значения в стоимость путёвки, кол-во взрослых и детей сразу вычислялась сумма. Я так понимаю это надо делать через событие SetEditText.
Помогите пожалуйста, застрял на этом.

-----
Прикрепленное изображение (кликните по картинке для увеличения):

Состояние: Консультация закрыта

Oтветов пока не поступило.

Мини-форум консультации № 199693

Зенченко Константин Николаевич

Старший модератор

ID: 31795

1

 +1 
 
= общий = |  23.11.2020, 11:36 |  цитировать |  профиль |  личное сообщение
Ericsson:

Код покажите.

Насколько я понял "стоимость путевки на одного взрослого человека" - это в сутки.
Я бы первое изменил в Form1.StringGrid1.Options опцию goEditing := true.
Тогда Вы будете работать с каждой ячейкой грида как с Edit, т.е. у Вас появится возможность вводить прямо в грид.

Ещё посмотрел бы на функцию TryStrToInt - проверяет возможность перевода строки в число. Т.к. пользователь может ввести что угодно, и программа будет вылетать если там не число, а так ему можно всегда сказать что он smile

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Ericsson

Посетитель

ID: 403884

2

= общий = |  23.11.2020, 12:38 |  цитировать |  профиль |  личное сообщение

"стоимость путевки на одного взрослого человека" - это значение просто задаётся пользователем, без привязки ко времени.
Я не особо понимаю как это сделать, поэтому написал "что-то"

Код (Pascal) :: выделить код
unit prog;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.ToolWin, Vcl.ActnMan,
  Vcl.ActnCtrls, Vcl.ActnMenus, Vcl.StdCtrls, Vcl.Grids;

type
  TForm3 = class(TForm)
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    Editing: TMenuItem;
    Help: TMenuItem;
    About: TMenuItem;
    OpenT: TMenuItem;
    OpenAsT: TMenuItem;
    SaveT: TMenuItem;
    SaveAsT: TMenuItem;
    out: TMenuItem;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Table: TStringGrid;
    EditOn: TMenuItem;
    EditOff: TMenuItem;
    procedure AboutClick(Sender: TObject);
    procedure outClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure OpenTClick(Sender: TObject);
    procedure EditOnClick(Sender: TObject);
    procedure EditOffClick(Sender: TObject);
    procedure HelpClick(Sender: TObject);
    procedure SaveTClick(Sender: TObject);
    procedure SaveAsTClick(Sender: TObject);
    procedure OpenAsTClick(Sender: TObject);
    procedure TableSetEditText(Sender: TObject; ACol, ARow: Integer;
      const Value: string);
    procedure TableSelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

uses Help, ABOUT1;

procedure TForm3.FormCreate(Sender: TObject);
begin
Table.ColWidths[0] := 40;
Table.Cells[0, 0] := '№';
Table.Cells[1, 0] := 'номер тура';
Table.Cells[2, 0] := 'страна';
Table.Cells[3, 0] := 'количество дней';
Table.Cells[4, 0] := 'фамилия туриста';
Table.Cells[5, 0] := 'количество взрослых';
Table.Cells[6, 0] := 'количество детей';
Table.Cells[7, 0] := 'стоимость путевки на одного взрослого человека';
Table.Cells[8, 0] := 'сумма к оплате';

end;

procedure TForm3.EditOnClick(Sender: TObject);
begin
self.Table.Options := self.Table.Options + [goEditing];
end;


procedure TForm3.EditOffClick(Sender: TObject);
begin
self.Table.Options := self.Table.Options - [goEditing];
end;

procedure TForm3.HelpClick(Sender: TObject);
begin
Form1.Show;
end;

procedure TForm3.AboutClick(Sender: TObject);
begin
AboutBox.Show;
end;

procedure TForm3.OpenAsTClick(Sender: TObject);
var L: TStringList;
      i: integer;
begin
 if not OpenDialog1.Execute then Exit;
 L := TStringList.Create;
 L.LoadFromFile(OpenDialog1.FileName);
 for i := 0 to L.Count - 1 do
  Table.Rows[i].CommaText := L.Strings[i];
 L.Free;
end;

procedure TForm3.OpenTClick(Sender: TObject);
var List: TStringList;
  i, j: Integer;
begin
Table.Visible:=True;
List:=TStringList.Create;
List.LoadFromFile('таблица.txt');
with Table do
  for i:=0 to RowCount-1 do
  for j:=0 to  ColCount-1 do
    Cells[j, i]:=List[i*ColCount+j];
end;

procedure TForm3.SaveAsTClick(Sender: TObject);
var L: TStringList;
      i: integer;
begin
 if not SaveDialog1.Execute then Exit;
 L := TStringList.Create;
 for i := 0 to Table.RowCount - 1 do
  L.Add(Table.Rows[i].CommaText);
 L.SaveToFile(SaveDialog1.FileName);
 L.Free;
end;

procedure TForm3.SaveTClick(Sender: TObject);
var List: TStringList;
  i, j: Integer;
begin
List:=TStringList.Create;
with Table do
  for i:=0 to RowCount-1 do
  for j:=0 to  ColCount-1 do
    List.Add(Cells[j, i]);
List.SaveToFile('таблица.txt');
end;

procedure TForm3.TableSelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
if (ARow=Table.RowCount-1)
   or (ACol=Table.ColCount-1)
          then CanSelect:=False;
end;

procedure TForm3.TableSetEditText(Sender: TObject; ACol, ARow: Integer;
  const Value: string);
var
b, n, c: integer; { b  - значение строки редактирования}
j: byte;  { j - параметр цикла для текущего номера столбца}
nRow, adult, child: real;
begin
with Table do
  if (ARow<>RowCount-1) and (ACol<>ColCount-1) then
   begin
    if value <> ' ' then {если введенное значение не пусто}
     begin
      val(Value, b, c); {переводим в число}
      if (c<>0) then
      Cells[ACol, ARow]:=' ';
      end;
      nRow:=0; {обнуляет сумму оценок в строке}
      for j:=5 to 7 do
      if Cells[j,ARow]<>'' then
     {если ячейка таблицы с координатами j, ARow не пустая}
      begin
       adult:=StrToFloat (Table.Cells [5,1])+StrToFloat (Table.Cells [7,1]);
       child:=StrToFloat (Table.Cells [6,1])+ StrToFloat (Table.Cells [7,1])*0.2;
       nRow:=nRow+adult+child;
      end;
     Table.Cells[8,ARow]:= nRow;
   end;
end;

procedure TForm3.outClick(Sender: TObject);
begin
close;
end;

end.

Последнее редактирование 23.11.2020, 12:51 Ericsson (Посетитель)

Ericsson

Посетитель

ID: 403884

3

= общий = |  23.11.2020, 12:55 |  цитировать |  профиль |  личное сообщение

Там в SetEditText я для себя пытался хотя-бы что-то сделать в первой строке. Но нужно чтобы считались и последующие ячейки

Зенченко Константин Николаевич

Старший модератор

ID: 31795

4

 +1 
 
= общий = |  23.11.2020, 16:04 |  цитировать |  профиль |  личное сообщение
Ericsson:

Сразу оговорюсь у меня не 10-ка, а D6

Код (Pascal) :: выделить код
procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,
  ARow: Integer; const Value: String);
  var
    a,b,c,d,e,f:integer;
  begin
    if(ARow>0)and(ARow<Form1.StringGrid1.RowCount)and
      (ACol>0)and(ACol<Form1.StringGrid1.ColCount)then
      if Value<>''then
        begin
          Form1.StringGrid1.Cells[ACol,ARow]:=Value;
          if tryStrToInt(Form1.StringGrid1.Cells[3,ARow],a)then
            begin
              if tryStrToInt(Form1.StringGrid1.Cells[4,ARow],b)then
                begin
                  if tryStrToInt(Form1.StringGrid1.Cells[5,ARow],c)then
                    begin
                      if tryStrToInt(Form1.StringGrid1.Cells[6,ARow],d)then
                        begin
                          if tryStrToInt(Form1.StringGrid1.Cells[7,ARow],e)then
                            begin
                              Form1.StringGrid1.Cells[8,ARow]:=IntToStr(a*(b*c+d*e));
                            end
                            else ShowMessage('7 '+IntToStr(ARow));
                        end
                        else ShowMessage('6 '+IntToStr(ARow));
                    end
                    else ShowMessage('5 '+IntToStr(ARow));
                end
                else ShowMessage('4 '+IntToStr(ARow));
            end
            else ShowMessage('3 '+IntToStr(ARow));
        end;
   end;

Получается что-то вроде. Куча begin end , большенство из них можно убрать. Верху форма сразу после форм креате, а внизу после изменения

-----
Прикрепленное изображение (кликните по картинке для увеличения):

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Ericsson

Посетитель

ID: 403884

5

= общий = |  23.11.2020, 17:34 |  цитировать |  профиль |  личное сообщение

Переделал под свою таблицу и условия, но почему теперь во всех ячейках могу вводить только один символ? smile Если удаляю этот код, то всё работает нормально. И как запретить в ячейках (там где стоимость путёвки и кол-во взрослых и детей) вводить любые символы кроме чисел?

Код (Pascal) :: выделить код
procedure TForm3.TableSetEditText(Sender: TObject; ACol, ARow: Integer;
  const Value: string);
var
a,b,c :integer;
begin
with Table do
  if(ARow>0)and(ARow<Table.RowCount)and (ACol>0)and(ACol<Table.ColCount)then
  if value <> ' ' then
  Table.Cells[ACol,ARow]:=Value;
  if tryStrToInt(Table.Cells[5,ARow],a)then
    begin
    if tryStrToInt(Table.Cells[6,ARow],b)then
      begin
        if tryStrToInt(Table.Cells[7,ARow],c)then
          begin
          Table.Cells[8,ARow]:=FloatToStr((a*b)+((b*c)-0.2));
          end;
      end;
    end;
end;

Последнее редактирование 23.11.2020, 17:44 Ericsson (Посетитель)

Зенченко Константин Николаевич

Старший модератор

ID: 31795

6

 +1 
 
= общий = |  23.11.2020, 17:47 |  цитировать |  профиль |  личное сообщение
Ericsson:

Цитата: Ericsson
но почему теперь во всех ячейках могу вводить только один символ?

Это из-за
Код (Pascal) :: выделить код
if Value<>''then

Уберите её


Цитата: Ericsson
И как запретить в ячейках (там где стоимость путёвки и кол-во взрослых и детей) вводить любые символы кроме чисел?


Обработчик такой
Код (Pascal) :: выделить код
procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
  const Digit=['0', '1'..'9'];
begin
  if (not (Key in Digit)) then Key:=#0;
end;

Условие нужно будет доработать, чтобы к примеру в колонках, к примеру ниже какого-то числа отключалось это условие

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Ericsson

Посетитель

ID: 403884

7

= общий = |  23.11.2020, 18:22 |  цитировать |  профиль |  личное сообщение

smile Хотел бы ещё спросить, почему даже при кол-ве детей = 0, в "сумме оплаты" всё равно считает с -20%?

Код (Pascal) :: выделить код
procedure TForm3.TableSetEditText(Sender: TObject; ACol, ARow: Integer;
  const Value: string);
var
a,b,c :integer;
begin
with Table do
  if(ARow>0)and(ARow<Table.RowCount)and (ACol>0)and(ACol<Table.ColCount)then
  if tryStrToInt(Table.Cells[5,ARow],a)then  // кол-во взрослых
    begin
    if tryStrToInt(Table.Cells[6,ARow],b)then  // кол-во детей
      begin
        if tryStrToInt(Table.Cells[7,ARow],c)then // стоимость
          begin
          Table.Cells[8,ARow]:=FloatToStr ((a*c)+((b*c) - 0.2));
          end;
      end;
    end;
  end;

-----
Прикрепленное изображение (кликните по картинке для увеличения):

Зенченко Константин Николаевич

Старший модератор

ID: 31795

8

= общий = |  23.11.2020, 21:30 |  цитировать |  профиль |  личное сообщение
Ericsson:

Цитата: Ericsson
почему даже при кол-ве детей = 0, в "сумме оплаты" всё равно считает с -20%

Вы так записали
Код (Pascal) :: выделить код
Table.Cells[8,ARow]:=FloatToStr ((a*c)+((b*c) - 0.2));

У меня считается
Код (Pascal) :: выделить код
Form1.StringGrid1.Cells[8,ARow]:=IntToStr(a*(b*c+d*e));

Кол-во дней*(кол-во взрослых*стоимость суток на человека+кол-во детей*сутки на ребенка)
практически е:=с*0,2 или е:=с*0,8, это как посмотреть
Если в TForm3.FormCreate или TForm3.OpenAsTClick или при любом изменении добавить refresh, т.е. подпрограмма, которая автоматически все поменяет, то будет Вам удача.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Зенченко Константин Николаевич

Старший модератор

ID: 31795

9

 +1 
 
= общий = |  24.11.2020, 16:00 |  цитировать |  профиль |  личное сообщение
Ericsson:

Получилось?

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Ericsson

Посетитель

ID: 403884

10

= общий = |  25.11.2020, 06:25 |  цитировать |  профиль |  личное сообщение

Да, всё получилось, спасибо вам

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