El misterio de los 200…

enero 26, 2012 en Advertencia, Artículos, Comunidad, Delphi, Enlace interesante, Entrada Diario, FireMonkey, LiveBindings, XE2

Aunque ya he comentado el contenido de esta entrada en el foro de facebook, necesitaba colgar de algún lado las fuentes que había utilizado para revisar el tema y de paso, dar la oportunidad para quien todavía no forme parte del mismo pueda acceder a su contenido, o por lo menos a las cosas que parecen interesantes. Es por esa razón que he acabado añadiéndola.

En este caso concreto, el hilo de comentarios del foro se originaba cuando uno de los compañeros, siguiendo las indicaciones del código publicado en el blog de Jim Tierney, que forma parte de los blogs de Embarcadero,  se extrañaba de que al intentar llenar los items de un componente TListBox (en tiempo de ejecución) desde una fuente de datos (un clientdataset, el numero de items añadidos al TListBox era como máximo igual o menor a 200. Y eso sucedía aun cuando dicha fuente de datos contuviera una cantidad mayor.

Esta es la entrada en la que me he basado para reproducir el problema y comprenderlo.

LiveBindings: Code to create TBindLink and fill a Listbox

Creo que lo mas interesante de estas lineas no es ya la corrección que se ha hecho para solucionar el problema, que solo ha consistido en añadir la linea de asignación en el procedimiento FillList( ) de la unidad UMain.pas

LBindList.BufferCount:= ARecordCount;

sino en destacar el punto que originaba el problema:

constructor TBindScopeDBEnumerator.Create(ABindScope: TCustomBindScopeDB;
  const AMemberName: string; ABufferCount: Integer);
begin
  FBindScope := ABindScope;
  FMemberName := AMemberName;
  FSaveActiveRecord := FBindScope.FDataLink.ActiveRecord;
  FNextRecord := FSaveActiveRecord;
  if ABufferCount > 0 then
    FBindScope.FDataLink.BufferCount := ABufferCount
  else
    FBindScope.FDataLink.BufferCount := 200;  // default to max 200 records in buffer
end;

 Al final, ese era el motivo por el que, no estando definido el valor del campo BufferCount en TBindList, cualquier movimiento hacia adelante de la estructura del enumerador, comprobaba si habia llegado al ultimo registro por lo que aunque existiera una cantida mayor en el dataset, el enlace le indicaba que había llegado al último.

:-)

En fin… cosas de los valores por defecto que supongo que sería fijado por algún motivo, porque de hecho el comentario en la misma linea corrobora que se hizo por alguna razón que ahora mismo ciertamente no comprendo.

Lo mas gracioso de todo es que pienso que esto debería por la forma en que se ha planteado afectar en tiempo de diseño por lo que quizás deberíamos comprobar que al crear una relación TBindList desde el editor de expresiones, en tiempo de diseño, el valor del campo en cuestión es correcto. Podéis hacer la prueba y comentamos en el foro. Para probarlo, simplemente acceded a la propiedad LiveBindings del TListBox y cread un nuevo enlace de tipo TBindList. Y seguidamente definid para la propiedad Format un nuevo item con los valores indicados en la rutina FillList( ). En las pruebas que he hecho, también se reproduce el error.

Tened en cuenta este punto para no caer en el problema.

 

 

unit UMain;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, Data.DB, Data.Win.ADODB,
  Datasnap.DBClient, FMX.Layouts, FMX.ListBox, FMX.Bind.Editors, Data.Bind.Components,
  Data.Bind.DBScope, Datasnap.Provider, Data.Bind.EngExt, Fmx.Bind.DBEngExt;

type
  TfrmFillListBox = class(TForm)
    lbxData: TListBox;
    bnFill: TButton;
    bnClear: TButton;
    cdsData: TClientDataSet;
    Conexion: TADOConnection;
    qData: TADOTable;
    dsData: TDataSource;
    dspData: TDataSetProvider;
    cdsDataOrderNo: TFloatField;
    cdsDataCustNo: TFloatField;
    BindScopeDB1: TBindScopeDB;
    lbRecordCount: TLabel;
    lbItemsCount: TLabel;
    BindingsList1: TBindingsList;
    procedure bnClearClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure bnFillClick(Sender: TObject);
  private
    { Private declarations }
    procedure FillLabelRecordCount;
    procedure FillLabelItemsCount;
  public
    { Public declarations }
  end;

var
  frmFillListBox: TfrmFillListBox;

implementation

{$R *.fmx}

//fuente del procedimiento: http://blogs.embarcadero.com/jimtierney
//         http://blogs.embarcadero.com/jimtierney/2011/10/03/31601
//
//  El procedimiento encapsula los pasos para rellenar distintos
//  tipos de controles, siguiendo lo que haria el usuario en tiempo de
//  diseño. Es util para el tiempo de ejecución
//
procedure FillList(AControl: TComponent; const AControlExpression: string;
  ASource: TBaseBindScopeComponent; const ASourceExpression: string; ARecordCount: Integer; const ASourceMemberName: string = '');
var
  LBindList: TBindList;
begin
  LBindList := TBindList.Create(nil);
  try
    // Turn off auto properties.
    LBindList.AutoFill := False;
    LBindList.AutoActivate := False;
    LBindList.ControlComponent := AControl;
    LBindList.SourceComponent := ASource;
    LBindList.SourceMemberName := ASourceMemberName;
    LBindList.BufferCount:= ARecordCount; //<- Linea añadida
    with LBindList.FormatExpressions.AddExpression do
    begin
      SourceExpression := ASourceExpression;
      ControlExpression := AControlExpression;
    end;
    LBindList.FillList;
  finally
    LBindList.Free;
  end;
end;

procedure TfrmFillListBox.bnClearClick(Sender: TObject);
begin
  lbxData.Clear;
  FillLabelItemsCount;
  FillLabelRecordCount;
end;

procedure TfrmFillListBox.bnFillClick(Sender: TObject);
begin
  FillList(lbxData, 'Text', BindScopeDB1, 'AsString', dsData.DataSet.RecordCount, 'OrderNo', );
  FillLabelItemsCount;
  FillLabelRecordCount;
end;

procedure TfrmFillListBox.FillLabelItemsCount;
begin
  lbItemsCount.Text:=  'Items.Count: '+IntToStr(lbxData.Items.Count);
end;

procedure TfrmFillListBox.FillLabelRecordCount;
begin
  lbRecordCount.Text:=  'RecordCount: '+IntToStr(cdsData.RecordCount);
end;

procedure TfrmFillListBox.FormCreate(Sender: TObject);

begin
  Conexion.ConnectionString:= 'Provider=Microsoft.Jet.OLEDB.4.0;'+
                              'Data Source=C:\Program Files\Common Files\CodeGear Shared\Data\dbdemos.mdb;'+
                              'Persist Security Info=False';
  cdsData.Open;

  FillLabelItemsCount;
  FillLabelRecordCount;
end;

end.

Nada mas por comentar. Si deseáis ver el ejemplo podéis acceder al siguiente enlace:

Descargar fuentes

Videos demostrativos Firemonkey – Demos (Danysoft)

noviembre 29, 2011 en 64bits, Comunidad, Delphi, Enlace interesante, FireMonkey, Nos deja la semana..., Seminario web, Videos, XE2

 

Con fecha de hoy, Danysoft ha subido a YouTube dos vídeos demostrativos, que sin duda os van a parecer interesantes y es por eso el remarcarlos aquí e incluirlos en esta entrada.

Ambos son parte de la misma sesión: El primero de ellos aborda el tema de Firemonkey desde la perspectiva de Windows, mostrando algunas posibilidades de la plataforma,  como efectos y calidad gráfica propia de los nuevos componentes y del uso de la GPU. El segundo vídeo prosigue la ejecución de la demo en el lado del compilador para Mac, mostrando la ejecución del programa en el simulador de iPhone.

Ya he añadido, igualmente, los enlaces al grupo de Facebook Delphi Solidario, para quienes estáis siguiendo el día a día en él. Gran trabajo el que está haciendo el partner español de Embarcadero, Danysoft, al generar esta colección de recursos que van quedando disponibles para todos nosotros.

Que los disfrutéis.

 

Parte 1.

Rad Studio XE2 | FireMonkey | demo windows

Parte 2.

Rad Studio XE2 | FireMonkey | demo Mac

 

Conversando con Pawel Glowacki

octubre 17, 2011 en Comunidad, Delphi, Entrada Diario, Eventos, FireMonkey, Nos deja la semana..., Presentaciones, Roadmap, XE2

 

Entrevista a Pawel Glowaky de Embarcadero

Foto: Germán Estévez, Pawel Glowacki y Salvador Jover.

Si pulsáis en la imagen, podéis acceder a la entrada del blog de nuestro compañero Germán Estévez, en la que conjuntamente, hemos intentado recoger la breve charla que pudimos mantener con el representante de Embarcadero, Pawel Glowacki, al finalizar el evento de Barcelona. Para nosotros tiene una importancia simbólica, ya que lo valoramos como una muestra del acercamiento de Embarcadero a nuestra Comunidad. Fue una charla distendida y agradable, sin demasiadas pretensiones por nuestra parte, pero creo que al final fue positiva. En la foto, señalábamos lo que parecía más importante, lo que resumía aquella charla: FireMonkey.

Si queréis leer como trancurrió, haced click en la imagen superior. Ir a la entrada.

Por nuestra parte, nos resta únicamente dar las gracias a Danysoft, por toda la ayuda que nos ha dado, que ha hecho mas sencillo preparar las entradas que han servido de resumen del evento.

Delphi Básico, Delphi Solidario y Comunidad Hispana

octubre 13, 2011 en Comunidad, Delphi

Hola compañeros,

como sabéis, hace un tiempo y con motivo del cambio de nombre del blog, incrementé las actividades en las redes sociales y mas concretamente en Facebook, creando un grupo de facebook que respondía al mismo nombre “Delphi Solidario“, desde el que se inició una etapa de difusión de contenido para nuestra Comunidad.

Respecto al cambio del nombre del blog, y de por qué pasó de ser Delphi Básico a llamarse Delphi Solidario podéis leer en la entrada Cerrando temas… , donde intentaba justificarlo y compartirlo con vosotros. Este punto lo podéis leer al final de la misma.

Lo realmente importante es que el grupo de facebook ha ido creciendo, superando las primeras expectativas y se han sumado compañeros sin los que hubiera sido imposible proyectarse hacia el exterior ni pensar en que el grupo puede llegar a más. No es un tema de que se incremente el numero de participantes -que se ha incrementado de forma considerable- sino que además, el grupo de facebook, está acogiendo a los compañeros que han colaborado activamente en la difusión de contenidos de habla hispana, intentando abrir los brazos simbólicamente hacia todos, sin excluir a nadie en este intento de crear un lugar común para nuestra Comunidad. La idea no es que dejen de existir los blogs o los foros, sino todo lo contrario, en dotar a la Comunidad de un punto de encuentro que los refuerce, manteniendo su propia idiosincracia y carácter; un lugar en el que puedan difundirse todos ellos y cualquier usuario (nuevo o no tan nuevo) que busque información sobre cualquier tema de nuestra herramienta de desarrollo, encuentre una respuesta real y efectiva. No buscamos dividir ni ser protagonistas, que entiendo es una idea que puede quedar en el aire y que de alguna forma hay que despejar, sino participar y proponer la creación de un marco que sea representativo de todos los bloggers, comunidades y grupos de Delphi. Y se está luchando también para que en dicho marco, se pueda contar con Embarcadero y que no sea ajeno a nuestra Comunidad.

Se que todo esto es un tanto complicado y que el grupo de facebook es el primer paso, un poco provisional, de una visión de Comunidad mas ambiciosa y solidaria. Pero os aseguro que estamos en ello.  :-)

Por ello, finalmente y tras meditarlo varios días, y antes de seguir con las acciones de difusión del grupo, he pensado que era necesario desligar mi blog del grupo de facebook, de forma que no se pudiera entender que encuentro un aprovechamiento del esfuerzo ajeno y que a mi me beneficia en algo. Y para que no exista la mínima duda de que esto no es así (y aunque se que los que me conocen lo saben hasta el punto de ser innecesario cambiar nada) he pensado que me cuesta poco que el blog vuelva a ser Delphi Básico, de forma que no exista una relación directa entre el nombre de uno y otro, y podamos seguir ese esfuerzo iniciado en pro de la Comunidad, que a fin de cuenta somos nosotros mismos.

Es por eso que el blog volverá a llamarse Delphi Básico y el grupo Delphi Solidario seguirá con el mismo nombre.

Curiosamente, esta especie de proyecto que estaba en nuestra mente, iba a llevar nombres mas tradicionales, como Comunidad Hispana de Delphi, o Delphi Hispano, o similares. Y de repente, por los comentarios recibidos en facebook, uno se da cuenta de que el grupo encuentra que el nombre les gusta, que el calificativo “solidario” dice mas que el conservador termino de Hispano. Porque valoramos positivamente el compromiso y entendemos que ese espíritu está mas relacionado con lo que tradicionalmente ha defendido nuestra Comunidad.

Así que esa es un poco la idea, para que entendáis el motivo del cambio y de que el blog se vuelva a llamar Delphi Básico.