Im try populate grid in Delphi, with values from database. For now, i have a TSQLConnection, TSQLQuery, TDataSource and TDBGrid.
The components are associated as follows:
1) myTDBGrid DataSource: myTDataSOurce
2) myTDataSource DataSet: myTSQLQuery
3) myTSQLQuery Connection: myTSQLConnection
When compile and run a error message broke the application:
Operation not allowed on a unidirectional dataset
Any ideas ?.
This is standard behaviour for dbExpress: all TSQLDataSets are unidirectional and a TDBGrid cannot handle those.
The solution is to use a TClientDataSet connected to a TDataSetProvider, which itself connects to TSQLQuery.
May I suggest reading the dbExpress tutorial?
Thanks for all. Im using the next article: Building aVCL Forms dvExpress and works.
Related
I'm trying to load about 500k+ data linked to an Oracle DB on my TcxGrid, I want to make the process faster using the GridView "GridMode" property, but I need to do that using a TSQLQuery (DBExpress Component) and it just doesn't work, Gridmode seems inoperable (doesn't load data faster on the Grid, doesn't load custom quantity of records using the "BufferCount" property, etc.)
Here I created a TSQLQuery component and used a query script for my 500k table (for performance purposes I just got 500 values but I need to load 500k+):
TSQLQuery
When I link the TSQLDataSet to the Grid and activate the TSQLQuery it shows all the records from the query, even if the GridMode is TRUE and the GridModeBufferCount is 5
GridWithTSQLQuery
On the other hand, when I use a TQuery, the GridMode just works properly, in this case I had to open SQL Explorer, make the connection and assign that connection to the TQuery DataBase property:
SQLExplorer
Here I show my TQuery with the values mentioned before:
TQuery
And when I activate my TQuery.. voilá:
GridWithTQuery
What I'm doing wrong? or do I need to do more things on my TSQLQuery besides linking it to my dataset and then linking the dataset to the grid?
It's impossible that a very old Tquery can do this and not a newer dbExpress component
Thank you so much guys
I would like to manually build the dataset used by a TDatasetProvider to return the data to the client.
The SQL request is taking a long time to run as a query and I am trying to speed up things by splitting the logic in code and using a kbmMemtable to hold my data before returning it to the client.
Can I do this:
kbmMemtable -> TDatasetProvider -> TClientDataset
If this can be done, in what event of my TDatasetProvider should I set the data in the memtable ?
Using Delphi XE
you could do it in BeforeGetRecords/OnGetData event handler or even elsewhere
How can i set the whole table of a database to show in my delphi form? Using TDBGrid i presume; but when I configure the data source (connected to a query) I receive an error message about it being Unidirectional. I've heard about a Clientdataset but that didnt seem to work. Could i have some clear instructions on how to do this please? Thank you in advance, Toby.
You say you are using TSQLQuery. This is one of the dbExpress components which are designed to be Unidirectional only (except the TSimpleDataSet). You either have to connect the TSQLQuery to a TDataSetProvider and TClientDataSet or change your query component to one that will buffer the data locally.
To use TDataSetProvider and TClientDataSet:
Set the DataSet property of TDataSetProvider to the SQLQuery.
Set the ProviderName property of the TClientDataSet to the DataSetProvider.
When the ClientDataset is opened, it will contain the data from your SQLQuery.
Set the DataSet Property of your TDataSource to the ClientDataset so the data can be displayed in your DBGrid.
Since you appear to be new to using databases with Delphi, I would recommend you use a different query component, because using the TDataSetProvider and TClientDataSet can be complicated. I suggest
TSimpleDatSet in dbExpress,
TADOQUery or TADODataset in dbGo,
TQuery in BDE (not recommended),
TFDQuery in FireDAC, or
other third party query components.
I have a infoPower Grid that is bound to the TQuery Component with following sql
SELECT membership_number, message_id, msgText,target, date_time_creation,
date_time_display
FROM MessageMembership
WHERE membership_number = :membershipnumber
ORDER BY date_time_display desc
qalso I have bind it to the dbnavigator as well as DataSource which is binded with The InfoPOwer Grid. Now insert and delete and update buttons are enable but insert button dont let me type the new values also update button dnt let me type the updated value. But delete is working as expected. What can be possible issue or step I am missing?
The code for executing TQuery is :
MessageMembershipSelectQuery.ParamByName('membershipnumber').AsString :=
custQuery.FieldByName('cust_code').AsString;
MessageMembershipSelectQuery.Open;
Please help me.
TQuery is a BDE dataset. It won´t let you edit it´s contents unless the RequestLive property is set to True and you have a TUpdateSQL component bound to it, by the UpdateObject property. Those two properties work together to enable the batch mode of BDE, which is named cached updates.
However, I strongly advise you to not invest in BDE, not even to learn how to program in Delphi. Much better is to start studing the way of TClientDataset. It´s a much more functional dataset that will give you more control over all parts of your application, from selecting to updating data.
The nice thing about TClientDataset is that you will isolate the SQL dependecy of your application away from the main domain logic, which will be written all around TClientDataset. That logic will be data-dependent, not SQL-dependent.
Think about it: now you have an application that works with MySQL. Then, suddenly, you have to port it to work with Oracle. If you isolate your SQL dependency away from the main code, this refactoring will be much faster and safer.
Remember: BDE is dead.
I have been asked by my company to update the reporting functionality of a paticular application written in delphi and using Quick reports to use FastReports instead.
The current implementation pulls all the data out of the database, does a lot of work to organise and calculate the required data for the reports and stores all this in several different objects. The Quick Report OnNeedData events are then used to fill out the bands until there is no more data (signified by setting MoreData = false)
The problem I'm having is Fast Reports seems to need a band to be connected to an actual data source, which I don't have. Also fastReports doesn't seem to have an event similar to OnNeedData.
Is there anyway to fill out the values of a data band in code and have it print again until all data is printed without connecting the band to a dataset?
I appologise for the vagueness of this question, I am very new to reporting software and any suggestions of where to go and what to look at would be greatly appreciated.
Fast reports use a intermediary object descending from _TFrxDataSet to connect the report engine which the data it prints.
To connect a report to a data source managed by the program itself, you use a TfrxUserDataSet component, which let's you see a data set inside the report, but you manually specify the column names in the Fields (TStrings) property and manage and supply values programatically writing event handlers for the following events:
OnCheckEOF is functionally equivalent to the OnNeedData, if there's no more to print, you set the EOF var parameter to true
OnFirst you do whatever you have to do to start walking for the data.
OnGetValue and OnNewGetValue you provide values for each of the different columns of the current row
OnNext, OnPrior you move your current row one next or one prior position.
As you see, the row/column concept (a DataSet) is used to provide the data to the report, but you can pull your data from any structure you use to store the result of your calculations (lists, arrays, or any other object/structure/file etc.)
Inside the report, you link the band to this logical DataSet and you use standard components to print the column values of this DataSet.
If you already have the data in a DataSet, for example a in-memory DataSet after your calculations, better use a TfrxDBDataset to directly bind your report to that source of data.
you can use TfrxUserDataSet.There is a demo named 'printstringlist' under folder 'demos'.
In our project we have implemented our own class inherited from TfrxCustomQuery. This new query class simply redirects its SQL statements to our application' internal query engine. We registered this new class in FastReport palette (used frxDsgnIntf.frxObjects.RegisterObject* for FR version 3 and 4) and now it is used in all our report templates instead of TfrxADOQuery or other built-in dataset classes.
Here is another alternative:
I've been using FastReport for years. I sometimes run into a similar situation. For offline tabular reports I use an in-memory dataset. I purchased DevExpress long time ago and so I have TdxMemData. But even without it, you should be happy using the TClientDataset component.
Besides that, the TfrxUserDataset is an alternative which I use when showing lists of objects.
There is a possibility to do it like this, it is slow though ,
Code:-
var
FRX: TfrxReport;
procedure NewPage;
begin
MyPage := TfrxReportPage.Create(FRX);
MyPage.CreateUniqueName;
MyPage.PaperSize := DMPAPER_A4;
end;
procedure ...(AText: string);
var
frMemo : TfrxMemoView;
begin
frMemo := TfrxMemoView.Create(MyPage);
frMemo.CreateUniqueName;
frMemo.Text := AText;
end;
Regards
Herman