How to make TProgressColumn work when used with LiveBindings and datasets - delphi

My goal is to have a TGrid with several columns, connected to a TClientDataSet via LiveBindings. One of the columns is of type TProgressColumn.
The grid displays the data, but the progress bar column shows nothing (i.e. 0% progress).
The TProgressColumn is connected to a field of type ftInteger. The values in this field are between 0 and 100.
I've tried with ftSingle, but with no luck.
I set the type of the column to be TProgressColumn via ColumnStyle property, available under TLinkGridToDataSourceBindSourceDB/Columns.
The strange thing is that when I use TPrototypeBindSource to generate values - the TProgressColumn works, but only for ftUInteger values. It fails for ftInteger generators.
Here is a little demo (Delphi XE7):
When I put a breakpoint in TProgressCell.DrawCell() and step over the two conditions for Value.IsOrdinal and Value.IsType are skipped and ClampValue receives a value "Min" which is 0.
There seems to be something wrong with the value, passed to the function.
Is there something special when working with TProgressColumn? Do I need to use CustomFormat, CustomParse in TLinkGridToDataSourceColumn?
Is that a bug or I miss something?
UPDATE:
Thanks to "nompa" the mystery was solved!
In fact "asInteger" is the well known property of the TField class i.e.:
someDataSet.fieldByName('myFieldName').asInteger
In CustomFormat property you can get access to many things, including self.asInteger properties.
More information here:
Using Custom Format and Parse Expressions in LiveBindings
Using binding expressions in the CustomFormat property of a TLinkPropertyToField component
Formatting your Fields
How to treat an Integer field as a Boolean?

The value is string by default, not matter is a integer field. In property CustomFormat write AsInteger.
The value will be take as integer and the progress now is visible.

Related

Summing values in repeated sections in Orbeon

I have a problem when it comes to suming values from a repeated section. Specifically, when I have a repeated section in the orbeon builder with a control that has a value I can easily sum the values of these sections in a different control using sum($control-1) - in the calculated value. When inputing values in the form preview the sum is correct in my control with the summed value.
Unfortunately, when I add a section using the +Insert Below button in the form preview while testing the form the sum() function doesn't work anymore. In the control with this calculated value nothing is shown. Is there a different way to get the sum of values from repeated sections or is this a bug in orbeon?
Once you add a new section while testing the form the sum() function doesn't work anymore, because it adds a empty element to the node-set.
In XPath, when using the sum function, the value of each node is determined by trying to converting it to a number (number()), if there is a empty value, it's gonna convert to NaN, thus in the control with this calculated value nothing is shown by Orbeon.
A different way that would work would be to use the expression like: sum($control-1[text()]) . This way you are testing if the node has content before trying to sum it, so it's always gonna work.

Execute a stored procedure inside textbox to get a localized text

Is it possible to execute a stored procedure inside a textbox? We need this to localize our report.
For example, we have a stored procedure which returns the localized text for a given Key and a given LanguageId. I want to execute this stored procedure for every Label (Textbox) with a different key inside my report.
We are using SSRS 2008.
I think you've got things a little mixed up, you can't "execute a sproc inside a textbox".
What you can do instead, is create a dataset that gets all required Key/Value pairs for your current language, something like this:
EXEC usp_GetReportLabels 'en-US'
/* Returns:
Key Val
--------- ------------
lbl1 Firstname
lbl2 Surname
etc etc
*/
On your textboxes you can use an expression utilizing the Lookup Function to retrieve the correct row from that dataset, and display the label value.
Note: You mention ssrs-2008 but not the ssrs-2008-r2 edition, I don't think the Lookup function is available in plain-2008. In that case you'll need to restructure your dataset(s) a bit to get the same effect. One solution would be to PIVOT the dataset and make the Keys into columns (the dataset will only contain one row in that case, so you can do First(Fields!lbl1.Value)). Bit of a workaround though.

Multiple field values to subreport error

I have a parent report that feeds one of the field values into a subreport. But the problem is that there this field value can include multiple records. For simplicity, assume that this field value is called color, where possible values might be orange, red, and green. I need to pass all of these value to the subreport, not just one. I have tried passing the values this way into the Color parameter of the subreport:
=Fields!Color.Value
But this doesn't work and gives me an error. I have also tried:
=join(Fields!Color.Value,",")
This also gives me an error on the subreport
I have also tried both of the above as an expression in a textbox in the parent report and I get #Error displayed on the parent report. I was able to successfully get just the first value to appear by using a similar expression and the First function. But I am not able to get all of the values to display in this textbox on the parent report? how can I do this or at least pass all of the values to this subreport?
The easy solution is if Color is already a parameter - I would pass this expression in the subreport:
=Parameters!Color.Value
If Color is not a parameter, I would add a column to the driving dataset in the parent report using a SELECT ... FOR XML to concatenate the relevant Color values together. Then you can pass that field to the subreport.

Delphi grid with a different data type in each row, displayed dynamically

I am trying to create a Delphi grid to allow display and edit in a db grid of data that might have a different data type on each row. I would like to display a specific control for each data type, e.g. when the data type is DateTime, I want to display my custom edit control that allows typing a date in or popping up a calendar.
The data looks something like this:
Name DataType DateValue StringValue BooleanValue
---------------------------------------------------------
A Date 1/1/2007
B String asdf
C Boolean True
...and in the db, this table has a column for each possible type of value. So, there is a BooleanValue column, DateValue, etc.
What I would like to do is display a single 'Value' column in the grid that displays the appropriate edit control depending on what the 'DataType' is for that row. So, the grid should look like :
Name DataType Value
---------------------------
A Date 1/1/2007
B String asdf
C Boolean True
It seems I will need to display a different edit control (to allow the user to edit the Value column) for each row dynamically based on the value of the DataType column. I know there are more advanced grids out there that handle this sort of problem, but the powers that be will not allow anything but what is available out-of-the-box with Delphi.
Any ideas on how to make something like this work?
Personally, I would not go for editing directly inside the TDBGrid in this case, since your Table is not DB normalized (I don't use it in any case actually). I would have used a Calculated field to display the desired value in the grid, And dynamically created the TDBxxxEdits on the form for each field type (How about your own TDBTreeEdit for example, a TDBRichEdit, or a DB Image pickup editor, etc...?).
In case you do want to use your own controls on the TDBGrid, and replace the default TInplaceEdit editor, you can refer the following article: Adding components to a DBGrid, and a related article: Displaying and editing MEMO fiels in Delphi's TDBGrid
Displaying all of the data in the same column is quite easy. You can simply add a calculated string field, and change the value according to what you are storing in that row.
The editing is quite a bit more complicated. If you want to have an in-place editor, you are in for a world of hurt... I've done it, it's a pain, and takes a lot of time. If you want to display a dialog to edit the value, that's much easier. You can add a column objects to the grid and you can setup the column you have attached to the calc field to display a button. When the button is clicked you simply display the editing dialog needed for that row, and commit the edits when the dialog is closed.
There are other ways to get this done, but I would say the above would be the shortest way. Other ways may include custom draw events to display your data in one column, intercept clicks to create your own editor, etc, etc, etc...
after add calculated fields .
Sample:
procedure OnCalculate(DataSet:TDataSet);
begin
case IndexText(DataSet['ValueType'],['Date','String','Boolean']) of
0:DataSet['DateValue']:=StrToDateTime(DataSet['Value']); // also converting
1:DataSet['StringValue']:=DataSet['Value'];
2:DataSet['BooleanValue']:= MatchText(DataSet['Value'],['1','True','T','Y','Yes']);
{etc datatypes}
end;
end;

Benefit of using DBComboBox over CombBox?

So I'm messing around with a new project in Delphi 2009 and the default components that can be dropped onto a form for accessing data consist of a SQLConnection, DataSource and SQLQuery. If I add a simple select to the query component, say:
select name from customers
and then drop a DBComboBox on the form and link it up with the DataSource I get a single record in the combo box. After using Google for half and hour to figure out what I was doing wrong it looks like you have to manually add some code to your project which loops through the dataset and adds all the records to the drop down box. Something like:
while not SQLQuery.eof do
begin
DBComboBox.items.add(SQLQuery.fieldbyname('name').asstring);
SQLQuery.next;
end;
And that actually sort of works, but then you get a list in the drop down which you can't actually select anything from. Regardless of the result though I'm wondering why would you even use a DBComboBox if you have to manually add the result of your query to it? Seems to me that if it doesn't automatically populate the db combo box with the result of the query then we might as well be using a non-data-aware component like tcombobox.
I guess what I'm asking is why does it work this way? Isn't the purpose of data aware drag-and-drop controls to minimize the amount of actual written code and speed development? Is there a method that I'm missing that is supposed to make this easier?
A TDBComboBox doesn't get its list of values from the database; it gets its current value from the database. Link it to a field in your dataset, and when you change the active record, the combo box's current value will change. Change the combo box's current value, and the corresponding field's value will change.
If you want to get the list of values from the database as well, then use a TDBLookupComboBox.
This is all covered in the help:
Using TDBListBox and TDBComboBox
Displaying and Editing Data in Lookup List and Combo Boxes
Defining a Lookup List Column
I think you want the TDBLookupComboBox because that allows you to lookup from a list of items where the list comes from a dataset.
In the TDBComboBox, the list is just a TStrings manually filled with data.
--jeroen
DbCombox is a dbaware version of the standard combobox component.

Resources