Re: Підкажіть що не правильно роблю, і як правильно зробити?
А чому від 0?
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → Pascal/Delphi → Підкажіть що не правильно роблю, і як правильно зробити?
Можливо скрінот допоможе правильно зрозуміти що я хочу зробити
Мені спочатку треба ввести дані, а потім нажати кнопку обчислити.
А чому від 0?
А я догнати не можу звідки береться порожній рядок зверху.
останнє питання де і що мені прописати щоб та Proba пішла при запуску програми без нажаття будь яких кнопок. Просто вибираю в комбо одне а в другому з'являється інше.
У форми є подія OnCreate, вона викликається коли форма створюється. Але якщо форма в програмі одна, то на старті програми.
procedure TForm1.Proba; const SPEED_UNITS: array[1..3] of string = ('Кілометрів за годину', 'Кілометрів за хвилину', 'Кілометрів за секунду'); var idx: integer; begin if ComboBox1.itemindex = 0 then ComboBox2.Items.Clear(); for idx:= 0 to high(SPEED_UNITS) do ComboBox2.Items.Add(SPEED_UNITS[idx]); end;
Куди ви знову поділи іще одну пару begin/end?
ProgramBandera написав:останнє питання де і що мені прописати щоб та Proba пішла при запуску програми без нажаття будь яких кнопок. Просто вибираю в комбо одне а в другому з'являється інше.
У форми є подія OnCreate, вона викликається коли форма створюється. Але якщо форма в програмі одна, то на старті програми.
ProgramBandera написав:procedure TForm1.Proba; const SPEED_UNITS: array[1..3] of string = ('Кілометрів за годину', 'Кілометрів за хвилину', 'Кілометрів за секунду'); var idx: integer; begin if ComboBox1.itemindex = 0 then ComboBox2.Items.Clear(); for idx:= 0 to high(SPEED_UNITS) do ComboBox2.Items.Add(SPEED_UNITS[idx]); end;
Куди ви знову поділи іще одну пару begin/end?
Дякую! Всі begin end; є в мене. Це я тут спішу і не дописую. Я вже ніч переспав і здогадався що це в подіях треба шукати. Правда я чомусь подумав що це треба рописати ось тут
procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
....
end;
Але в вашому випадку буде ще краще.
Вам явно зарано з формами працювати. Розберіться із тим, що таке типи та як працювати з масивами.
Пане koala підкажіть будь-ласка як можна іще оптимізувати цей код?
procedure TForm1.ComboBox1Change(Sender: TObject);
const UNITS_OF_TIME_1: array[1..3] of string =
('c. - Секунд','хв. - Хвилин','год. - Годин');
const UNITS_OF_MOVING_1: array[1..5] of string =
('мм. - Міліметрів','см. - Сантиметрів','дм. - Дециметрів','м. - Метрів',
'км. - Кілометрів');
const UNITS_OF_SPEED_1: array[1..15] of string =
('мм/с. - Міліметрів за секунду','см/с. - Сантиметрів за секунду',
'дм/с. - Дециметрів за секунду','м/с. - Метрів за секунду',
'км/с. - Кілометрів за секунду','мм/хв. - Міліметрів за хвилину',
'см/хв. - Сантиметрів за хвилину','дм/хв. - Дециметрів за хвилину',
'м/хв. - Метрів за хвилину','км/хв. - Кілометрів за хвилину',
'мм/год. - Міліметрів за годину','см/год. - Сантиметрів за годину',
'дм/год. - Дециметрів за годину','м/год. - Метрів за годину',
'км/год. - Кілометрів за годину');
var
idx:integer;
begin
if ComboBox1.ItemIndex =0 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
end;
if ComboBox1.ItemIndex =1 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
end;
if ComboBox1.ItemIndex =2 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
end;
if ComboBox1.ItemIndex =3 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
end;
if ComboBox1.ItemIndex =4 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
end;
if ComboBox1.ItemIndex =5 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
end;
if ComboBox1.ItemIndex =6 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
end;
if ComboBox1.ItemIndex =7 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
end;
if ComboBox1.ItemIndex =8 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
end;
if ComboBox1.ItemIndex =9 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
end;
if ComboBox1.ItemIndex =10 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
end;
if ComboBox1.ItemIndex =11 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
end;
if ComboBox1.ItemIndex =12 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
if ComboBox1.ItemIndex =13 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
if ComboBox1.ItemIndex =14 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
if ComboBox1.ItemIndex =15 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
if ComboBox1.ItemIndex =16 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
if ComboBox1.ItemIndex =17 then
begin
ComboBox5.Clear;
for idx:= 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
end;
Для початку:
- якщо користуєтеся high, то користуйтеся і low:
for idx:=low(UNITS_OF_TIME_1) to high(UNITS_OF_TIME_1) do
- всі гілки починаються з
ComboBox5.Clear;
якщо більше варіантів, крім перелічених, немає, то можна його винести перед усіма гілками, вже на 17 рядків менше.
Умови гілок взаємовиключні, тому бажано додавати else:
if умова then begin
тіло
end {крапка з комою не потрібна, бо далі else}
else if умова then begin
тіло
end
else if...
Далі, тіла гілок бувають лише трьох видів, із UNITS_OF_TIME_1, UNITS_OF_MOVING_1 (коректніше було б DISTANCE) та UNITS_OF_SPEED_1. Можна скористатися логічними операторами or та and:
if ComboBox1.ItemIndex=0 or ComboBox1.ItemIndex=1 or ComboBox1.ItemIndex=2 or ... then
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx])
else if ...
чи, оскільки значення параметрів у певних інтервалах, навіть так:
if 0<=ComboBox1.ItemIndex and ComboBox1.ItemIndex<=5 then
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx])
else if ...
Зверніть увагу, що в складних умовах краще використовувати лише оператори < та <= - тоді числа розташовуватимуться впорядковано, що зручно для сприйняття.
Але Pascal має ще один тип, зручний для запису подібних виразів - set.
if ComboBox1.ItemIndex in [0..5] then
for idx:= 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx])
else if ...
Але можна скористатися конструкцією case .. of, що й буде оптимальним рішенням тут:
ComboBox5.Clear;
case ComboBox1.ItemIndex of:
0..5: for idx:= low(UNITS_OF_TIME_1) to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]);
6..11: for idx:=low(UNITS_OF_MOVING_1) 1 to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]);
12..17: for idx:=low(UNITS_OF_SPEED_1) 1 to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
Перемога?
П.С. Якщо вам здається, що я навмисно пройшовся по всіх варіантах - то ви, на диво, помиляєтеся. Я писав це в тій послідовності, в якій згадував.
Для початку:
- якщо користуєтеся high, то користуйтеся і low:for idx:=low(UNITS_OF_TIME_1) to high(UNITS_OF_TIME_1) do
- всі гілки починаються з
ComboBox5.Clear;
якщо більше варіантів, крім перелічених, немає, то можна його винести перед усіма гілками, вже на 17 рядків менше.
Умови гілок взаємовиключні, тому бажано додавати else:if умова then begin тіло end {крапка з комою не потрібна, бо далі else} else if умова then begin тіло end else if...
Далі, тіла гілок бувають лише трьох видів, із UNITS_OF_TIME_1, UNITS_OF_MOVING_1 (коректніше було б DISTANCE) та UNITS_OF_SPEED_1. Можна скористатися логічними операторами or та and:
if ComboBox1.ItemIndex=0 or ComboBox1.ItemIndex=1 or ComboBox1.ItemIndex=2 or ... then for idx:= 1 to high(UNITS_OF_MOVING_1) do ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]) else if ...
чи, оскільки значення параметрів у певних інтервалах, навіть так:
if 0<=ComboBox1.ItemIndex and ComboBox1.ItemIndex<=5 then for idx:= 1 to high(UNITS_OF_MOVING_1) do ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]) else if ...
Зверніть увагу, що в складних умовах краще використовувати лише оператори < та <= - тоді числа розташовуватимуться впорядковано, що зручно для сприйняття.
Але Pascal має ще один тип, зручний для запису подібних виразів - set.if ComboBox1.ItemIndex in [0..5] then for idx:= 1 to high(UNITS_OF_MOVING_1) do ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]) else if ...
Але можна скористатися конструкцією case .. of, що й буде оптимальним рішенням тут:
ComboBox5.Clear; case ComboBox1.ItemIndex of: 0..5: for idx:= low(UNITS_OF_TIME_1) to high(UNITS_OF_TIME_1) do ComboBox5.Items.Add(UNITS_OF_TIME_1[idx]); 6..11: for idx:=low(UNITS_OF_MOVING_1) 1 to high(UNITS_OF_MOVING_1) do ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx]); 12..17: for idx:=low(UNITS_OF_SPEED_1) 1 to high(UNITS_OF_SPEED_1) do ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]); end;
Перемога?
П.С. Якщо вам здається, що я навмисно пройшовся по всіх варіантах - то ви, на диво, помиляєтеся. Я писав це в тій послідовності, в якій згадував.
Пане koala величезне вам дякую! за таку чудову відповідь. Ви для мене, як пан Морфіус з фільму матриця, відкриваєте такий світ, про який я навіть не здогадувався. Іще раз вам величезне дякую!
величезне вам дякую!
Пора прикручувати робота, який відповідатиме на дописи з таким текстом
А взагалі я підозрюю, що користувачам зручніше було б вводити "5 км" замість 5 в одне поле і вибирати "км" з іншого.
А взагалі я підозрюю, що користувачам зручніше було б вводити "5 км" замість 5 в одне поле і вибирати "км" з іншого.
у нас зараз на проєкті зроблено так само, одне поле - числове значення, а друге - селект з юнітами
по-перше: таким чином юзер не може зробити одрук
по-друге: юзер відразу бачитиме, які юніти доступні, і не буде проблем з використанням непідтримуваних юнітів і здогадками юзера - а які значення взагалі можливі в цьому додатку???
та ще й це просто швидше, от є юніт tablespoon - столова ложка. І юзеру треба список значень таких зробити - то що легше, вручну кожного разу писати те слово, чи просто обрати з селекту? Звісно, можна копіювати, але звичайний необізнаний юзер до того може й не додуматись
Можна навіть сумістити: обираєте "tablespoon" - в полі замінюється "spoon" на "tablespoon", а кому легше набирати - хай набирає.
а можна ще підключити голосовий набір, і юзер такий каже - тейблспун, і воно автоматично додає цей текст в поле
або показати формочку з картинками
і якщо юзер клікне на столову ложку, то вписати tablespoon в поле
А взагалі я підозрюю, що користувачам зручніше було б вводити "5 км" замість 5 в одне поле і вибирати "км" з іншого.
Діти так вводити можуть, а ось дорослі починають лаятися, "А ЧОМУ ЦЕ ВОНО НЕПРАВИЛЬНО РАХУЄ? ЯКИЙ Д....Л СКЛАДАВ ПРОГРАМУ!".
Та питання не в цьму. Пане koala ви давали мені декілька прикладів по масивах. Я оболонку вже майже закінчив і підійшов до процедури обчислення і в мене виникла ось така помилка.
procedure TForm1.ComboBox1Change(Sender: TObject);
const UNITS_OF_TIME_1: array[1..3] of string =
('c. - Секунд','хв. - Хвилин','год. - Годин');
const UNITS_OF_MOVING_1: array[1..5] of string =
('мм. - Міліметрів','см. - Сантиметрів','дм. - Дециметрів','м. - Метрів',
'км. - Кілометрів');
const UNITS_OF_SPEED_1: array[1..15] of string =
('мм/с. - Міліметрів за секунду','см/с. - Сантиметрів за секунду',
'дм/с. - Дециметрів за секунду','м/с. - Метрів за секунду',
'км/с. - Кілометрів за секунду','мм/хв. - Міліметрів за хвилину',
'см/хв. - Сантиметрів за хвилину','дм/хв. - Дециметрів за хвилину',
'м/хв. - Метрів за хвилину','км/хв. - Кілометрів за хвилину',
'мм/год. - Міліметрів за годину','см/год. - Сантиметрів за годину',
'дм/год. - Дециметрів за годину','м/год. - Метрів за годину',
'км/год. - Кілометрів за годину');
var
idx:integer;
begin
if 0<=ComboBox1.ItemIndex and ComboBox1.ItemIndex<=5 then
for idx:= low(UNITS_OF_TIME_1) to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx])
else
if 6>=ComboBox1.ItemIndex and ComboBox1.ItemIndex<=11 then
for idx:= low(UNITS_OF_MOVING_1) to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx])
else
if 12>=ComboBox1.ItemIndex and ComboBox1.ItemIndex<=17 then
for idx:= low(UNITS_OF_SPEED_1) to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
{[Error] Unit1.pas(157): Incompatible types}
{Несумісні типи}
І в другому варіанті теж несумісні типи
procedure TForm1.ComboBox1Change(Sender: TObject);
const UNITS_OF_TIME_1: array[1..3] of string =
('c. - Секунд','хв. - Хвилин','год. - Годин');
const UNITS_OF_MOVING_1: array[1..5] of string =
('мм. - Міліметрів','см. - Сантиметрів','дм. - Дециметрів','м. - Метрів',
'км. - Кілометрів');
const UNITS_OF_SPEED_1: array[1..15] of string =
('мм/с. - Міліметрів за секунду','см/с. - Сантиметрів за секунду',
'дм/с. - Дециметрів за секунду','м/с. - Метрів за секунду',
'км/с. - Кілометрів за секунду','мм/хв. - Міліметрів за хвилину',
'см/хв. - Сантиметрів за хвилину','дм/хв. - Дециметрів за хвилину',
'м/хв. - Метрів за хвилину','км/хв. - Кілометрів за хвилину',
'мм/год. - Міліметрів за годину','см/год. - Сантиметрів за годину',
'дм/год. - Дециметрів за годину','м/год. - Метрів за годину',
'км/год. - Кілометрів за годину');
var
idx:integer;
begin
if ComboBox1.ItemIndex=0 or ComboBox1.ItemIndex=1 or ComboBox1.ItemIndex=2 or
ComboBox1.ItemIndex=3 or ComboBox1.ItemIndex=4 or ComboBox1.ItemIndex=5 then
for idx:= low(UNITS_OF_TIME_1) to high(UNITS_OF_TIME_1) do
ComboBox5.Items.Add(UNITS_OF_TIME_1[idx])
else
if ComboBox1.ItemIndex=6 or ComboBox1.ItemIndex=7 or ComboBox1.ItemIndex=8 or
ComboBox1.ItemIndex=9 or ComboBox1.ItemIndex=10 or ComboBox1.ItemIndex=11 then
for idx:= low(UNITS_OF_TIME_1) to high(UNITS_OF_MOVING_1) do
ComboBox5.Items.Add(UNITS_OF_MOVING_1[idx])
else
if ComboBox1.ItemIndex=12 or ComboBox1.ItemIndex=13 or ComboBox1.ItemIndex=14 or
ComboBox1.ItemIndex=15 or ComboBox1.ItemIndex=16 or ComboBox1.ItemIndex=17 then
for idx:= low(UNITS_OF_TIME_1) to high(UNITS_OF_SPEED_1) do
ComboBox5.Items.Add(UNITS_OF_SPEED_1[idx]);
end;
Так як ці варіанти мені найкраще підходять для повного перебору усіх ItemIndex, з десяти ComboBox!!! Ці типи якось можна поєднати?
ProgramBandera
По-перше, треба вказати пріоритет операцій, як в математиці:
if (0<=ComboBox1.ItemIndex) and (ComboBox1.ItemIndex<=5) then
koala мабуть не протестував свій код, і тому не зробив цього.
По-друге, вам слід іще раз уважно перечитати його повідомлення, бо ви пропустили один з перших пунктів.
По-третє, у вас не усе в порядку зі знаками більше/менше.
Так, забув цю особливість Паскалю - логічні оператори мають вищий пріоритет за порівняння, тому
3<=4 and 4<=5
розглядається як
3<=(4 and 4)<=5
і призводить до помилки. Правильно писати
(3<=4) and (4<=5)
Навіть не знаю, чому Вірту спало на думку саме так зробити - ну, хіба що спонукати розставляти дужки (це в будь-якому разі корисно в складних виразах).
Добрий день панство! Як правильно заповнити двовимірний масив типу strng? Спробував ось так
const TIME: array [1..6,1..9] of string =
(('t1 - Час','t2 - Час','t3 - Час','t4 - Час','t5 - Час','t6 - Час'),
('c. - Секунд','хв. - Хвилин','год. - Годин','t1 - Час','t2 - Час','t3 - Час',
't4 - Час','t5 - Час','t6 - Час'));
і видало помилку {Кількість елементів відрізняється від декларації}.
Яке саме зі слів "Кількість елементів відрізняється від декларації" ви не розумієте?
Яке саме зі слів "Кількість елементів відрізняється від декларації" ви не розумієте?
Я не розумію чому воно відрізняється! Там 6 там 9.
І пане koala це не відповідь. Питання було як правильно заповнити, вкажіть на помилку.
У вас двовимірний масив 6 на 9 елементів типу string, усього має бути 6*9=54. Я бачу лише 15. 54!=15. А як правильно заповнити - це вам видніше, це ваш масив. Треба привести у відповідність кількість елементів і декларацію. Я підозрюю, що відповідь
const TIME: array [1..1,1..1] of string =(('t1 - Час'));
вас не задовільнить, хоча вона абсолютно точно відповідає на ваше питання.