Добрый день!
Нужно сравнить два ячейки в AdvStringGrid.Казалось, что может быть проще, но что-то у меня возникли трудности. Задача, есть две колонки в гриде "от" и "до". Пользователь может редактировать обе, но значения "до" не должно быть меньше "от" и соответственно "от" не должно превышать "до", строка значений "от" и "до" одинаковая, разница только в колонках. В итоге нельзя отпускать пользователя пока не введет корректно. Не удается привязать ни к одному событию, ибо если число многозначное условие срабатывает на первом символе и не дает ввести дальше. Есть еще варианты кроме просто сравнения?
У меня в Дельфи нет этого компонента, есть в Билдере. Но смысл должен быть понятен:
void __fastcall TForm1::AdvStringGrid1EditCellDone(TObject *Sender, int ACol, int ARow)
{
TAdvStringGrid *grid = dynamic_cast<TAdvStringGrid*>(Sender);
int Col = ACol, Row = ARow;
switch(Col)
{
case 3:
if(!(grid->Cells[Col - 1][Row]).IsEmpty())
if(StrToInt(grid->Cells[Col][Row]) < StrToInt(grid->Cells[Col - 1][Row]))
{
// В Дельфи можешь выделить это во вложенную процедуру, чтоб не дублировать код
ShowMessage("Oops, error!!!");
grid->SetFocus();
grid->Col = Col; grid->Row = Row;
grid->EditorMode = true;
}
break;
case 2:
if(!(grid->Cells[Col + 1][Row]).IsEmpty())
if(StrToInt(grid->Cells[Col][Row]) > StrToInt(grid->Cells[Col + 1][Row]))
{
ShowMessage("Oops, error!!!");
grid->SetFocus();
grid->Col = Col; grid->Row = Row;
grid->EditorMode = true;
}
break;
}
}
Не владею С, вот попробовал. Вроде верно отрабатывает, но чет с фокусом не совсем разобрался. Мне как не отпускать пользователя с клетки?
Установи активной ячейкой ту, которая была изначально отредактирована, и только потом переходи в EditMode:
procedure TfrmNormRemont.sgNormRemontEditCellDone(Sender: TObject; ACol,
ARow: Integer);
var TheCol, TheRow : Integer;
begin
TheCol := ACol; TheRow := ARow;
if StrToInt(sgNormRemont.Cells[3, ARow])<StrToInt(sgNormRemont.Cells[2, ARow]) then
begin
ShowMessage('Oops, error!!!');
sgNormRemont.Row := TheRow; sgNormRemont.Col := TheCol;
sgNormRemont.SetFocus;
sgNormRemont.EditMode :=True;
end;
end;
Я так догадываюсь, что он должен войти в режим ввода числа, а он просто выделяет ячейку.
> // В Дельфи можешь выделить это во вложенную процедуру, чтоб не дублировать код
auto ShowError = [grid, Col, Row](){
ShowMessage("Oops, error!!!");
grid->SetFocus();
grid->Col = Col; grid->Row = Row;
grid->EditorMode = true;
}
TarasBer, ты на самом деле думаешь, что Билдер (любой, у меня 2009, если что) поддерживает все фишки нового стандарта?
Работает! Огромное спасибо!
Вопрос не в темку. Как сделать, чтоб запретить ввод значений в двух столбцах. Сделал так, но лочит только последнюю колонку. Надо залочить 0 и 19 колонку.
// CanSelect := not (ACol in [0, 19]);Выбирай, что больше нравится
CanSelect := (ACol <> 0) and (ACol <> 19);
Все нравится! Огромное спасибо!
Есть ли возможность запретить ввод с клавиатуры в ячейки Грида? При чем оставить возможность выбора из вписанного в эти ячейки комбобокса.
В событии AdvStringGrid1GetEditorType для тех столбцов (или строк, как тебе нужно) в которых надо запретить ввод с клавиатуры - выставляй AEditor := edNone, тогда Inplace-редактор создаваться не будет, с клавиатуры ничего не введешь. А там, где AEditor := edComboList (Лист, а не Эдит) - и так только выбирать из списка, клавиатура там не помогает.
class ShowError
{
TGrid grid, int Col, int Row;
public :
ShowError (TGrid grid, int Col, int Row) : grid(grid), Col(Col), Row(Row) {}
void Do ()
{
ShowMessage("Oops, error!!!");
grid->SetFocus();
grid->Col = Col; grid->Row = Row;
grid->EditorMode = true;
}
};