Фокус на ячейке Grid-а не адекватно определяет запись в его DataSet

m830
Дата: 13.06.2019 12:52:17
На форме Form3 помещен Grid1, DataSet которого задается программно процедурой
[/SRC]
procedure TForm3.ListBox1Click(Sender: TObject);
Var
  AGrid :TDBGrid;
  ADataSet :TDataSet;
begin
  Edit5.Text:=ListBox1.Items[ListBox1.ItemIndex];
  AGrid:= Form2.FindComponent(Edit5.Text) as TDBGrid;
  If AGrid<>Nil Then
    begin
      DBGrid1.DataSource:=AGrid.DataSource;
      ADataSet:=AGrid.DataSource.DataSet;
      if ADataset is TADOStoredProc then
        Begin
          Edit6.Text:=TADOStoredProc(ADataset).ProcedureName;
          Label7.Caption:=IntToStr(DBGrid1.DataSource.DataSet.RecordCount);
        End;
    end;
  DBGrid1.SetFocus;
end;
[SRC delphi]


При выборе имени Grid-а на форме Form3 фокус устанавливается
на ячейке первой колонки на записи, соответствующей DataSet выбранного Grid-а формы Form2.
Ну а дальше начинаются пляски.
При изменении фокуса Grid-а на форме Form3 (мышкой, клавиатурой) на любую ячейку, расположенную ниже предыдущей,
номер записи DataSet Grid-а на форме Form3 адекватно соответствует новой выбранной ячейки.
А если выбрать ячейку, расположенную выше предыдущей, изменение DataSet Grid-а на форме Form3
как бы замораживается на один выбор.
Победить эти пляски не удается.
Может уже кто-то побеждал? Отзовитесь
krapotkin
Дата: 13.06.2019 14:56:22
давайте упростим ситуацию без всяких номеров записи, т.к. это штука довольно странная

две формы два грида, один датасет и общий датасурс
и если в одном гриде перейти на другую строку, то другой это не отобразит???
DimaBr
Дата: 13.06.2019 15:54:39
m830
Победить эти пляски не удается.

В правильно сформулированном вопросе содержится половина ответа.
Вы 2 недели страдаете над двумя гридами. Вместо того, чтобы чётко сформулировать задачу.
m830
Дата: 14.06.2019 07:57:42
krapotkin,

При изменении фокуса на Grid-е Form3 адекватно изменяется фокус на Grid-е Form2 (родителе). На нем запись адекватно соответствует фокусу.
m830
Дата: 14.06.2019 08:24:32
DimaBr,

Задача простая
Создать форму, которая бы по горячей клавише отражала "внутренности" активной формы (заголовок, Unit, имя формы, Grid-ы на ней) и для выбранного Grid-а отражала хранимую процедуру БД и полный вынос (с Id-шниками таблиц запроса).
И все.
Поэтому и нужен другой Grid, который подхватывает DataSet анализируемого Grid-а и показывает полный вынос хранимки.
А DataSet.RecNo не особо и нужен, нужно значение данных ячейки с фокусом. Но именно по нему я понял проблему.

Обработка события изменения фокуса ячейки осуществляется процедурой
[/SRC]
procedure TForm3.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
  Field: TField; State: TGridDrawState);
Var i:integer;
begin
  Beep;                                                                                      // Для контроля
  Label7.Caption:=IntToStr(DBGrid1.DataSource.DataSet.RecNo);  // Для контроля
  i:=DBGrid1.SelectedIndex;
  Edit1.Text:=DBGrid1.Fields[i].AsString;
end;
[SRC delphi]


А еще мне нужен Edit со скролингом для показа в нем Memo полей и соответствующая процедура для этого. Все, чтоя нашел в Инете меня не вдохновило.
_Vasilisk_
Дата: 14.06.2019 13:50:12
m830
А DataSet.RecNo не особо и нужен, нужно значение данных ячейки с фокусом. Но именно по нему я понял проблему.
Какую проблему?
m830
begin
  Beep;                                                                                      // Для контроля
  Label7.Caption:=IntToStr(DBGrid1.DataSource.DataSet.RecNo);  // Для контроля
  i:=DBGrid1.SelectedIndex;
  Edit1.Text:=DBGrid1.Fields[i].AsString;
end;
Вы, что ли DataSet.RecNo сравниваете с DBGrid.SelectedIndex и видите, что они не равны? Так они и не будут равны. RecNo - это номер записи, SelectedIndex - индекс столбца DBGrid на котором установлен фокус
m830
Дата: 02.07.2019 10:56:17
Проблему победил.
Вместо использования OnDrawDataSel на Grid для отработки события смены ячейки использовал OnDataChange на DataSource.
Мало того, что OnDrawDataSel при смене ячейки вызывается 4 раза, но и косячит с указателем на текущую запись.
Более того, для исключения мерцания при многократном изменении ячеек (расчет суммы по заданному полю на клиенте), помимо отключения прорисовки Grid, временно вообще отключаю OnDataChange, а по окончании расчета восстанавливаю. Очень ускоряет расчет (практически мгновенно), т.к. у Grid-а есть связанные с ним детки с расчетом своих хранимок
  DataSource1.OnDataChange:=AGrid.DataSource.OnDataChange;
  AGrid.DataSource.OnDataChange:=Nil;
  AGrid.DataSource.Enabled:=False;
  Sm1:=0.0;
  Panel2.Visible:=True;
  AGrid.DataSource.DataSet.First;
  while NOT AGrid.DataSource.DataSet.Eof do
    begin
      Sm1:=Sm1+TADOStoredProc(AGrid.DataSource.DataSet).FieldByName(FldName).Value;
      AGrid.DataSource.DataSet.Next;
    end;
  Panel2.Caption:=FloatToStrF(Sm1,ffFixed,10,3);
  AGrid.DataSource.OnDataChange:=DataSource1.OnDataChange;
  AGrid.DataSource.Enabled:=True;
  AGrid.DataSource.DataSet.First;

И Frame рулит

Всем спасибо за помощь
_Vasilisk_
Дата: 02.07.2019 13:09:27
m830
Вместо использования OnDrawDataSel на Grid для отработки события смены ячейки
Капец!
DimaBr
Дата: 02.07.2019 15:10:02
Мне вот интересно, это курсовик или работодатель дал задание ?
Если второе, передайте ему мои искренние соболезнования.
softwarer
Дата: 03.07.2019 01:51:09
m830
помимо отключения прорисовки Grid, временно вообще отключаю OnDataChange

Откройте для себя метод DisableControls.