Как получить результаты запроса MySQL для отображения в cxGrid?

Я использую Delphi 5 и хочу отображать результаты запроса MySQL в cxGrid. У меня есть cxGrid, cxGridLevel и cxGridDBTableView, настроенные по умолчанию при добавлении в форму. DataController.DataSource для cxGridDBTableView - это TDataSource с именем DSNewKits с его DataSet, установленным на tMySQLQuery с именем NewKitsQry.

Когда пришло время отображать данные, я устанавливаю для свойства Enabled DSNewKits значение false, запускаю метод Close для NewKitsQry, затем устанавливаю для свойства Enabled DSNewKits значение true, устанавливаю свойство SQL.Text для NewKitsQry и запускаю метод Open NewKitsQry. . Затем у меня появляется диалоговое окно с сообщением, в котором отображается количество результатов в запросе, а их 408, поэтому я знаю, что запрос работает правильно. В сетке отображаются строки и столбцы со строками между ними, нет данных для отображения сообщения, но все ячейки пусты.

Я пробовал выполнять эти шаги в другом порядке, комментируя некоторые из них и т. Д., Но ничего не приводит к отображению данных. Я уверен, что мне не хватает чего-то простого и / или очевидного, но мне не удалось найти пример в Интернете. Спасибо за любую помощь, которую вы можете оказать!

(Отредактировано, чтобы включить код) Вот мой код:


interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  cxGridLevel, cxGridCustomTableView, cxGridTableView, cxGridDBTableView,
  cxClasses, cxControls, cxGridCustomView, cxGrid, ExtCtrls, Db,
  mySQLDbTables, ovcbase, ovcfiler, ovcstore,
  gECCConst,
  StdCtrls;

type
  Tf_cw_cxgrid_db = class(TForm)
    WebCatDB: TmySQLDatabase;
    NewKitsQry: TmySQLQuery;
    DSNewKits: TDataSource;
    Panel1: TPanel;
    cxNewKitsGrid: TcxGrid;
    cxNewKitsGridDBTableView1: TcxGridDBTableView;
    cxNewKitsGridDBTableView1CompanyID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1RegionID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1BranchID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1CustID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1Username: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitComment: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitEffDate: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitExpDate: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitNote: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitType: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitFlags: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitTab: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitAddDate: TcxGridDBColumn;
    cxNewKitsGridDBTableView1KitEditedDate: TcxGridDBColumn;
    cxNewKitsGridDBTableView1Line: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ProductID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1MfgProdID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1PartNum: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ProductDesc: TcxGridDBColumn;
    cxNewKitsGridDBTableView1Qty: TcxGridDBColumn;
    cxNewKitsGridDBTableView1RefQty: TcxGridDBColumn;
    cxNewKitsGridDBTableView1UnitPrice: TcxGridDBColumn;
    cxNewKitsGridDBTableView1UnitPriceType: TcxGridDBColumn;
    cxNewKitsGridDBTableView1UofM: TcxGridDBColumn;
    cxNewKitsGridDBTableView1PSUofM: TcxGridDBColumn;
    cxNewKitsGridDBTableView1UNSPSC: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemNote: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemGroupID: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemDrpDnHdr: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemSection: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemFlags: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemAddDate: TcxGridDBColumn;
    cxNewKitsGridDBTableView1ItemEditedDate: TcxGridDBColumn;
    cxNewKitsGrid1Level1: TcxGridLevel;
    RegistryStore: TOvcRegistryStore;
    userqry: TmySQLQuery;
    Button1: TButton;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  f_cw_cxgrid_db: Tf_cw_cxgrid_db;

implementation

{$R *.DFM}

procedure Tf_cw_cxgrid_db.FormShow(Sender: TObject);
var
  Server : String;
  User   : String;
  Passwd : String;
  DBName : String;
  Button : Integer;
  WCPath : String;
begin
  RegistryStore.Open;
  Server     := RegistryStore.ReadString( 'SBAdmin', 'Host',     '127.0.0.1');
  User       := RegistryStore.ReadString( 'SBAdmin', 'User',     '');
  Passwd     := RegistryStore.ReadString( 'SBAdmin', 'Password', '');
  DBName     := RegistryStore.ReadString( 'SBAdmin', 'Database', WebCatDefUserDBName );  { caw 7-24-20 }
  RegistryStore.Close;

  WebCatDB.Host              := Server;
  WebCatDB.UserName          := User;
  WebCatDB.UserPassword      := Passwd;
  WebCatDB.DatabaseName      := 'WEBCAT_' + DBName;
end;

procedure Tf_cw_cxgrid_db.Button1Click(Sender: TObject);
begin
  DSNewKits.Enabled := False;
  NewKitsQry.Close;
  try
    DSNewKits.Enabled := True;
    NewKitsQry.SQL.Text := 'SELECT KitHdrs.CompanyID, KitHdrs.RegionID, KitHdrs.BranchID, KitHdrs.CustID, ' +
                           'KitHdrs.Username, KitHdrs.KitID, KitHdrs.KitComment, KitHdrs.KitEffDate, ' +
                           'KitHdrs.KitExpDate, KitHdrs.KitNote, KitHdrs.KitType, KitHdrs.KitFlags, KitHdrs.KitTab, ' +
                           'KitHdrs.KitAddDate, KitHdrs.KitEditedDate, KitLines.Line, KitLines.ProductID, ' +
                           'KitLines.MfgProdID, KitLines.PartNum, KitLines.ProductDesc, KitLines.Qty, ' +
                           'KitLines.RefQty, KitLines.UnitPrice, KitLines.UnitPriceType, KitLines.UofM, ' +
                           'KitLines.PSUofM, KitLines.UNSPSC, KitLines.ItemNote, KitLines.ItemGroupID, ' +
                           'KitLines.ItemDrpDnHdr, KitLines.ItemSection, KitLines.ItemFlags, ' +
                           'KitLines.ItemAddDate, KitLines.ItemEditedDate ' +
                           'FROM KitHdrs JOIN KitLines ON KitHdrs.KitSeq = KitLines.KitSeq;';
    NewKitsQry.Open;
    cxNewKitsGridDBTableView1.DataController.CreateAllItems;

    MessageDlg( 'There are ' + IntToStr( NewKitsQry.RecordCount ) + ' records.', mtInformation, [mbOK], 0 );
  except
    MessageDlg( 'There was an error displaying the kit databases.', mtError, [mbOK], 0 );
  end;
end;

end.

person Keila    schedule 17.08.2020    source источник
comment
Пожалуйста, разместите код (Паскаль и форму) в своем q и не описывайте его. Это более полезно и быстрее для воспроизведения вашей проблемы.   -  person Delphi Coder    schedule 18.08.2020


Ответы (1)


Несмотря на то, что cxGrid является прекрасным компонентом, тот факт, что он имеет так много глубоко вложенных свойств, может усложнить настройку cxGrid с нуля.

Я создал приведенный ниже пример, чтобы показать, как создать и настроить cxGrid полностью в коде, чтобы вы могли легко увидеть минимум, который необходимо сделать. Он использует TClientDataSet, который заполняется в коде, для предоставления данных сетки, так что пример полностью самодостаточен. Было бы тривиально адаптировать его к существующему набору данных MySql.

type
  TForm1 = class(TForm)
    CDS1: TClientDataSet;
    DS1: TDataSource;
    DBNavigator1: TDBNavigator;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
  protected
  public
    cxGrid : TcxGrid;
    cxLevel : TcxGridLevel;
    cxView : TcxGridDBTableView;
  end;
[...]
// This is a utility function to create TFields in code
function CreateField(AFieldClass : TFieldClass; AOwner : TComponent; ADataSet : TDataSet;
AFieldName, AName : String; ASize : Integer; AFieldKind : TFieldKind) : TField;
begin
  Result := AFieldClass.Create(AOwner);
  Result.FieldKind := AFieldKind;
  Result.FieldName := AFieldName;
  Result.Name := AName;
  Result.Size := ASize;
  Result.DataSet := ADataSet;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
  Field : TField;
begin
  //  All the code to set up the cxGrid is in this event handler
  
  //  First, create the Fields of the ClientDataSet
  Field := CreateField(TIntegerField, Self, CDS1, 'ID', 'CDS1ID', 0, fkData);
  Field := CreateField(TIntegerField, Self, CDS1, 'Qty', 'CDS1Qty', 0, fkData);
  Field := CreateField(TCurrencyField, Self, CDS1, 'UnitPrice', 'CDS1UnitPrice', 0, fkData);
  CDS1.CreateDataSet;

  CDS1.IndexFieldNames := 'ID';

  //  Next, populate the CDS with a few records
  CDS1.InsertRecord([1, 1, 1]);
  CDS1.InsertRecord([2, 2, 5]);
  CDS1.InsertRecord([3, 3, 6]);

  CDS1.First;

  DS1.DataSet := CDS1;

  //  Now, create a cxGrid to display the CDS data
  cxGrid := TcxGrid.Create(Self);
  cxGrid.Parent := Self;
  cxGrid.Width := 400;

  cxLevel := cxGrid.Levels.Add;
  cxLevel.Name := 'Firstlevel';

  cxView := cxGrid.CreateView(TcxGridDBTableView) as TcxGridDBTableView;
  cxView.Name := 'ATableView';
  cxView.DataController.KeyFieldNames := 'ID';

  cxLevel.GridView := cxView;
  cxView.DataController.DataSource := DS1;
  cxView.DataController.CreateAllItems;
end;
person MartynA    schedule 18.08.2020
comment
Я не понимаю, как источник данных DS1 связан с набором данных CDS1. Установлено ли для свойства DataSet DS1 значение CDS1 (во время разработки)? - person Keila; 20.08.2020
comment
Извините, я подумал, что это настолько очевидно, что я оставил это, но я добавлю его в код - в Delphi (или вы можете сделать это в Object Inspector во время разработки), TDataSource является (единственным) каналом для данных в от набора данных, такого как CDS1, до элемента управления с поддержкой базы данных, такого как TcxGrid. - person MartynA; 20.08.2020
comment
Боюсь, я упускаю что-то столь же очевидное, поэтому и спросил. Я все еще что-то упускаю; мои данные не отображаются. - person Keila; 20.08.2020
comment
Кроме того, работает ли мой код, расскажите мне о результате этого 30-секундного эксперимента: поместите TDBGrid (из вкладки DataControls в палитре компонентов) в свою форму и установите для его свойства DataSource свой DSNewKits. Запустите приложение. DBGrid отображает записи данных или нет? - person MartynA; 20.08.2020
comment
CDS находится на вкладке DataAccess, рядом с TDataSource. - person MartynA; 20.08.2020
comment
Да, DBGrid отображает записи. Я все еще работаю над вашим кодом. - person Keila; 20.08.2020
comment
Позвольте нам продолжить это обсуждение в чате. - person Keila; 20.08.2020
comment
Хорошо; он просто побуждал меня переместить его в чат. Да, DBGrid отображает записи. В моем случае CDS был на палитре Midas, но я наконец нашел его. Когда я запускаю ваш код, он показывает ‹Нет данных для отображения› - person Keila; 21.08.2020
comment
Давайте сначала посмотрим, сможем ли мы заставить мой код работать на вас, потому что он настолько прост, что, если мы не сможем, я не вижу никаких перспектив заставить ваш работать. Я только что создал совершенно новый проект Delphi (7) и трансплантировал код из своего ответа. Он скомпилировал, запустил и отобразил 3 записи. Пожалуйста, сделайте это, но перед запуском приложения установите точку останова отладчика в первой CDS1.InsertRecord... строке. Отладчик останавливается на этой точке останова или нет? Я спрашиваю, потому что я могу получить ваш результат ‹Нет данных для отображения›, только если закомментирую строки CDS1.InsertRecord. - person MartynA; 21.08.2020
comment
Что ж, я чувствую себя пустышкой, но я забыл поместить процедуру FormCreate в событие OnCreate формы. Как только я это сделал, все заработало. - person Keila; 21.08.2020
comment
Что ж, здорово, что вы нашли его там, где он сходил с рельсов! Было бы хорошо, если бы вы тоже приняли мой ответ. - person MartynA; 21.08.2020
comment
Поскольку нет очевидной причины, по которой ваш cxGrid не работает, в вашем положении я бы сделал следующее: запустите полностью новый проект, содержащий только одну форму. На нем поместите только пустую сетку DBGrid из ComponentPalette, подключите ее к TDataSource и к вашему компоненту набора данных MySql. Соедините их и используйте код из моего ответа, чтобы создать cxGrid. Вы по-прежнему получаете результат, что DBGrid показывает данные, а cxGrid - нет? Я предлагаю попробовать это, потому что ваша форма содержит другие компоненты, такие как TOvcRegistryStore из библиотеки Orpheus, которые могут мешать. - person MartynA; 21.08.2020
comment
Это позволило мне понять это. Очевидно, он не соединил все те столбцы, которые я создал во время разработки, с данными; когда я вместо этого использую DataController.CreateAllItems, он работает. Большое спасибо за вашу помощь! - person Keila; 21.08.2020