Ver Mensaje Individual
  #10  
Antiguo 23-03-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Reputación: 31
Lepe Va por buen camino
Bueno, aqui va una de código, ahh, si quereis optimizar el código... será bienvenido

Uso una funcion rarita... codigoutil.ifthen es la equivalente que tiene Delphi en la unidad Math, strutils, y en otra unidad más que no recuerdo, yo las he metido en un .pas llamado CodigoUtil .... muy original .... ya

Las Lineas que empiezan con FrmDebug.anade ... son llamadas a una ventana auxiliar para ver por donde iba el programa y como furulaba. (pueden obviarse esas lineas.

Código:
procedure AjustaDisplayWidth(D:TDataSet;const MaxAncho:Integer = 150);
var i, nIdx:Integer;
begin
if D.Active then
begin
  try
  D.DisableControls;
  D.First;
  nIdx:=0;
  while not D.Eof do
  begin
     for i:=0 to pred(D.FieldCount) do
     begin
          // en la 1ª vuelta reseteo el displayWidth existente
          if (nIdx = 0) then
            D.Fields[i].DisplayWidth  := 1;
          D.Fields[i].DisplayWidth  :=EnsureRange(
                                                  Max(  D.Fields[i].DisplayWidth,
                                                        Length(D.Fields[i].AsString)+
 codigoutil.IfThen(D.Fields[i].DataType = ftFloat, 3) 
// añadimos espacios para ,00
                                                      ),
                                                  0,MaxAncho);
     end;
     D.Next;
     Inc(nIdx);
  end;
  finally
    D.EnableControls;
  end;
end; // D.active
end;
Formatear los números para que salgan en los listados con 2 decimales y puntos de millar:
Código:
procedure FormatFloatFields(Rpt:TcustomQuickrep);
var j :Integer;
    Band : TQRcustomBand;
begin
  Band := Rpt.Bands.DetailBand;

  for j:=0 to Band.ControlCount -1 do
  if Band.Controls[j] is TQRExpr  then
  with TQRExpr(Band.Controls[j]) do
  begin
    if (Pos('percentiva',Expression) = 0)) then
      Mask := '#,##0.00'; // curosamente si es un texto lo que hay no le
                                 // afecta, solo he probado con campos de
                                //  Float, Texto, Boolean y enteros. con los demás no 
                               //  sé que hará exactamente.
  end;
end;
Añadir un SummaryBand en tiempo de ejecución (despues de la linea del QrcreateList) Esta funcion es un coñazo.... no está muy bien hecha . Además he encontrado algunos bugs menores que no sé como solucionarlos.

Código:
procedure AnadirSummaryBand(Rpt:TcustomQuickrep;const Data : TDataSet;const Campos:TStringList);

const SEP = 20;

var i :Integer;
    MaxLeft : Integer;
    CampoActual: TField;
    TotalLabel : TQRLabel;
    Total     : TQRExpr;
    Unidades: TQRUnit;
begin
// 9-03-2004  añadir totales al informe
  with Rpt do
  begin
    Unidades:= units;
    Units := Pixels;
    if not Bands.HasSummary then
    begin
       Bands.HasSummary:= True;
       with Bands.SummaryBand do
       begin
         Height:= 50;
         Frame.DrawTop:= True;
         Frame.DrawBottom:= True;

// El texto puede salirse a la dcha de la linea right
//         Frame.DrawLeft:= True;
//         Frame.DrawRight:= True;
      end;
    end;
    MaxLeft:=0;
    for i:=0 to pred(Campos.Count) do
    begin
      CampoActual := Data.FindField(Campos[i]);
      if CampoActual  <> nil then
      if CampoActual.DataType = ftfloat then
      begin
        if CampoActual.FieldName= 'percentiva' then
          Continue;

        TotalLabel := TQRLabel(Rpt.Bands.SummaryBand.AddPrintable(TQRLabel));
        TotalLabel.Top:= 10;
        TotalLabel.AutoSize:= True;
        TotalLabel.Caption:= LeftStr(CampoActual.DisplayLabel,10)+':';
      // Base Imponible se solapa con el siguiente campo que haya
        totallabel.Frame.DrawBottom:= True;
//        frmDebug.Anade(['left antes', 'maxleft '],[TotalLabel.Left, MaxLeft] );
        TotalLabel.Left:= MaxLeft; 

        total := TQRExpr(Bands.SummaryBand.AddPrintable(TQRExpr));
        total.Top:= 30;
        Total.AutoSize:= True;
        total.Expression:= 'SUM('+ CampoActual.FieldName+')';
        Total.Left:= TotalLabel.Left;
        Total.Mask:= '#,##0.00';
        MaxLeft := Max(Total.Width, TotalLabel.Width)+ MaxLeft+SEP;

//        frmDebug.Anade('pagina' + FloatToStr(Rpt.Page.Width)+' maxleft '+IntToStr(MaxLeft));

        if (Rpt.Page.Orientation = poportrait) and (MaxLeft >Rpt.Page.Width) then
          Rpt.Page.Orientation:= poLandscape;
      end;
    end;
  end;
// fin 9-03-2004  añadir totales al informe

  Rpt.Units:= Unidades;
end;
Cambiar el número de pagina poniendolo en español, despues de la linea del qrcreatelist
Código:
    with TQRExpr(V.pQuickreport.Bands.PageFooterBand.Controls[0]) do
      expression := QuotedStr('Página ') +'+ PAGENUMBER';
// PAGENUMBER es una variable que entiende QUICKREPORTS
La forma correcta de llamarlo sería asÍ:
Código:
V:=  TPrevi.Create(FrmMdi );
  FreeAndNil(V.pquickreport);
  qrextra.QRCreateList(tcustomquickrep(V.pQuickreport),v, DTM.qryAlb,
                        TituloListado ,ListaCampos);

  AjustaDisplayWidth(dtm.qryalb);
  AnadirSummaryBand(V.pQickReport,dtm.qryAlb,ListaCampos);
  FormatFloatFields(V.pQuickReport);


    with TQRExpr(V.pQuickreport.Bands.PageFooterBand.Controls[0]) do
      expression := QuotedStr('Página ') +'+ PAGENUMBER';
// PAGENUMBER es una variable que entiende QUICKREPORTS
  V.pQuickreport.units:= MM;
  V.pQuickreport.OnPreview:= ListadoOnPreview;
Los Uses que os puede pedir son estos:
Código:
uses  nkstrs,Forms,strutils, Windows,Graphics,Registry,dbtables, Classes,
      types, sysutils,DB, dbgrids, math ,Variants,
      QuickRpt,QRCTRLS, qrprntr, Controls,qrexpr,printers // anadirSummaryband
Espero no olvidarme de nada... Aunque no lo juro, ha sido copy y paste.

Cadetill: ojo al TPrevi.Create

Buen Provecho.
Responder Con Cita