На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Обязательно указание:
1) типа базы данных (Paradox/Oracle/Interbase и т.п.)
2) способа доступа к базе данных (ODBC/ADO/DAO/BDE и т.п.)
Например: Paradox/BDE, MS Access/ADO

Наиболее часто задаваемые вопросы:
Базы даных для начинающих. Первые шаги. Понятие о BDE.
Переход на клиент-сервер и начала ADO
Приёмы работы с BLOB (OLE/Memo) полями
Запросы и параметры или как избавиться от многих проблем. Проблемы с датами в запросах.
Нужели мне нужно устанавливать BDE? (или почему не работает программа на другом компьютере)
Модераторы: Bas, Rouse_
  
> Перерисовка ячейки DBGrid при клике на неё, Перерисовка ячейки таблицы по событию DBGridCellClick в случае, если по клику еще и меняется значение этой ячейки
    Доброго времени суток, уважаемые форумчане. Прошу вашего совета в возникшем вопросе.

    Исходные данные: DBGrid, ZQuery. В ZQuery содержится запрос, в котором выполняется SELECT из нескольких таблиц (использую JOIN'ы). Таблицу прорисовываю вручную (DBGrid.DefaultDrawing := False), т.к. в ней содержится очень много графики (содержимое ячеек подменяются различными картинками).

    Задача: при клике на ячейку таблицы изменять значение этой ячейки (например, банальный чекбокс) и перерисовывать картинку, в зависимости от измененного содержимого.

    Попытка №1. Изменение значения в поле напрямую
    Пробовал в DBGridCellClick() изменять значение поля напрямую через TField.

    ExpandedWrap disabled
      procedure TFrameTemplatePage.DBGridCellClick(Column: TColumn);
      var
        lField : TField;
        lRect  : TRect;
      begin
        lField := DBGrid.Fields[FGridCoord.X]; //FGridCoord : TGridCoord - номер активной ячейки DBGrid
       
        DBGrid.DataSource.DataSet.Edit;
        
        if lField.AsInteger = 0
          then lField.Value := 1
          else lField.Value := 0;
        
        lRect := DBGrid.CellRect(FGridCoord.X, FGridCoord.Y);
       
        DBGridDrawDataCell(Self, lRect, lField, [gdSelected, gdFocused]); //Перерисовываю содержимое этой ячейки
      end;
       
       
      procedure TFrameTemplatePage.DBGridDrawDataCell(Sender: TObject; const Rect: TRect;
            Field: TField; State: TGridDrawState);
      var
        lChecked : integer;
        lStartPoint : TPoint;
      begin
        //Для удобства убрал все лишнее, оставив только необходимый код
        if Field.FieldName <> FCheckFieldTitle
          then Exit;
       
        lChecked := Field.AsInteger;
       
        if lChecked = 1
          then ImageIndex := 0
          else ImageIndex := 2;
       
        lStartPoint := GetCenteredLeftTop(Rect, ImageListCheckBoxes.Width, ImageListCheckBoxes.Height); //самописные функции для отрисовки
        X := StartPoint.X;
        Y := StartPoint.Y;
       
        ImageListCheckBoxes.Draw(DBGrid.Canvas, X, Y, ImageIndex);
      end;


    Все работает ровно до того момента пока не кликну потом на другую какую-нибудь ячейку. Выходит сообщение: Cannot update a complex query with more then one table :( Похоже из-за того что у меня в запросе не одна таблица, такой вариант не прокатывает.

    Попытка №2. Изменение значения поле через стороннюю ORM, обновление ZQuery и позиционирование к нужной записи ZQuery.Locate

    ExpandedWrap disabled
      TFrameTemplatePage.DBGridCellClick(Column: TColumn);
      var
        lField : TField;
        FieldValue : integer;
        PKValue : integer;
      begin
        FieldValue := FQueryBrowse.FieldByName(FCheckFieldTitle).AsInteger;
        PKValue    := FQueryBrowse.FieldByName(FPKFieldName).AsInteger;
       
        FTableRecord.QueryConstructor.ClearConditions;
        if FieldValue = 0
          then FTableRecord.UpdateRecord(PKValue, FCheckFieldName, 1)
          else FTableRecord.UpdateRecord(PKValue, FCheckFieldName, 0);
       
        RefreshBrowse;
      end;
       
      procedure TFrameTemplatePage.RefreshBrowse;
      var
        lStr : string;
        lCurrentRecordID : integer;
      begin
        lCurrentRecordID := GetCurrentRecordId;
       
        lStr := FTableBrowse.GetSelectQuery;
        FQueryBrowse.SQL.Text := lStr;
       
        FQueryBrowse.Active := TRUE;
       
        FQueryBrowse.Locate(PKFieldName, lCurrentRecordID);
      end;


    И этот вариант тоже работает, но происходит обновление всей таблицы, а Locate возвращает курсор DBgrid таким образом, что выбранная строка становится первой сверху. Т.е. позиционирование сбивается и дизориентирует пользователя (заметно, когда в таблице количество записей на 2 экрана и больше).

    Прошу помочь советом.
      Удалось решить проблемы:

      С чекбоксами - за счет того, что убрал из базы соответствующее поле и держу ID'ники выбранных записей в памяти. Все прорисовывается отлично.
      С другими записями - с помощью использования закладок:

      ExpandedWrap disabled
        procedure TFrameTemplatePage.RefreshBrowse;
        var
          lMoveByIndex : integer;
          lBookMark : TBookmark;
        begin
          FQueryBrowse.UpdateCursorPos;
          lBookMark := FQueryBrowse.GetBookmark;
          FQueryBrowse.DisableControls;
          try
            lMoveByIndex := TMyDataSet(FQueryBrowse).FCurrentRecord;
            FQueryBrowse.SQL.Text := FTableBrowse.GetSelectQuery;
            FQueryBrowse.Active := TRUE;
            FQueryBrowse.MoveBy(lMoveByIndex - 1);
            if FQueryBrowse.BookmarkValid(lBookMark)
              then FQueryBrowse.GotoBookmark(lBookMark);
          finally
            FQueryBrowse.EnableControls;
            FQueryBrowse.FreeBookmark(lBookMark);
          end;
        end;
      Сообщение отредактировано: seska86 -
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script Execution time: 0,0816 ]   [ 18 queries used ]   [ Generated: 19.08.19, 01:36 GMT ]