C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
проверка Edit
mirk
Отправлено: 06.07.2003, 02:44


Ученик-кочегар

Группа: Участник
Сообщений: 10



Есть прога, в ней при добавлении записей в базу должна проходить проверка на введенные символы в порядка 30 Edit`ов, в случае если какие нгибудь не заполненные, выпрыгивала новая форма с ListBox`ом с перечислением незаполненных полей, в случае если все нормально форма есно не появляется и данные нормально сохраняются.

не писать же так:

if (eFio->Text=="")
{
fWar->lbWar->Items->Add(fio);
fWar->ShowModal();
}
else ..........
if (eAmb->Text=="")
{
fWar->lbWar->Items->Add(amb);
fWar->ShowModal();
}
else ...........

Asher
Отправлено: 08.07.2003, 16:07


Мастер участка

Группа: Модератор
Сообщений: 550



Перечисление компонентов на форме
CODE

TEdit* edit;
for(int i = 0; i < ComponentCount; i++){//По всем компонентам формы
edit = dynamic_cast<TEdit*>(Components[i]);//Попытка приведения компонента
if(edit){//Если это TEdit (ну или потомок TEdit), то работаем
 if (edit->Text.IsEmpty()){//Если поле ввода пустое, то
   //Создаешь список пустых полей редактирования, edit->Name
 }//if (edit->Text.IsEmpty())
}//if(edit)
}//for(int i = 0; i < ComponentCount; i++)
//Если список не пустой, то показать форму с жалобой и списком


Отредактировано Asher — 08/07/2003, 18:11
iAlexander
Отправлено: 08.07.2003, 16:22


Дежурный стрелочник

Группа: Участник
Сообщений: 70



Круто.
Но можно и полегче — без динамической идентификации.
Просто функция

void Verify(TEdit *edit, TListBox *fWar)
if (edit->Text=="")
{
fWar->lbWar->Items->Add(edit->Text);
}
Asher
Отправлено: 08.07.2003, 17:35


Мастер участка

Группа: Модератор
Сообщений: 550



А чем легче?
для каждого Edit Verify в ручную вызвать?
и добавив или удалив Edit идти и переделывать п/п обработки?
Гость_mirk
Отправлено: 09.07.2003, 10:03


Не зарегистрирован







Asher

Это я и имел в виду.
Сенк большое, счас попробую.
mirk
Отправлено: 10.07.2003, 23:55


Ученик-кочегар

Группа: Участник
Сообщений: 10



Попробовал что то набодобие написат для радиобатонов:
И не хрена не пашет, ругается на память , типо не может быть "read", и одну пустую запись добавляет в таблицу.


TRadioButton *m_button[11];

m_button[1] = rbDnvc1;
m_button[2] = rbDnvc2;
m_button[3] = rbDnvc3;
m_button[4] = rbDnvc4;
m_button[5] = rbDnvc5;
m_button[6] = rbDnvc6;
m_button[7] = rbDnvc7;
m_button[8] = rbDnvc8;
m_button[9] = rbDnvc9;
m_button[10] = rbDnvc10;
m_button[11] = rbDnvc11;

for(int i = 0; i < m_button[i]->ComponentCount; i ++)
{
if(m_button[i]->Checked)
{
tE->FieldByName("Long")->AsString="i";
}
else
{
tE->FieldByName("Long")->AsString="0";
}
}
Admin
Отправлено: 11.07.2003, 00:16


Владимир

Группа: Администратор
Сообщений: 1190



QUOTE

TRadioButton *m_button[11];

m_button[1] = rbDnvc1;
m_button[2] = rbDnvc2;
m_button[3] = rbDnvc3;
m_button[4] = rbDnvc4;
m_button[5] = rbDnvc5;
m_button[6] = rbDnvc6;
m_button[7] = rbDnvc7;
m_button[8] = rbDnvc8;
m_button[9] = rbDnvc9;
m_button[10] = rbDnvc10;
m_button[11] = rbDnvc11;


А начинается массив с 1, а не с 0 ???

m_button[0] = rbDnvc1;
m_button[1] = rbDnvc2;
m_button[2] = rbDnvc3;
m_button[3] = rbDnvc4;
m_button[4] = rbDnvc5;
m_button[5] = rbDnvc6;
m_button[6] = rbDnvc7;
m_button[7] = rbDnvc8;
m_button[8] = rbDnvc9;
m_button[9] = rbDnvc10;
m_button[10] = rbDnvc11;
Гость_mirk
Отправлено: 11.07.2003, 07:40


Не зарегистрирован







Опечатка, я тут уже усе перепробовал, с 0 тоже самое
Asher
Отправлено: 11.07.2003, 09:05


Мастер участка

Группа: Модератор
Сообщений: 550



Я не понял, по каким элементам должен работать цикл
for(int i = 0; i < m_button[i]->ComponentCount; i ++)
Насколько я понимаю m_button[i]->ComponentCount это количество объектов, у которых m_button[i] является Owner, и как должен работать тАкой цикл я что-то не пойму wink.gif
если тебе надо по всему массиву, то делай i < 11, т.к при таком написании как у тебя входа в цикл не будет вообще, а если положить элементы не с нулевого элемента, то и ошибка памяти добавится.
Гость_mirk
Отправлено: 11.07.2003, 09:15


Не зарегистрирован







И так не хотит

for(int i = 0; i < 11; i ++)
{
if(m_button[i]->Checked == True)
{
tE->FieldByName("Long")->AsString="i";
}
}
Гость_mirk
Отправлено: 11.07.2003, 09:24


Не зарегистрирован







Выдает ошибку

Project brak.exe raised exception class EStringListError with message 'List index out of bounds (-1)'.
Asher
Отправлено: 11.07.2003, 09:37


Мастер участка

Группа: Модератор
Сообщений: 550



У меня тот фрагмент работает, а на какую строку ругается?
и где там StringList?
Admin
Отправлено: 11.07.2003, 09:44


Владимир

Группа: Администратор
Сообщений: 1190



Тогда приведите более полный код и ошибку,
где и что конкретно не работает.

Например, вот так все работает:

CODE

void __fastcall TForm1::Button1Click(TObject *Sender)
{

TLabel *m_label[5];
TRadioButton *m_button[5];

m_button[0] = rbDnvc1;
m_button[1] = rbDnvc2;
m_button[2] = rbDnvc3;
m_button[3] = rbDnvc4;
m_button[4] = rbDnvc5;

m_label[0] = Label1;
m_label[1] = Label2;
m_label[2] = Label3;
m_label[3] = Label4;
m_label[4] = Label5;

for(int i=0; i<5; i++){
m_label[i]->Caption = "- no checked — ";
if(m_button[i]->Checked == true) m_label[i]->Caption = "Ckeck !";
}

}
//----------------------------------------------------


И действительно, откуда взялся StringList ???
(EStringListError)


Отредактировано Admin — 11/07/2003, 10:51
Гость_mirk
Отправлено: 11.07.2003, 10:00


Не зарегистрирован







void __fastcall TForm1::Button1Click(TObject *Sender)
{

TRadioButton *m_button[5];

m_button[0] = rbDnvc1;
m_button[1] = rbDnvc2;
m_button[2] = rbDnvc3;
m_button[3] = rbDnvc4;
m_button[4] = rbDnvc5;

for(int i = 0; i < 11; i ++)
{
if(m_button[i]->Checked == True)tE->FieldByName("Long")->AsString="i";

}

}
//----------------------------------------------------
Admin
Отправлено: 11.07.2003, 10:09


Владимир

Группа: Администратор
Сообщений: 1190



QUOTE

for(int i = 0; i < 11; i ++)
{
if(m_button[i]->Checked == True)tE->FieldByName("Long")->AsString="i";

}



Опять опечатка ?
Цикл до 11, а TRadioButton *m_button[5]; всего 5 ???

-----

и потом  — если редактируете таблицу
(я так понимаю tE — это компонент типа Table)
то сначала надо Edit или Append


CODE

{
if(m_button[i]->Checked == true){
   tE->Append(); // добавить запись
   tE->FieldByName("Long")->AsString="i"; // может не "i" ,а IntToStr(i);
   tE->Post();
   }
}


И лучше имени поля такие имена (Long) не давать.

Гость_mirk
Отправлено: 11.07.2003, 10:23


Не зарегистрирован







Тоже не пашет

for (int i = 0; i < 11; i ++)
{
if(m_button[i]->Checked == true)
{
tE->FieldByName("Long_a")->AsString=IntToStr(i);
}
}

Насчет
QUOTE

и потом — если редактируете таблицу
(я так понимаю tE — это компонент типа Table)
то сначала надо Edit или Append


очепятка
sprinter
Отправлено: 11.07.2003, 10:47


Ученик-кочегар

Группа: Участник
Сообщений: 14



Mirk, а может сразу при вводе проверять данные?
Создать одну или несколько функций (в зависимости от критерия), например, для разрешения цифры и "забоя"
void __fastcall TForm1::EditKeyPress(TObject *Sender, char &Key)
{
if (!isdigit(Key) && Key!=VK_BACK)
Key=0;
}
и кроме того что можно ничего не введешь. Одну функцию присваиваешь нужным Edit'ам на событие OnKeyPress и вроде некриво получается...
Тоже можно и с другими компонентами проделывать, но нужно подобрать свойство.

И еще. Если желаете остаться при своем мнении, то помните (далее почти цитата)
> NEW аналогично malloc, но лучше пользовать именно NEW. Это пожелание
>становится необходимостью при динамическом размещении в памяти объектов
>библиотеки компонентов CBuilder.

Поэтому формулы типа
TRadioButton *m_button[11];//(1)
будет более надежно заменить
TRadioButton *m_button=new TRadioButton[11];//(2)

Покрайней мере код (2) гарантированно устойчиво работает, в то время как (1) капризничает. Частенько с этим встречался, особенно на Builder'е.
Admin
Отправлено: 11.07.2003, 11:47


Владимир

Группа: Администратор
Сообщений: 1190



Необходимо тогда четко определить,
где именно — в какой строчке возникает ошибка,
что-то у меня впечатление, что ошибка возникает
вообще не в этом коде.

----

Теперь что касается:

QUOTE

Поэтому формулы типа
TRadioButton *m_button[11];//(1)
будет более надежно заменить
TRadioButton *m_button=new TRadioButton[11];//(2)


Никакой надежности. wink.gif

Это вообще разные вещи.

В первом случае у нас массив из 11 указателей
на объект типа TRadioButton и мы честно можем
выполнить присваивание указатель — указатель.

Во втором случае — идея ясна — мы создаем 11 новых объектов -
и на хрена это надо  — создавать новые объекты, выделять
память под них и т.д. ???

(Да и вообще этот код
TRadioButton *m_button=new TRadioButton[11];//(2)
компилится не будет -
компилятор выдаст "Cannot find default constructor to initialize array ...")

Гость_mirk
Отправлено: 11.07.2003, 12:04


Не зарегистрирован







QUOTE
(Да и вообще этот код
TRadioButton *m_button=new TRadioButton[11];//(2)
компилится не будет -
компилятор выдаст "Cannot find default constructor to initialize array ...")


Угу, у меня то же самое.

Пробовал еше так:
int i = 0;
while (!m_button[i]->Checked)
{
i++;
}
tE->FieldByName("Long_a")->AsString=IntToStr(i);

Тоже самое

У моля пробовал менять тип с Number на Alpha, такая же фигня
Guest
Отправлено: 11.07.2003, 12:41


Не зарегистрирован







А я вот где то вычитал, сам не проверял.

TObjecе Obj;
for(int i=0; i Obj=Form.Components[i];
if (Obj is TEdit)
if(Obj->Text=="")
{MessageBox();
break;
}

Было в дельфях.
Anry
Отправлено: 14.07.2003, 13:05


Дежурный стрелочник

Группа: Участник
Сообщений: 56



Господа!!!
Данная проблема решается гораздо проще, без всяких циклов, массивов и выделений памяти.
У каждого компонента есть не используемое свойство Tag. Для всех RadioButton'ов ставится свое значение, отличное от нуля. У всех один обработчик события OnClick:
CODE

void __fastcall TOptionForm::File_RdBtnClick(TObject *Sender)
{
 TRadioButton *rd = (TRadioButton *)Sender;
 tE->FieldByName("Long_a")->AsString = IntToStr(rd->Tag);
}

Вернуться в Вопросы программирования в C++Builder