I save my DBrichView( formatted justified) in a database and I need print in the quickreport.
I using "TRichView wrapper (RVQRControls) v3.0 for QuickReport", tQrDBRichview, but it isn't show the text formatted and also show with different font.
var
sds1: TSQLDataSet;
dsp1: TDataSetProvider;
cds1: TClientDataSet;
qrp1: TQuickRep;
qrbDetailBand1: TQRBand;
qrDBRvw1: TQRDBRichView;
...
with sds1 do
begin
CommandText :=
'select a.id_anot, a.text, a.cod_user from anot a where a.id_ANOT = 1977';
end;
with dsp1 do
begin
Name := 'dsp1';
DataSet := sds1;
end;
with cds1 do
begin
Name := 'cds1';
ProviderName := 'dsp1';
end;
with qrp1 do
begin
Name := 'qrp1';
DataSet := cds1;
end;
with qrbDetailBand1 do
begin
Name := 'qrbDetailBand1';
Parent := qrp1;
BandType := rbDetail;
end;
with qrDBRvw1 do
begin
Name := 'qrDBRvw1';
Parent := qrbDetailBand1;
NoMargins := True;
DataField := 'TEXTO';
DataSet := cds1;
end;
...
How I resolve this?
Related
I have a FDStored procedure that has a datetime parameter:
create procedure [dbo].[p_gl_for_ap]
(#inMode char(1), --I=Invoice, C=Check
#inId_Invoice integer, --reqd for invoice or credit memo maintenance, I
#inReg char(3), --reqd for check update or void, C
#inCheckNo integer, --reqd for check update or void, C
#inIs_Reversal char, --Y only if Invoice Delete or Check Void
#inDt_Rev datetime, --reqd only for reversal
#inDt datetime, --optl G/L tran date; normally null
#inId_glsrcjrn varchar(10),
#inId_create integer,
#ret integer output)
AS
declare....
and I have a FDStoredProc component using the stored procedure:
(following is from component to code)
var
spGLForAP: TFDStoredProc;
spGLForAP := TFDStoredProc.Create(Self);
spGLForAP.Name := 'spGLForAP';
spGLForAP.Connection := dmConnect.cnxData;
with spGLForAP.FormatOptions.MapRules.Add do begin
SourceDataType := dtDateTime;
TargetDataType := dtDateTimeStamp;
end;
spGLForAP.StoredProcName := 'p_gl_for_ap';
with spGLForAP.ParamData.Add do begin
Position := 1;
Name := 'RESULT';
DataType := ftInteger;
ParamType := ptResult;
end;
with spGLForAP.ParamData.Add do begin
Position := 2;
Name := 'inMode';
DataType := ftFixedChar;
ParamType := ptInput;
Size := 1;
end;
with spGLForAP.ParamData.Add do begin
Position := 3;
Name := 'inId_Invoice';
DataType := ftInteger;
ParamType := ptInput;
end;
with spGLForAP.ParamData.Add do begin
Position := 4;
Name := 'inReg';
DataType := ftFixedChar;
ParamType := ptInput;
Size := 3;
end;
with spGLForAP.ParamData.Add do begin
Position := 5;
Name := 'inCheckNo';
DataType := ftInteger;
ParamType := ptInput;
end;
with spGLForAP.ParamData.Add do begin
Position := 6;
Name := 'inIs_Reversal';
DataType := ftFixedChar;
ParamType := ptInput;
Size := 1;
end;
with spGLForAP.ParamData.Add do begin
Position := 7;
Name := 'inDt_Rev';
DataType := ftDateTime;
FDDataType := dtDateTimeStamp;
NumericScale := 3;
ParamType := ptInput;
end;
with spGLForAP.ParamData.Add do begin
Position := 8;
Name := 'inDt';
DataType := ftDateTime;
FDDataType := dtDateTimeStamp;
NumericScale := 3;
ParamType := ptInput;
end;
with spGLForAP.ParamData.Add do begin
Position := 9;
Name := 'inId_glsrcjrn';
DataType := ftString;
ParamType := ptInput;
Size := 10;
end;
with spGLForAP.ParamData.Add do begin
Position := 10;
Name := 'inId_create';
DataType := ftInteger;
ParamType := ptInput;
end;
with spGLForAP.ParamData.Add do begin
Position := 11;
Name := 'ret';
DataType := ftInteger;
ParamType := ptInputOutput;
end;
I am initializing with this code:
function tdmAP.DoGLForAP(whichInvoice: integer; hasDelete: Boolean):
integer;
begin
spGLForAP.Params.ClearValues;
spGLForAP.ParamByName('inMode').AsString := 'I';
spGLForAP.ParamByName('inId_Invoice').AsInteger := whichInvoice;
spGLForAP.ParamByName('inReg').AsString := '';
spGLForAP.ParamByName('inCheckNo').AsInteger := 0;
if hasDelete then
begin
spGLForAP.ParamByName('inIs_Reversal').AsString := 'Y';
spGLForAP.ParamByName('indt_Rev').value := Date;
end
else
begin
spGLForAP.ParamByName('inIs_Reversal').AsString := 'N';
spGLForAP.ParamByName('indt_Rev').AsDateTime := Date;
end;
spGLForAP.ParamByName('indt').AsDateTime := Date;
spGLForAP.ParamByName('inId_glsrcjrn').AsString := '';
spGLForAP.ParamByName('inId_create').AsInteger := LoginRec.LoginUserId;;
try
spGLForAP.Prepare;
spGLForAP.Execute;
Result := spGLForAP.ParamByName('ret').AsInteger;
except
on E:Exception do
begin
ShowMessage('Error executing stored procedure p_gl_for_ap: ' + e.Message);
result := -1;
end;
end;
end;
but I keep getting error back from firedac complaining about the parameter type changing:
error on execute
I have tried using the datatype mapping.
I have tried using this code:
spGLForAP.ParamByName('indt_Rev').value = 0;
and
spGLForAP.ParamByName('indt_Rev').AsDateTime := Date;
and
spGLForAP.ParamByName('indt_Rev').AsDateTime := now;
I have also tried changing the datatypes on the two date parameters from ftTimeStamp to ftDateTime, repreparing the query after setting the parameters types, and just about anything else I can think of. obviously, I'm missing something...
using Delphi 10.2.2 Tokyo, against mssql server 2008R2.
note: in this particular case, I'm trying to set the inDt_rev and inDt to 0. but can't seem to successfully set them to any value.
Try to change this part of your code:
with spGLForAP.ParamData.Add do begin
Position := 7;
Name := 'inDt_Rev';
DataType := ftDateTime;
FDDataType := dtDateTimeStamp;
NumericScale := 3;
ParamType := ptInput;
end;
with spGLForAP.ParamData.Add do begin
Position := 8;
Name := 'inDt';
DataType := ftDateTime;
FDDataType := dtDateTimeStamp;
NumericScale := 3;
ParamType := ptInput;
end;
to this one:
with spGLForAP.Params.Add do begin
Name := '#inDt_Rev';
DataType := ftTimeStamp;
ParamType := ptInput;
end;
with spGLForAP.Params.Add do begin
Name := '#inDt';
DataType := ftTimeStamp;
ParamType := ptInput;
end;
and use Value property instead of .AsDateTime accessor like:
spGLForAP.Params.ParamByName('#inDt').Value := Now;
or use AsSQLTimeStamp accessor:
// uses Data.SqlTimSt;
spGLForAP.Params.ParamByName('#inDt').AsSQLTimeStamp := DateTimeToSQLTimeStamp(Now);
because FireDAC maps such parameter as dtDateTimeStamp type (for which is the AsSQLTimeStamp accessor for).
You can create a custom data type mapping rule:
http://docwiki.embarcadero.com/RADStudio/XE5/en/Data_Type_Mapping_(FireDAC)
And map dtTimeStamp into dtDateTime.
// --------------------------- MAP RULES ------------------------- \\
with dm6.fdDB.FormatOptions do begin
OwnMapRules := True;
with MapRules.Add do begin
SourceDataType := dtDateTimeStamp;
TargetDataType := dtDateTime;
end;
end;
Here is how I am creating My PageControl.
PageCtrlSub := TPageControl.Create(Self);
PageCtrlSub.Parent := GroupSub;
PageCtrlSub.Align := alClient;
SubFormCnt := 0;
TblOdSub.First;
while not TblOdSub.Eof do
begin
SubPartNo := TblOdSub.FieldByName('sub_part_no').AsString;
AddNewSubTab(SubPartNo,Prc1Rs);
TblOdSub.Next;
end;
Here is how I am Creating my TabSheet and Form on the tabSheet.
procedure TFrmSub.AddNewSubTab(PartNo : String; PrcRs : TPriceRec);
var
i : Integer;
begin
inc(SubFormCnt);
TabSheet := TTabSheet.Create(PageCtrlSub);
TabSheet.Caption := 'Sub '+ intToStr(SubFormCnt);
TabSheet.PageControl := PageCtrlSub;
Form := TFrmSubExchange.Create(Self);
Form.Name := 'SForm' + IntToStr(SubFormCnt);
Form.Parent := TabSheet;
for i := 0 to Componentcount-1 do
begin
if (Components[i] is TFrmSubExchange) and (Components[i].Name = 'SForm' + IntToStr(SubFormCnt)) then
TFrmSubExchange(Components[i]).DataChangedSub(PartNo, PrcRs);
end;
Form.Show;
end;
I have a TCaption on each form that is created. When the user changes tab and press a button I need to know the text stored in the TCaption.caption property on the form of the active tab?
Thanks in Advance
Without seeing the DFM for TFrmSubExchange, this is just a guess, but you can try something like this:
procedure TFrmSub.SomeButtonClick(Sender: TObject);
var
s: string;
begin
s := (PageCtrlSub.ActivePage.Controls[0] as TFrmSubExchange).Caption1.Caption;
...
end;
I'm building a custom panel in Delphi XE5 and I'm having a hard time simulating a new "Gravity" property where I can combine two coordinates (like Right + Bottom) and the effect is similar to "Align" however, it does not resize the object, direction. The main problem I encountered is to simulate this behavior. My initial intention was to create a panel in memory with the same "Parent" in my custom panel and then align to the position defined in "Gravity" overwriting the "SetBounds" method. It's working, but a bit precarious, especially in "Design Time". Could someone suggest me how to more effectively simulate this alignment using VCL?
function TZPanel.GetPosition: TCustomPanel;
var
sid: TZSide;
anch: TAnchors;
panTest: TPanel;
function getGravity(al: TAlign): TRect;
var
panGravity: TPanel;
I: Integer;
begin
try
//Self.Visible := False;
panGravity:= TPanel.Create(Self);
panGravity.BevelInner := panTest.BevelInner;
panGravity.BevelOuter := panTest.BevelOuter;
panGravity.BevelWidth := panTest.BevelWidth;
panGravity.BorderWidth := panTest.BorderWidth;
panGravity.ParentBackground := True;
panGravity.SetBounds(panTest.Left, panTest.Top, panTest.Width, panTest.Height);
panGravity.Parent:= Self.Parent;
panGravity.Align := al;
Result:= panGravity.BoundsRect;
finally
panGravity.Destroy;
Self.Visible := True;
end;
end;
begin
panTest := TPanel.Create(Self);
panTest.Align := Align;
panTest.Anchors := Anchors;
panTest.BevelInner := BevelInner;
panTest.BevelOuter := BevelOuter;
panTest.BevelWidth := BevelWidth;
panTest.BorderWidth := BorderWidth;
panTest.SetBounds(Left, Top, Width, Height);
if (FGravity = []) then
begin
//
end
else
begin
panTest.Align := alCustom;
anch := [];
for sid in FGravity do
begin
case sid of
sTop:
begin
panTest.Top := getGravity(alTop).Top;
anch := anch + [akTop];
end;
sRight:
begin
panTest.Left := getGravity(alRight).Left;
anch := anch + [akRight];
end;
sBottom:
begin
panTest.Top := getGravity(alBottom).Top;
anch := anch + [akBottom];
end;
sLeft:
begin
panTest.Left := getGravity(alLeft).Left;
anch := anch + [akLeft];
end;
end;
end;
panTest.Anchors := anch;
end;
Result := panTest;
end;
I have code that creates summary footers at runtime for numeric columns, but I can't get the group summary results to show. I've looked at How to create group summaries at runtime and How to set group summary values and How can create summary footer on runtime? but I'm hitting runtime error:
EcxInvalidDataControllerOperation with message 'RecordIndex out of range'
when the grid is rendering.
This code accepts any TcxGridDBTableView so it would be very easy to put into an existing Delphi form.
procedure SummaryGroup(ASummary: TcxDataSummary; AColumn: TcxGridDBColumn;
AKind: TcxSummaryKind; AFormat: string);
var
sumGroup: TcxDataSummaryGroup;
link: TcxGridTableSummaryGroupItemLink; //TcxDataSummaryGroupItemLink;
item: TcxGridDBTableSummaryItem;
begin
AColumn.Summary.FooterKind := AKind;
AColumn.Summary.FooterFormat := AFormat;
sumGroup := ASummary.SummaryGroups.Add;
link := sumGroup.Links.Add as TcxGridTableSummaryGroupItemLink;
link.Column := AColumn;
item := sumGroup.SummaryItems.Add as TcxGridDBTableSummaryItem;
item.Column := AColumn;
item.Kind := AKind;
item.Position := spGroup;
item.Format := AColumn.Summary.FooterFormat;
end;
procedure AutoAwesum(AView: TcxGridDBTableView);
var
summary: TcxDataSummary;
summing: Boolean;
i: Integer;
dc: TcxGridDBDataController;
col: TcxGridDBColumn;
begin
dc := AView.DataController;
summing := False;
summary := dc.Summary;
summary.BeginUpdate;
try
summary.SummaryGroups.Clear;
dc.BeginFullUpdate;
try
dc.GridView.ClearItems;
dc.CreateAllItems;
for i := 1 to AView.ColumnCount - 1 do
begin
col := AView.Columns[i];
case col.DataBinding.Field.DataType of
ftSmallint, ftInteger, ftWord, ftLargeint, ftAutoInc,
ftLongWord, ftShortint:
begin
summing := true;
SummaryGroup(summary, col, skSum, '#');
end;
ftFloat, ftBCD, ftFMTBcd, ftExtended, ftSingle:
begin
summing := true;
SummaryGroup(summary, col, skSum, '#.##');
end;
ftCurrency:
begin
summing := true;
SummaryGroup(summary, col, skSum, '$#.##');
end;
end;
end;
dc.DataModeController.GridMode := not summing;
AView.OptionsView.Footer := summing;
AView.OptionsView.GroupFooterMultiSummaries := summing;
AView.OptionsView.GroupFooters := gfVisibleWhenExpanded;
finally
dc.EndFullUpdate;
end;
finally
summary.EndUpdate;
end;
end;
What am I missing? Thanks.
Finally had a chance to get back to this. As expected, the changes were few and simple. Here's the code that generically creates group summary headers for each numeric column in a grid. I've left some options commented out in the code that you may want to use.
uses
cxGridDBDataDefinitions;
procedure Summarize(ASummary: TcxDataSummary; AColumn: TcxGridDBColumn;
AKind: TcxSummaryKind; AFormat: string);
var
sumGroup: TcxDataSummaryGroup;
link: TcxGridTableSummaryGroupItemLink;
item: TcxGridDBTableSummaryItem;
begin
AColumn.Summary.FooterKind := AKind;
AColumn.Summary.FooterFormat := AFormat;
AColumn.Summary.GroupKind := AKind;
AColumn.Summary.GroupFormat := AFormat;
AColumn.GroupIndex := -1;
sumGroup := ASummary.SummaryGroups.Add;
link := sumGroup.Links.Add as TcxGridTableSummaryGroupItemLink;
link.Column := AColumn;
item := sumGroup.SummaryItems.Add as TcxGridDBTableSummaryItem;
item.Column := AColumn;
item.Kind := skSum;
item.Position := spGroup;
item.Format := AColumn.Summary.FooterFormat;
end;
procedure AutoAwesum(AView: TcxGridDBTableView);
var
summary: TcxDataSummary;
summing: Boolean;
i: Integer;
dc: TcxGridDBDataController;
col: TcxGridDBColumn;
begin
dc := AView.DataController;
summing := False;
summary := dc.Summary;
summary.BeginUpdate;
try
summary.SummaryGroups.Clear;
dc.BeginFullUpdate;
try
dc.GridView.ClearItems;
dc.CreateAllItems;
for i := 1 to AView.ColumnCount - 1 do
begin
col := AView.Columns[i];
case col.DataBinding.Field.DataType of
ftSmallint, ftInteger, ftWord, ftLargeint, ftAutoInc,
ftLongWord, ftShortint:
begin
summing := true;
Summarize(summary, col, skSum, ',0');
end;
ftFloat, ftBCD, ftFMTBcd, ftExtended, ftSingle:
begin
summing := true;
Summarize(summary, col, skSum, ',.00');
end;
ftCurrency:
begin
summing := true;
Summarize(summary, col, skSum, '$,0.00');
end;
end;
end;
// dc.DataModeController.GridMode := not summing;
// AView.OptionsView.Header := summing;
AView.OptionsView.Footer := summing;
// AView.OptionsView.GroupFooterMultiSummaries := summing;
// AView.OptionsView.GroupFooters := gfVisibleWhenExpanded;
finally
dc.EndFullUpdate;
end;
finally
summary.EndUpdate;
end;
end;
How to bind data from TTreeview control to Edit control in Delphi..
When I click on submit button .Like I can edit that data and have to update it..
procedure TForm1.Button1Click(Sender: TObject);
var
CurrentDeptID, RecordDeptID: Integer;
RootNode, DeptNode: TTreeNode;
begin
CurrentDeptID := 0;
TreeList1.Items.Clear;
RootNode := TreeList1.Items.Add(nil, 'Departments');
DeptNode := nil;
ADOQuery1.SQL.Text := 'SELECT sd.DeptID, sd.Name, d.Dept FROM SubDepartments sd INNER JOIN Departments d ON (sd.DeptID = d.DeptID) ORDER BY d.Dept, sd.Name';
ADOQuery1.Open;
try
ADOQuery1.First;
while not ADOQuery1.Eof do
begin
RecordDeptID := ADOQuery1.FieldByName('DeptID').AsInteger;
if (DeptNode = nil) or (RecordDeptID <> CurrentDeptID) then
begin
DeptNode := TreeList1.Items.AddChild(RootNode, ADOQuery1.FieldByName('Dept').AsString);
CurrentDeptID := RecordDeptID;
end;
TreeList1.Items.AddChild(DeptNode, ADOQuery1.FieldByName('Name').AsString);
ADOQuery1.Next;
end;
finally
ADOQuery1.Close;
end;
Thank you..
There is no DB Treeview as standard in Delphi 7, and in any case the query you have isn't editable. If you want to use data-aware controls on your form, you will need to add an additional dataset to bind your edit controls to. You can store the key reference of the sub-department in the TTreeItem's Data property.
procedure TForm1.Button1Click(Sender: TObject);
var
CurrentDeptID, RecordDeptID: Integer;
RootNode, DeptNode, SubDeptNode : TTreeNode;
begin
CurrentDeptID := 0;
TreeList1.Items.Clear;
RootNode := TreeList1.Items.Add(nil, 'Departments');
DeptNode := nil;
ADOQuery1.SQL.Text := 'SELECT sd.DeptID, sd.Name, d.Dept FROM SubDepartments sd INNER JOIN Departments d ON (sd.DeptID = d.DeptID) ORDER BY d.Dept, sd.Name';
ADOQuery1.Open;
try
ADOQuery1.First;
while not ADOQuery1.Eof do
begin
RecordDeptID := ADOQuery1.FieldByName('DeptID').AsInteger;
if (DeptNode = nil) or (RecordDeptID <> CurrentDeptID) then
begin
DeptNode := TreeList1.Items.AddChild(RootNode, ADOQuery1.FieldByName('Dept').AsString);
CurrentDeptID := RecordDeptID;
end;
SubDeptNode := TreeList1.Items.AddChild(DeptNode, ADOQuery1.FieldByName('Name').AsString);
SubDeptNode.Data := ADOQuery1.FieldByName('DeptID').AsInteger;
ADOQuery1.Next;
end;
finally
ADOQuery1.Close;
end;
In the OnClick event of your Treeview you can recover the key of the Subdepartment and pass that value to your additional query :-
Procedure TForm1.TreeList1Click(Sender : TObject);
Var
lNode : TTreeNode;
lID : Integer;
Begin
lNode := TTreeList.Selected;
If Assigned(lNode) And (lNode.Level = 2) Then
Begin
lID := lNode.Data;
// Pass this lID to your additional query.
End;
End;