Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > StringGrid


Автор: Гость_Инна 17.11.2005, 14:19
Подскажите как правильно удалить строку с известным номером из StringGrid?
Спасибо.

Автор: _hunter 17.11.2005, 14:41
поднимаем все строки под этой на одну вверх и уменьшаем RowCount на 1

Автор: Гость_Инна 17.11.2005, 15:51
Пытаюсь убрать все строки у который во второй колонке пусто. Как правильно поднимать строки?
int u = Form1->StringGrid1->RowCount;
for (int i = 0; i<u ; i++)
{
if(Form1->StringGrid1->Cells[1][i] == "")
//поднять как?

Form1->StringGrid1->RowCount = Form1->StringGrid1->RowCount-1;
}

Автор: _hunter 17.11.2005, 15:59
поднять -- это перенести значения всех ячеек строки

Автор: Гость_Инна 17.11.2005, 16:24
int yborka = Form1->StringGrid1->RowCount;
for (int i = 0; i<yborka ; i++)
{
if(Form1->StringGrid1->Cells[1][i] == "")
{
for (int i = 0; i<yborka ; i++)
{
Form1->StringGrid1->Cells[0][i]=Form1->StringGrid1->Cells[0][i+1];
Form1->StringGrid1->Cells[1][i]=Form1->StringGrid1->Cells[1][i+1];
}
Form1->StringGrid1->RowCount = Form1->StringGrid1->RowCount-1;
}
}
Не работает. Где ошибка?

Автор: _hunter 17.11.2005, 16:34
на вопрос
Цитата
Где ошибка?

я могу ответить только "там".

что значит "Не работает"?
Добавлено @ 16:36
P.S.
не стесняемся на кнопку "Код" тыкать...

P.P.S.
два цикла с одной переменной -- не есть гут...

Автор: Гость_Инна 17.11.2005, 16:43
СтрингГрид состоит из двух колонок. Во второй колонке есть пустые ячейки. Строки в которых присутствуют пустые значения во второй колонке надо убрать из СтрингГрид. Код выше с этим не справляется. Остаются пустые строки во второй колонке.
Еще подскажите: при старте приложения всегда выделена первая ячейка в первой колонке СтрингГрида, как сделать, чтобы этого выделения не было. И как менять размеры колонок, установила goColSizing в true, но поменять размер колонок не удается курсором мыши.
У меня СтрингГрид без фиксированных колонок и строк.
Спасибо.

Автор: Vyacheslav 17.11.2005, 16:44
Надо нежнее, еще нежнее
Код


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


class TPublicGrid: public  TStringGrid
{
    public:
        using TStringGrid::DeleteRow;
};
((TPublicGrid*)StringGrid1)->DeleteRow(1);


}



Добавлено @ 16:51
Код


class TPublicGrid: public  TStringGrid
{
    public:
        using TStringGrid::DeleteRow;
};
for (int i = StringGrid1->RowCount ; i--;)
{
      if(Form1->StringGrid1->Cells[1][i] == "")
        ((TPublicGrid*)StringGrid1)->DeleteRow(i);
}



Автор: Гость_Инна 17.11.2005, 18:06
Спасибо, работает smile
Теоретически это как реализовано? Идет переопределение защищенной переменной из класса TStringGrid? За что отвечает эта переменная в базовом классе TStringGrid? Почему классический TStringGrid не дает так просто удалять?
Еще вопросы:
Подскажите, как программно установить ширину двух колонок в StringGrid в зависимости от самого длинного текста в каждой из них и как снять выделение с первой ячейки StringGrid в момент его появления на форме?
Спасибо.


Автор: _hunter 17.11.2005, 18:23
это называется взлом класса ( и нет там никакой переменой )
а почему удалять не дает -- у разработчиков спрашивать надобно...
ширину установить -- ColWidths
длину текста определить -- stringGrid->Canvas->TextWidth()
выделение убрать -- Col в -1 поставить попробуй ( ну или HideSelection в Design Time' е в true а потом вернуть в false )

Автор: Vyacheslav 17.11.2005, 18:35
Здесь прсото создается некий прокси-класс, у которого всего лишь чисто декоративное отличие:
метод DeleteRow, объявленный как protected, объявляется в новом классе открытым.
Код

class TPublicGrid: public  TStringGrid
{
    public:
        using TStringGrid::DeleteRow;
};


Я бы не назвал, это взломом. Вполне стандартный прием.
Просто разработчики решили, что этот не стоит этот метод делать открытым для данного класса. А Вам он понадобился smile

Автор: Гость_Инна 17.11.2005, 19:00
Cпасибо за обяснения.

Кто знает, подскажите где ошибка. Пробую установить ширину двух своих колонок в СтрингГрид:
Код

int with_string1;
int with_string2;
int stolb = 1;
with_string1 = Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[0][stolb]);
for (int i = Form1->StringGrid1->RowCount; i--;)
{
  if (Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[0][stolb])<
       Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[0][stolb+1]))
     {
       with_string1 = Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[0][stolb+1]);

     }
  stolb++;

}

int stolb2 = 1;
with_string2 = Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[1][stolb2]);
for (int i = Form1->StringGrid1->RowCount; i--;)
{
  if (Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[1][stolb2])<
       Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[1][stolb2+1]))
     {
       with_string2 = Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[1][stolb2+1]);

     }
  stolb2++;

}

Form1->StringGrid1->ColWidths[0] = with_string1;
Form1->StringGrid1->ColWidths[1] = with_string2;
Form1->StringGrid1->SetFocus();//убрать выделение


Как-то странно работает smile В смысле неправильно smile

Автор: _hunter 17.11.2005, 19:33
странный код...
зачем постоянно вычислять длины ( if (Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[1][stolb2])<
Form1->StringGrid1->Canvas->TextWidth(Form1->StringGrid1->Cells[1][stolb2+1])) )?
создай перед циклом переменную int maxWidth = 0;
и проверяй больше ли длина столбца этой переменной. если больше -- обновляй значение.
после цикла ставь длину в maxWidth и все...
+ ты, похоже путаеш столбцы и строки ( Cells[int ACol][int ARow] )

Автор: docwar 27.9.2006, 17:07
Здравствуйте!
1) Как в StringGrid удалить выделенную строку? Причем не просто очистить ее ячейки, а удалить полностью.
2) Как сделать выделенную строку доступной для редактирования? Т.е. выбераем строку, жмем на клавишу и можем изменять текст в любой ячейки строки прямо в таблице!
Модератор: зачем подымать старый топик. Я дал ссылку на него, что бы Вы смогли решить проблему с ошибкой. Ответы на это  топик и тот, который Вы  открыли полностью дают ответ на Ваши вопросы http://forum.vingrad.ru/index.php?showtopic=113677

Автор: docwar 29.9.2006, 17:22
Извините, но я не могу выделить строку. Это вообще возможно?

Автор: Romikgy 29.9.2006, 22:46
Код

    TGridRect myRect;
  myRect.Left = 0;
  myRect.Top = 1;
  myRect.Right = StringGrid1->ColCount-1;
  myRect.Bottom = 1;

StringGrid1->Selection=myRect;

Автор: docwar 30.9.2006, 08:59
Спасибо большое, но я не пойму... куда вставить этот код, а то куда бы не вставлял - эффекта нет...

Автор: Romikgy 30.9.2006, 11:31
туда где выделяешь строку

Автор: docwar 30.9.2006, 17:49
В обрабочик кнопки? Не выделяет он строки...  smile 

Автор: Romikgy 30.9.2006, 20:20
в конце обработчика передай фокус стринггриду!

Автор: docwar 30.9.2006, 21:36
В конец кнопки удалить уже пробовал добавлять.... результатов ноль...

Добавлено @ 21:44 
Мне кажется, что всему виной центрирование хидеров и проблемы с прорисовкой....
Посмотри, пожалуйста, код формы с первой страницы.  smile 

Автор: Romikgy 30.9.2006, 23:22
Цитата(docwar @  30.9.2006,  20:36 Найти цитируемый пост)
В конец кнопки удалить уже пробовал добавлять.... результатов ноль...

Добавлено @ 20:44 
Мне кажется, что всему виной центрирование хидеров и проблемы с прорисовкой....
Посмотри, пожалуйста, код формы с первой страницы.  

К чему это все?
Цитата(Romikgy @  29.9.2006,  21:46 Найти цитируемый пост)
StringGrid1->Selection=myRect;

после этого добавь StringGrid1->SetFocus();

Автор: docwar 30.9.2006, 23:42
Очищаются все строки + хидеры.... smile

Автор: docwar 8.10.2006, 20:25
Пересобрал весь проект. Помогите, пожалуйста, разобраться в удалением и редактированием выделенной строки!
Предложенные варианты удаления строки либо удаляют все строки, либо ничего вообще не делают! smile

Автор: Romikgy 8.10.2006, 22:20
У тя билдер какой?

Автор: docwar 9.10.2006, 13:59
Шестой.

Автор: Aline 9.10.2006, 15:30
docwar, 

Посмотри свойство Options, там есть goRowSelect, поставь в true, чтобы выделить целую строку.

Объявляешь класс как советовал Vyacheslav :

class TPublicGrid: public  TStringGrid
{
    public:
        using TStringGrid::DeleteRow;
};



а потом в обработчик кнопки, например, ставишь:

  ((TPublicGrid*)StringGrid1)->DeleteRow(sRow);


Значение sRow - индекс выбранной строки, можно получить в событии OnSelectCell. Кстати, совсем необязательно выделять целую строку, дастаточно встать в одну из ячеек этой строки.

Для редактирования, опять же используй Options, goEditing

void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol,
      int ARow, bool &CanSelect)
{
  sCol = ACol;
  sRow = ARow;
}

Добавлено @ 15:41 
docwar, 
Да, ещё, можно программно выделить строку.

Для этого устанавливаешь StringGrid->Row номер строки, которую нужно выделить и в Options должно быть установлено goRowSelect и goDrawFocusSelected

У меня по крайней мере выделяет нужную строку...

Автор: Romikgy 9.10.2006, 16:12
Код

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  StringGrid1->Options<<goRowSelect;
}

void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
//delete row
int rrow,i;
if (StringGrid1->RowCount==1) return;
TStringList * sl=new TStringList();

rrow=StringGrid1->Row;
for (i=0;i< StringGrid1->ColCount;i++)
{
 sl->Assign(StringGrid1->Cols[i]);
 sl->Delete(rrow);
 StringGrid1->Cols[i]->Assign(sl);
}
sl->Free();
StringGrid1->RowCount--;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
 //add row
 int rrow,i;
 StringGrid1->RowCount++;
if (StringGrid1->RowCount==1) return;
TStringList * sl=new TStringList();

rrow=StringGrid1->Row;
for (i=0;i< StringGrid1->ColCount;i++)
{
 sl->Assign(StringGrid1->Cols[i]);
 sl->Insert(rrow,"Add");
 StringGrid1->Cols[i]->Assign(sl);
}
sl->Free();

}

Автор: Vyacheslav 9.10.2006, 16:41
Romikgy, 
Ну зачем выдавать такой навороченный код 
Давали же уже.

Код

//удаление выделенной строки
void __fastcall TForm1::Button2Click(TObject *Sender)
{

class TPublicGrid: public  TStringGrid
{
    public:
        using TStringGrid::DeleteRow;
};
((TPublicGrid*)StringGrid1)->DeleteRow(StringGrid->Row);


}



Что тут непонятного ?

Вот этот код работать не будет 
Код

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  StringGrid1->Options<<goRowSelect;
}



Надо делать вот так 

Код

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  StringGrid1->Options = StringGrid1->Options << goRowSelect;

И зачем использовать FormCreatе? Вместо него  используем конструктор.
Цитата

Note:    Use of the OnCreate event is discouraged in C++Builder because it can interact badly with the form’s constructor (see OldCreateOrder). It is recommended that you override the form constructor instead.


Цитата

Note:    Use of the OnCreate event is discouraged in C++Builder because it can interact badly with the form’s constructor (see OldCreateOrder). It is recommended that you override the form constructor instead.


И еще.
Вот это выглядит довольно забавно 
Код

sl->Free();

Может все таки стоит хоть немного внимать рекомендациям Borland
Цитата

Do not call the Free method of an object. Instead, use the delete keyword, which invokes Free to destroy an object. Free automatically calls the destructor if the object reference is not NULL.

"Не вызывайте метод Free. Вместо него используйте delete



  




Автор: docwar 9.10.2006, 18:21
Спасибо Вам огромное за ответы!!!

Только у меня опять вопросы! smile
Удаляю как советует Vyacheslav, добавление данных у меня оформлено так:
Код
if(!Edit1->Text.IsEmpty() && !Edit2->Text.IsEmpty()){
Form1->StringGrid1->Cells[0][Form1->StringGrid1->RowCount-1] = Edit1->Text;
Form1->StringGrid1->Cells[1][Form1->StringGrid1->RowCount-1] = Edit2->Text;
...
Form1->StringGrid1->Cells[1][Form1->StringGrid1->RowCount-1] = Edit6->Text;
Edit1->Clear();
Edit2->Clear();
...
Edit6->Clear();
Form1->StringGrid1->RowCount++;
}

Потом делаю следующее:
1) Добавляю данные
2) Удаляю эту строку
3) Добавляю новую
и в результате в таблицу выводится вторая строка, потом первая...  smile 

Автор: Romikgy 9.10.2006, 21:02
Цитата(Vyacheslav @  9.10.2006,  15:41 Найти цитируемый пост)
Ну зачем выдавать такой навороченный код 


Vyacheslav, ты дал один способ решения проблемы , я дал другой, автор выбрал который ему больше понравился

А зачем... имхо да потому что это форум, или я кого то повторил?

Добавлено @ 21:04 
Цитата(Vyacheslav @  9.10.2006,  15:41 Найти цитируемый пост)
Вот это выглядит довольно забавно 
Выделить всёкод C++ Builder
1:
    
sl->Free();

Может все таки стоит хоть немного внимать рекомендациям Borland
Цитата

Do not call the Free method of an object. Instead, use the delete keyword, which invokes Free to destroy an object. Free automatically calls the destructor if the object reference is not NULL.

"Не вызывайте метод Free. Вместо него используйте delete

здесь согласен , по инерции из дельфей

Добавлено @ 21:07 
Цитата(docwar @  9.10.2006,  17:21 Найти цитируемый пост)
Потом делаю следующее:
1) Добавляю данные
2) Удаляю эту строку
3) Добавляю новую
и в результате в таблицу выводится вторая строка, потом первая..

я из этого мало что понял , но имхо можно поменять местами, или подкорректировать ввод

Автор: docwar 9.10.2006, 21:18
Цитата(Romikgy @  9.10.2006,  21:02 Найти цитируемый пост)
я из этого мало что понял

Сначала добавил данные в таблицу, потом удалил только что созданную строку, потом опять пользуюсь формой ввода. И в таблице отображаются ДВЕ строки: вторая - первая (сверху вниз!)

Цитата(Romikgy @  9.10.2006,  21:02 Найти цитируемый пост)
можно поменять местами, или подкорректировать ввод

А не подскажите как?  smile 

Автор: Romikgy 9.10.2006, 22:03
Цитата(docwar @  9.10.2006,  20:18 Найти цитируемый пост)
Сначала добавил данные в таблицу, потом удалил только что созданную строку, потом опять пользуюсь формой ввода. И в таблице отображаются ДВЕ строки: вторая - первая (сверху вниз!)

код бы привел
Цитата(docwar @  9.10.2006,  20:18 Найти цитируемый пост)
А не подскажите как?

подразумеваю надо после удаления позицию Row корректировать 

Автор: docwar 9.10.2006, 22:06
Код
if(!Edit1->Text.IsEmpty() && !Edit2->Text.IsEmpty())
{
Form1->StringGrid1->Cells[0][Form1->StringGrid1->RowCount-1] = Edit1->Text;
Form1->StringGrid1->Cells[1][Form1->StringGrid1->RowCount-1] = Edit2->Text;
...
Form1->StringGrid1->Cells[1][Form1->StringGrid1->RowCount-1] = Edit6->Text;
Edit1->Clear();
Edit2->Clear();
...
Edit6->Clear();
Form1->StringGrid1->RowCount++;
}


Это добавление! smile А есть еще и центрирование заголовков таблицы:
Код
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
TStringGrid *pSG = (TStringGrid *)Sender;
AnsiString nameCol = pSG->Cells[ACol][ARow];
int Align;
if(!ARow)
{
Align = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
pSG->Canvas->Brush->Color = clBtnFace;
}
else
{
Align = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
pSG->Canvas->Brush->Color = clWhite;
}
pSG->Canvas->FillRect(Rect);
TRect r = Rect;
DrawText(pSG->Canvas->Handle,nameCol.c_str(),nameCol.Length(),&r,Align);
}

Автор: Romikgy 9.10.2006, 23:02
1 ты уверен что

Цитата(docwar @  9.10.2006,  21:06 Найти цитируемый пост)
Form1->StringGrid1->Cells[0][Form1->StringGrid1->RowCount-1] = Edit1->Text;

а не Form1->StringGrid1->RowCount?
2 как удаялешь

PS елы палы что по пункно надо вытягивать?
написал
Цитата(docwar @  9.10.2006,  17:21 Найти цитируемый пост)
1) Добавляю данные
2) Удаляю эту строку
3) Добавляю новую
и в результате в таблицу выводится вторая строка, потом первая..

покажи это все
Цитата(docwar @  9.10.2006,  21:06 Найти цитируемый пост)
А есть еще и центрирование заголовков таблицы:

и это имхо .... не надо

Автор: Aline 10.10.2006, 07:59
docwar, 
у меня тоже так было
Умного решения не нашла :-), просто очищала ячейки в добавленной  строке:

 StringGrid1->Cells[0][StringGrid1->RowCount-1]="";
 StringGrid1->Cells[1][StringGrid1->RowCount-1]="";

Автор: docwar 10.10.2006, 17:45
Цитата
покажи это все

Я делаю это все после запуска программы! Скриншоты показать?  smile 

Автор: Romikgy 10.10.2006, 22:05
Цитата(docwar @  10.10.2006,  16:45 Найти цитируемый пост)
Скриншоты показать? 

на кой они!? исходник покажи как ты это делаешь 
(последний раз прошу, далее просто не появлюсь в этой теме)

Автор: docwar 11.10.2006, 15:48
Romikgy, извини, пожалуйста, что не понял тебя с первого раза!
После твоего ответа стал внимательно вчитываться в код и заметил, что я невнимателен! smile

Осталось только написать код для редактирования выделенной строки!  smile 

Автор: docwar 15.10.2006, 12:46
И снова здравствуйте!
Помогите, пожалуйста, написать код для редактирования строки! smile 
Спасибо!  

Автор: Aline 16.10.2006, 12:21
docwar, 
Что значит "написать код для редактирования строки"? Ты толком можешь объяснить, что тебе надо? Что тебе со строкой делать надо?

Автор: FFFFFFF7 16.10.2006, 12:50
Цитата(Aline @  16.10.2006,  12:21 Найти цитируемый пост)
Ты толком можешь объяснить, что тебе надо?

действительно.
docwar, ты когда научишься пользоваться мануалом?
Заметка: редактировать строку невозможно. Заруби это =)))!
Можно - ячейку.

Автор: docwar 16.10.2006, 14:54
Тогда помогите, пожалуйста, с кодом редактирования выделенной ячейки!
Делать всю таблицу доступной для редактирования мне не надо! =)
Спасибо!

Автор: docwar 18.10.2006, 11:18
Надеюсь, что кто-нибудь мне поможет!  smile 

Автор: Aline 18.10.2006, 15:42
docwar, 

Слушай, посмотри текст на предыдущей странице, по-моему я тебе уже писала, что надо использовать свойство Options и событие OnSelectCell

По этому событию можно получить индексы выделенной ячейки, а с помощью Options настроить её свойства

Например:

void __fastcall TMainForm::StringGridClick(TObject *Sender)
{
  if (sCol == 1) StringGrid->Options = StringGrid->Options << goEditing;  //разрешаем редактирование во второй колонке
  else StringGrid->Options = StringGrid->Options >> goEditing;  //запрещаем редактирование
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::StringGridSelectCell(TObject *Sender, int ACol,
      int ARow, bool &CanSelect)
{
  sCol = ACol;
  sRow = ARow;
} 



Автор: docwar 18.10.2006, 17:14
Aline, извини! Просто только сейчас вернулся к редактированию ячеек и забыл о твоем сообщении...  smile 
Не пойму... компилятор ругается, что символы sCol и sRow не определены...  smile 

Автор: Aline 19.10.2006, 08:40
docwar, 
ну так правильно, их объявить надо как int
в OnSelectCell объявлены ACol и ARow, а если тебе индексы ячеек нужны в другом месте, то другим переменным присваиваешь эти значения и потом работаешь с этой ячейкой как хочешь 

Автор: docwar 20.10.2006, 22:57
Aline, ну не получается у меня... :'(
Все время ругается, что-либо неопределен элемент, либо что значение не используется...
Смысл такой, чтобы при нажатии на клавишу редактирование становилось возможным.
Пишу так: (уже кучу вариантов перебрал, определял уже и через AnsiString...)
Код
void __fastcall TForm1::StringGrid1Click(TObject *Sender)
{
int sCol, sRow;
if (sCol == 1) StringGrid1->Options = StringGrid1->Options << goEditing;  
else StringGrid1->Options = StringGrid1->Options >> goEditing; 
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol,
      int ARow, bool &CanSelect)
{
int sCol, sRow;
  sCol = ACol;
  sRow = ARow;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::N10Click(TObject *Sender)
{
int a=ACol;
int b=ARow;
}

Автор: bsa 21.10.2006, 12:04
docwar, ты, надеюсь, сам понимаешь, что чушь написал? Три метода, два из которых вообще ничего не делают, а первый делает неизвестно что (от случая к случаю).
Может сначала стоит C++ выучить?
А теперь по порядку.
В первом методе ты объявляешь sCol и sRow, но не присваиваешь им ничего. Поэтому операция if (sCol == 1) ... будет иногда срабатывать, но чаще будет работать то, что после else. Так как в sCol в идеале случайное значение.
Во втором методе ты просто выполняешь лишние операции, который будут потеряны, после выхода из данного метода.
А третий метод вообще не скомпилируется (если, конечно, в классе нет аттрибутов ACol и ARow, а их скорей всего нет), но даже если и скомпилируется, то будет тоже самое, что и во втором методе.

Тебе надо объявить int sCol, sRow; В ОПРЕДЕЛЕНИИ КЛАССА (в .h файле). А все локальные определения убрать.

Автор: docwar 21.10.2006, 14:40
Цитата
надеюсь, сам понимаешь, что чушь написал?

Естественно понимаю! =) Ничего не получалось(забыл, что обьявлять надо в .h) + был после стоматолога... вот и написал такой код...
Спасибо! Ошибок нет, но действий никаких не выполняется. ?

Автор: Aline 23.10.2006, 15:27

Код


int sCol, sRow;

 void __fastcall TForm1::StringGrid1Click(TObject *Sender)
//когда ты щелкнешь на ячейку, то сразу разрешишь или запретишь редактирование этой ячейки
{
    if (sCol == 1) StringGrid1->Options = StringGrid1->Options << goEditing;  
    else StringGrid1->Options = StringGrid1->Options >> goEditing; 
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol,
      int ARow, bool &CanSelect)
{
  sCol = ACol;
  sRow = ARow;
}
//---------------------------------------------------------------------------

//если тебе надо обработывать это по кнопке, то перенеси текст из StringGrid1Click в обработчик клика кнопки или выбора команды 
//меню:

void __fastcall TForm1::N10Click(TObject *Sender)
{
    if (sCol == 1) StringGrid1->Options = StringGrid1->Options << goEditing;  
    else StringGrid1->Options = StringGrid1->Options >> goEditing; 
} 

docwar, 
Всё должно работать, проверь ещё раз. В крайнем случае поставь точку останова и посмотри в отладчике что происходит. А вообще, что ты хотел увидеть? По  тому условию что ты поставил, у тебя будет разрешено редактирование во второй колонке, т.е. там будет курсор появляться.

Автор: docwar 23.10.2006, 17:19
Aline, спасибо! Проверю код как только получу доступ к своему компьютеру (завтра вечером примерно).
Цитата
А вообще, что ты хотел увидеть?

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

Автор: docwar 8.11.2006, 19:28
Вопрос еще не решен! 
Прошу вашей помощи!!!

Автор: Reptile 9.11.2006, 11:32
Цитата(docwar @  23.10.2006,  17:19 Найти цитируемый пост)
Хотел, чтобы прямо в таблице можно было вносить изменения или с помощью вызова доп. формы. Ввел данные в редактируемую строку - данные в ней заменились. 

Ну так создай еще одну форму, набросай Edit-ы и при нажатии на кнопку редактирования показываеш форму с Edit-ми, а в них заполняеш значения из StringGrid, нажимаеш ОК и все данные из Edit-ов переносиш в StringGrid и закрываеш доп. форму. И все smile 

Автор: dumb 9.11.2006, 11:52
docwar,
в дизайнере форм тыкни ЛКМ(левая кнопка мыши) на свой StringGrid. нажми F11. найди там Options. нажми "+". найди goEditing. поставь значение true.

user posted image

Автор: васек 9.11.2006, 16:31
Люди подскажите как разработать визуальную компаненту таблицы умножения String Grid? smile 

Автор: docwar 9.11.2006, 21:56
Reptile, это понятно! У меня трудности с написанием кода! Можешь помочь? =)

dumb, без комментариев...

Автор: Romikgy 9.11.2006, 22:05
docwar, я сколько смотрю , ты все просишь, помогите , помогите, 
только я до сих пор не понял , чем помочь то?

Автор: Reptile 10.11.2006, 10:52
Цитата(docwar @  9.11.2006,  21:56 Найти цитируемый пост)
Можешь помочь? =)

docwar, есть 2-а способа:
  • Простой, как еаписал dumb(он подробна объяснил), так ты сможеш изменять прямо в StringGrid
  • Сложнее через доп форму 
    вот простой проект  smile (Можно конечно покультурнее, но... smile )

ОЙ smile  smile  smile 
Сорри проект на Delphi (забыл какой раздел  smile  smile  smile ),
но думаю алгоритм под Builder переделать не сложно smile 

Автор: docwar 10.11.2006, 12:59
Reptile, буду благодарен, если проект под Билдер адаптируешь, а то открыть cpp не смог...
Romikgy, надо открыть доп. форму, содержащую в Эдитах текст выделенной строки (причем каждый столбец - отдельный эдит), внести изменения, нажать на клавишу и заменить ранее выделенную строку измененной... =)

Автор: Reptile 10.11.2006, 13:42
Под рукой Builder-а нету smile 
Пишу здесь могут быть опечятки smile 
Вот это вешаеш на нажатие кнопки:
Код

  Form2->Edit1->Text = StringGrid1.Cells[1][StringGrid1->Row];
  Form2->Edit2->Text = StringGrid1.Cells[2][StringGrid1->Row];
  Form2->Edit3->Text = StringGrid1.Cells[3][StringGrid1->Row];
  Form2->Edit4->Text = StringGrid1.Cells[4][StringGrid1->Row];
  Form2->ShowModal();

Это во второй форме на нажатие "Сохранить"(или как там у тебя...):
Код

  Form1->StringGrid1->Cells[1][Form1->StringGrid1->Row] = Form2->Edit1->Text;
  Form1->StringGrid1->Cells[2][Form1->StringGrid1->Row] = Form2->Edit2->Text;
  Form1->StringGrid1->Cells[3][Form1->StringGrid1->Row] = Form2->Edit3->Text;
  Form1->StringGrid1->Cells[4][Form1->StringGrid1->Row] = Form2->Edit4->Text;
  Close(); 

Если будут ошибки - пиши smile Буду благодарен за исправления.
P.S.Не забудь подключить формы друг к другу.

Автор: docwar 10.11.2006, 17:11
Reptile, спасибо огромное!!!
Я писал такой же код, но строка после редактирования добавлялась ПОСЛЕ, а не заменяла строку, текст которой помещался в Эдиты... поэтому и решил, что метод мой ошибочный! ))
Уже и перед нажатием на ОК (на форме редактирования) активировал ф-ию удаления строки и Form1->StringGrid1->RowCount--; писал.....
Как быть? =)

Добавлено @ 17:13 
Строка после редактирования добавляется после всех остальных строк....

Автор: Reptile 10.11.2006, 17:50
Цитата(docwar @  10.11.2006,  17:11 Найти цитируемый пост)
Я писал такой же код, но строка после редактирования добавлялась ПОСЛЕ, а не заменяла строку

Значит уже не такой smile 
Цитата(docwar @  10.11.2006,  17:11 Найти цитируемый пост)
Уже и перед нажатием на ОК (на форме редактирования) активировал ф-ию удаления строки и Form1->StringGrid1->RowCount--; писал.....
Как быть? =)

Не понял smile
Етот код редактирует, для добавления строки делай похожую форму но увеличивай Form1->StringGrid1->RowCount и добавляй.

Цитата(docwar @  10.11.2006,  17:11 Найти цитируемый пост)
Добавлено @ 17:13 
Строка после редактирования добавляется после всех остальных строк.... 

Как это? 
Код

  Form1->StringGrid1->Cells[1][Form1->StringGrid1->Row] = Form2->Edit1->Text;
  Form1->StringGrid1->Cells[2][Form1->StringGrid1->Row] = Form2->Edit2->Text;
  Form1->StringGrid1->Cells[3][Form1->StringGrid1->Row] = Form2->Edit3->Text;
  Form1->StringGrid1->Cells[4][Form1->StringGrid1->Row] = Form2->Edit4->Text;

Изменяет сущуствующие ячейки,он не добавляет
В чем вопрос?

Автор: docwar 10.11.2006, 18:21
Вопрос в том, что строка, которую мы выбираем для редактирования остается неизменной, а отредактированная добавляется ПОСЛЕ всех строк таблицы...

Цитата(Reptile @  10.11.2006,  17:50 Найти цитируемый пост)
Етот код редактирует, для добавления строки делай похожую форму но увеличивай Form1->StringGrid1->RowCount и добавляй.

Увеличивать RowCount или нет? Только смысл? Уменьшение желаемого результата тоже не принесло.

Забыл сказать, что у меня на главной форме прописано StringGrid1->Options = StringGrid1->Options << goRowSelect; ..... но это ни на что не должно влиять...

Автор: Reptile 10.11.2006, 18:44
Цитата(docwar @  10.11.2006,  18:21 Найти цитируемый пост)
Вопрос в том, что строка, которую мы выбираем для редактирования остается неизменной, а отредактированная добавляется ПОСЛЕ всех строк таблицы...

 smile
Покажи код навешаный на кнопку ОК. А лучше прикрепи проект, я проверю и завтра выложу smile 
Какие у Тебя значения в FixedRows и FixedCols ?

Цитата(docwar @  10.11.2006,  18:21 Найти цитируемый пост)
Увеличивать RowCount или нет?

Нет, если надо только редактировать.

Цитата(docwar @  10.11.2006,  18:21 Найти цитируемый пост)
Забыл сказать, что у меня на главной форме прописано StringGrid1->Options = StringGrid1->Options << goRowSelect; 

Это логично, иначе Ты бы не выделял всей строки smile 


Автор: docwar 10.11.2006, 18:53
FixedRows=1
StringGrid1->FixedCols = 0;

Сожалею, но весь проект прикрепить не могу....  smile 

Цитата(Reptile @  10.11.2006,  18:44 Найти цитируемый пост)
Покажи код навешаный на кнопку ОК.

Код
  Form1->StringGrid1->Cells[0][Form1->StringGrid1->Row] = Form2->Edit1->Text;
  Form1->StringGrid1->Cells[1][Form1->StringGrid1->Row] = Form2->Edit2->Text;
  Form1->StringGrid1->Cells[2][Form1->StringGrid1->Row] = Form2->Edit3->Text;
  Form1->StringGrid1->Cells[3][Form1->StringGrid1->Row] = Form2->Edit4->Text;
  Form1->StringGrid1->Cells[4][Form1->StringGrid1->Row] = Form2->Edit5->Text;
  Form1->StringGrid1->Cells[5][Form1->StringGrid1->Row] = Form2->Edit6->Text;
  Form1->StringGrid1->Cells[6][Form1->StringGrid1->Row] = Form2->Edit7->Text;
  Form1->StringGrid1->Cells[7][Form1->StringGrid1->Row] = Form2->Edit8->Text;
  Close(); 

Автор: Reptile 10.11.2006, 19:10
Цитата(docwar @  10.11.2006,  18:53 Найти цитируемый пост)
Сожалею, но весь проект прикрепить не могу....  smile 

Тогда ничем не могу помочь smile 
У меня все работает smile 
Не могу понять
Цитата(docwar @  10.11.2006,  18:21 Найти цитируемый пост)
отредактированная добавляется ПОСЛЕ всех строк таблицы...

Как  smile 

Автор: docwar 10.11.2006, 21:09
Reptile, вопрос решил добавление переменной, хранящей номер строки, которую мы хотим отредактировать.
Как же ты без этого сделал не пойму!

Спасибо большое за помощь!

Автор: Reptile 11.11.2006, 10:27
Цитата(docwar @  10.11.2006,  12:59 Найти цитируемый пост)
Reptile, буду благодарен, если проект под Билдер адаптируешь

Бодьше не чем не могу помоч smile 

Автор: XPyCT 2.7.2008, 14:24
Цитата(docwar @ 29.9.2006,  17:22)
Извините, но я не могу выделить строку. Это вообще возможно?

что тут  не ясного! хоть пост был давно но отпишу
Предположим у вас стрингрид  с одним выделенным рядом и одним выделенным столбцом!
нумерация в стрингриде идет с нуля!
и так первый фикс ряд =0  и фикс кол=0;

идем дальше вам нужно к примеру выделить ряд под номером №5

кидаем на форму едит и кнопку
Далее пишем там этот код по событию нажатия кнопки
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int cRow=StrToInt(Edit1->Text);

  if(cRow > StringGrid1->RowCount-1 || Edit1->Text.IsEmpty())
    ShowMessage("Диапазон рядов задан не верно!");
      else
       {
        StringGrid1->Row=cRow;
        StringGrid1->Options<<goRowSelect;  //  "<<" - так разрешаем выделение строки  ">>" -Так запрещаем
         // goEditing; "<<" - так разрешаем Редактирование таблицы  ">>" -Так запрещаем
       }
}



Одновременное применение своиств  goRowSelect и goEditing не дает эфекта (goEditing);- только goRowSelect 




Автор: XPyCT 4.7.2008, 10:18
вот написал думаю поможет!
прошу не пинать сам не силен но пишу то что знаю и делал!
и так есть две формы
fmBaza - Главная форма
fmADD- Форма добавления товара
SGBaza- StringGrid

по нажатию клавиши ентер появляется форма добавления
которая смотрит какая колонка и ряд и исходя из этого  уже добавляет
привожу код 
1. Главная форма
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include<winuser.h>

#include "MAIN_Unit.h"
#include "ADD_ITEM_Unit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfmBaza *fmBaza;
int cRow,cCol; //Глобальные переменные
//---------------------------------------------------------------------------
__fastcall TfmBaza::TfmBaza(TComponent* Owner)
        : TForm(Owner)
{
     //Ввод начального значения
SGBaza->Cells[1][1]="Сахар";
SGBaza->Cells[2][1]="20,75";
SGBaza->Cells[3][1]="8,25";
}
//---------------------------------------------------------------------------
void __fastcall TfmBaza::FormShow(TObject *Sender)
{
SGBaza->ColWidths[0]=30;   //Задаем размер колонок
SGBaza->ColWidths[1]=150;
SGBaza->ColWidths[2]=80;
SGBaza->ColWidths[3]=80;

SGBaza->Cells[0][0]="№";     //Озаглавливание фикс ряда
SGBaza->Cells[1][0]="Найменование";
SGBaza->Cells[2][0]="Кол-во";
SGBaza->Cells[3][0]="Цена в руб";

SGBaza->SetFocus(); //Передача фокуса в таблицу
SGBaza->Options<<goTabs; //Разрешаем перемещение по таблице клавишей таб

//нумерация всех рядов
for(int i=1; i<SGBaza->RowCount; i++)
SGBaza->Cells[0][i]=i;
}
//---------------------------------------------------------------------------
void __fastcall TfmBaza::SGBazaKeyPress(TObject *Sender, char &Key)
{
if(Key==VK_RETURN)
   {
     cRow=SGBaza->Row; //Получаем Активную строку
     cCol=SGBaza->Col; //Полчаем  Активную колонку

     fmADD->Edit1->Text=SGBaza->Cells[cCol][cRow];
     fmADD->Show();
   }


}
//---------------------------------------------------------------------------
void __fastcall TfmBaza::btAddRowClick(TObject *Sender)
{
SGBaza->RowCount++;
cRow=SGBaza->RowCount-1;
cCol=1;//Делаем активным первую колонку последнего ряда
SGBaza->Row=cRow; //Делаем активным последний ряд
SGBaza->SetFocus(); //Передача фокуса в таблицу
//нумерация всех рядов
for(int i=1; i<SGBaza->RowCount; i++)
SGBaza->Cells[0][i]=i;
}
//---------------------------------------------------------------------------
void __fastcall TfmBaza::btDeleteRowClick(TObject *Sender)
{
if(SGBaza->Cells[1][1].IsEmpty()&& SGBaza->Cells[2][1].IsEmpty()&& SGBaza->Cells[3][1].IsEmpty())
 ShowMessage("Нечего удалять!");  //Если единственный ряд пустой
 else
 {

if (MessageDlg("Вы действительно хотите удалить запись? "+SGBaza->Cells[1][cRow],mtConfirmation,TMsgDlgButtons() << mbOK<<mbCancel,0)==mrOk)
  {   //Если всего один ряд то просто очищаем
    if(SGBaza->RowCount==2 && SGBaza->Row==1 )
   {
    SGBaza->Cells[1][1]="";
    SGBaza->Cells[2][1]="";
    SGBaza->Cells[3][1]="";
    }
    else
     {
     class TProxyGrid : public TStringGrid
    {
       public:
        using TStringGrid::DeleteRow;

   };

    ((TProxyGrid*)SGBaza)->DeleteRow(cRow);

    }
  }
  }

SGBaza->SetFocus(); //Передача фокуса  в таблицу
//нумерация всех рядов
for(int i=1; i<SGBaza->RowCount; i++)
SGBaza->Cells[0][i]=i;

}
//---------------------------------------------------------------------------
void __fastcall TfmBaza::SGBazaKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
if(Key==VK_INSERT)//Добавляем ряд при нажатии клав инсерт
fmBaza->btAddRow->Click();
}
//---------------------------------------------------------------------------




2. Форма добавления

Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "ADD_ITEM_Unit.h"
#include "MAIN_Unit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfmADD *fmADD;
extern int cRow,cCol; //Глобальные переменные
//---------------------------------------------------------------------------
__fastcall TfmADD::TfmADD(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfmADD::Edit1KeyPress(TObject *Sender, char &Key)
{
int i,k,s=0;
char str[10];
  if(Key==VK_RETURN) //если нажата клавиша ентер
  {
    if(cCol==1)  //Просто добавляем или заменяем наименование товара
    fmBaza->SGBaza->Cells[cCol][cRow]=Edit1->Text;
    if(cCol==2)//Дабавляем к существующему количеству новое 2+2=4
     {
//---Конвертирование содержимого Edit1 и замена точки на запятую-
      strcpy(str,Edit1->Text.c_str());
       for(i=0; i<10; i++)
        if(str[i]=='.')
          str[i]=',';
          Edit1->Text=str;
//---Конвертирование содержимого Edit1 и замена точки на запятую---End--
          if(!fmBaza->SGBaza->Cells[cCol][cRow].IsEmpty())//Если ечейка не пустая
                {
fmBaza->SGBaza->Cells[cCol][cRow]= //Добавление количества
FloatToStr(StrToFloat(fmBaza->SGBaza->Cells[cCol][cRow])+StrToFloat(Edit1->Text));
                }
             else
                {  //если ечейка пустая
//---Конвертирование содержимого Edit1 и замена точки на запятую-
             strcpy(str,Edit1->Text.c_str());
            for(i=0; i<10; i++)
            if(str[i]=='.')
           str[i]=',';
            Edit1->Text=str;
//---Конвертирование содержимого Edit1 и замена точки на запятую---End-- ]
           fmBaza->SGBaza->Cells[cCol][cRow]=Edit1->Text;
                }
     }

  if(cCol==3)  //Просто добавляем или заменяем Цену
     {
//---Конвертирование содержимого Edit1 и замена точки на запятую-
             strcpy(str,Edit1->Text.c_str());
            for(i=0; i<10; i++)
            if(str[i]=='.')
           str[i]=',';
            Edit1->Text=str;
//---Конвертирование содержимого Edit1 и замена точки на запятую---End-- ]

    fmBaza->SGBaza->Cells[cCol][cRow]=Edit1->Text;
     }
     fmBaza->SGBaza->SetFocus(); //Передача фокуса  в таблицу
     //нумерация всех рядов
     for(int i=1; i<fmBaza->SGBaza->RowCount; i++)
     fmBaza->SGBaza->Cells[0][i]=i;
     Close();
  }
}
//---------------------------------------------------------------------------


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)