Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Vale la pena revisarlas, porque algunas son muy interesantes. Hay un poco de todo, de carácter general, técnicas, algunas más “offtopic” y otras referentes a partners y componentes comerciales.
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
40 preguntas de ejemplo, con al menos, 10 votos cada una.
¿Lo conseguiremos? ;-)
TRUCO: Nos interesa que las preguntas lleguen a 10 votos, pero no más; Es decir, es mejor repartir votos para que el máximo de preguntas lleguen a ese límite de 10. ;-)
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Personalmente soy de los que llevo unos cuantos años utilizando las RxLib. Siempre me han parecido unas librerías muy buenas y estables.
Hace un tiempo realizé una traducción (no oficial) de la versión para Delphi 7, para traducirla a Delphi 2005/2006.
Desde ese día hasta hoy, no son pocos los programadores que se han puesto en contacto conmigo, vía correo electríonico o vía mi web para pedirme esa versión o para comentarme cosas sobre versiones posteriores.
Así que me he decidido ha hacer esta recopilación de diferentes versiones, oficiales, no-oficiales, recursos,…
Os adjunto también algo de información de cada una de ellas. En la mayoría de los casos datos del autor y poco más, extraídos de los fuentes o de los archivos TXT que incluyen.
(08/04/2024)
Está disponible para descarga desde la página «no oficial» www.micrel.RxLib la versión 1.0.22 compatible con las últimas versiones de Delphi, Delphi 12 Athens. También os dejo el enlace de descarga desde mi página.
Está disponible para descarga desde la página «no oficial» www.micrel.RxLib la versión 1.0.21 compatible con las últimas versiones de Delphi, Delphi 10.4 Sydney y 11 Alexandría. También os dejo el enlace de descarga desde mi página.
Está disponible para descarga desde la página «no oficial» http://www.micrel.cz/RxLibwww.micrel.RxLib la versión 1.0.19 compatible con Delphi 10.3 Rio. También os dejo el enlace de descarga desde mi página.
Nueva versión no-oficial, de las RxLib. Revisión 1.08. Incluye soporte para la útltima versión de delphi (XE2) y segun el documento con las modificaciones, también soporte para 64 bits.
Añadida versión no-oficial de las RxLib (2.75 build 1.07); Añade un componente nuevo y corrige algunos bugs de la anterior. Según la documentación comprende versiones delde D2005 hasta Delphi XE2.
Versión «no-oficial» de las RxLib que soporta DelphiXE. Esta incluye nuevas funciones y nuevos componentes (17 según leo). Podéis ver la los cambios principales introducidos en esta versión revisando esta página.
También he subido una recopilación de todos los recursos en los diferentes idiomas para la versión 2.75(Bulgarian, Chinese, Chinese (traditional), Czech, Danish, Dutch, French, Galician, German, Geek, Hungarian, Italian, Korean, Mexican, Polish, Portuguese, Romanian, Serbian, Slovene, Spanish, Slovak, Swedish, Turkish, Ukrainian).
Versión (no oficial) para RAD Studio XE; Compilado sin problemas; Incluye packages para Delphi 6 y posteriores hasta RAD Studio XE, junto con las Demos y la ayuda.
Os adjunto también este link, que permite acceder a la ayuda en línea, a partir de las imágenes de los componentes que aparecen en la paleta de las RxLib.
AÑADIDO: Adjunto esta página (traducción automática al castellano) que también hace un recopilatorio de páginas ynoticias relacionadas con las RxLib. Está originalmente en ruso y traducida utilizando el traductor de Google.
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Siguiendo con los ejempos y ahondando en las posibilidades de WMI (Windows Management Instrumentation), a raiz de este hilo en los foros del ClubDelphi, referente al software instalado en nuestro ordenador, he probado a obtener la lista de programas instalados utilizando la WMI.
Para ello podemos utilizar la clase Win32_Product.
Si accedemos a su descripción en MSDN, obtenemos la siguiente descripción de la clase:
Podemos disponer así de toda la información, referente a cada uno de los programas/aplicaciones instalados en nuestro equipo (*NOTA*).
Para ello, lo primero que debemos hacer es Importar a Delphi la librería “Microsoft WMI Scripting v1.X Library (Version 1.X)“, si no lo hemos hecho ya.
En la Introducción sobre WMI, se explica un poco más detalladamente.
Una vez importada, lo siguiente (dentro de nuestro ejemplo) es conectar con nuestro proveedor (en este caso nuestra máquina local):
1
2
3
4
5
6
// Create the Location object
Locator := CoSWbemLocator.Create();// Connect to the WMI service, with the root\cimv2 namespace
aServices := Locator.ConnectServer(STR_EMPTY,{Server}
STR_CIM2_ROOT,{user}STR_EMPTY,{password}STR_EMPTY,
STR_EMPTY,STR_EMPTY,0,nil);
// Create the Location object
Locator := CoSWbemLocator.Create();
// Connect to the WMI service, with the root\cimv2 namespace
aServices := Locator.ConnectServer(STR_EMPTY, {Server}
STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY,
STR_EMPTY,STR_EMPTY, 0, nil);
A continuación, si la conexión ha sido correcta, realizamos la consulta sobre la clase Win32_Product, que nos dará la información que necesitamos.
1
2
3
// realizar la consulta
ObjSet := Services.ExecQuery('SELECT * FROM Win32_Product','WQL', wbemFlagReturnImmediately and wbemFlagForwardOnly ,nil);
// realizar la consulta
ObjSet := Services.ExecQuery('SELECT * FROM Win32_Product',
'WQL', wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
A partir de ahí basta con recorrer los elementos obtenidos y e nuestro caso formatear algunas propiedades para mostrarlas (Caption, InstallDate, Vendor y Version), aunque todas las demás están igualmente a disponsición del programador.
Recordad de colocar en el USES las dos units comentadas antes.
(*NOTA*): Recordemos (link), que una de las características de WMI es que permite «Administración remota», con lo que si tenemos los suficientes permisos, este código también puede servir para inventariar otras máquinas.
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
No hace mucho me cruce con esta “palabrota” este concepto: WMI.
A priori parece sólo eso, una “palabrota” más, de las muchas que nos encontramos en nuestro día a día “informático”. Pero rascando, rascando ha aparecido una perla oculta bajo una capa de polvo.
WMI son las iniciales de “Windows Management Instrumentation”. Se me hace complicado explicar en pocas palabras qué es, pero si tuviera que hacerlo, diría que es algo así como “Una puerta de acceso a la Administración de Sistemas Windows” ( ;-D Windows Management Instrumentation).
Junto a WMI aparecen dos “palabrotas” dos conceptos más que nos ayudan a saber de dónde viene.
WBEM (Web-Based Enterprise Management )
CMI (Common Model Information).
Si las juntamos todas nos queda que, WMI es una implementación que Microsoft ha hecho para Windows, de un estandard llamado WBEM que sirve para la administración de sistemas vía web y que está basado en CIM, que vienen a ser unas clases que nos dan acceso a diferente información del un equipo.
(Traducción al idioma Terrícola):
“A través de WMI yo puedo administrar un equipo basado en Windows, local o remoto, independientemente de la versión del sistema, utilizando las clases que me provee CIM.”
Y esto visto desde el punto de vista de un programador tiene muy buena pinta.
Este podría ser un gráfico sencillo de su estructura.
Dicho esto, yo me pregunto, ¿Qué tiene de bueno WMI y qué puede hacer por mi? (en el terreno más práctico)
Utilizando WMI podemos consultar información sobre nuestro equipo. Desde las aplicaciones instaladas, a la información de la BIOS, discos duros instalados, particiones creadas, Antivirus instalado si lo hay, nivel de carga de la batería (si conviene), procesos ejecutándose, acceso a los servicios instalados, acceso a las tareas programadas, y la lista sigue y sigue…
Cuando hablamos de administración significa que no sólo podemos consultar estos parámetros, sino también modificarlos en muchos casos.
Administración remota. Significa que lo dicho anteriormente se aplica también a administración remota. Es decir, no sólo podemos hacerlo en nuestro equipo, sino en el resto de equipos de la red. WMI está presente en sistemas Windows 2000 con SP2 en adelante. Para los anteriores (95, 98 y NT 4.0) se puede descargar un SDK para instalarlo (link).
Es extensible. Microsoft añade nuevas clases a cada versión de Windows. Además se pueden crear nuevos proveedores de WMI que amplíen funcionalidades.
Acceso desde la línea de comandos. Existe una herramienta para trabajar desde la línea de comandos con WMI (link).
Utilizándola podemos por ejemplo obtener los procesos ejecutándose si desde una ventana de MS-DOS escribimos:
1
2
3
4
WMIC PROCESS
WMIC PROCESS LIST BRIEF (mejora la visualización)
WMIC /output:”c:\procesos.txt” PROCESS LIST BRIEF
(para obtener salida a un fichero)
WMIC PROCESS
WMIC PROCESS LIST BRIEF (mejora la visualización)
WMIC /output:”c:\procesos.txt” PROCESS LIST BRIEF
(para obtener salida a un fichero)
Lenguaje de consulta similar a SQL llamado WQL (WMI Query Language). Utilizándolo podemos desde una ventana MS-DOS ejecutar comandos como estos:
1
2
3
4
5
WMIC PRINTER WHERE Default=”TRUE”
(obtener info sobre la impresora predeterminada)
WMIC PRINTER WHERE Default=”TRUE” LIST FULL
WMIC PRINTER WHERE default="TRUE" GET DriverName,PortName,PrintProcessor
(para obtener determinados datos de la impresora predeterminada)
WMIC PRINTER WHERE Default=”TRUE”
(obtener info sobre la impresora predeterminada)
WMIC PRINTER WHERE Default=”TRUE” LIST FULL
WMIC PRINTER WHERE default="TRUE" GET DriverName,PortName,PrintProcessor
(para obtener determinados datos de la impresora predeterminada)
Aquí se pueden ver unos cuantos ejemplos más a parte de la extensa documentación existente en las páginas de Microsoft.
Una vez hecha esta introducción (muy genérica) sobre WMI, me gustaría centrarme en las aplicaciones que pueden acceder a ella. Microsoft proporciona las API de WMI para scripts, aplicaciones Visual Basic, aplicaciones C++ y .NET Framework. Eso no quiere decir que no se pueda acceder desde casi cualquier lenguaje. En mi caso me voy a centrar en el acceso a ella desde Delphi.
Para acceder desde Delphi a WMI lo primero que necesitamos en Importar la librería desde el menú de Project/Import Type Library (pasos aquí):
Una vez importada la librería tendremos la unit WbemScripting_TLB.pas generada y lista para utilizar. En nuestros programas deberemos incluir en la clausula USES, esta unit junto con la de ActiveX.
Antes de acabar esta entrada (espero poder publicar más, ya que el tema me parece muy interesante) podemos ver cómo utilizar la WMI para acceder a los datos del disco duro. En este caso, para simplificar vamos a acceder a los datos del primer disco (DiskDrive) existente en el sistema. Para ello se utiliza la clase: Win32_DiskDrive
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Personalmente a veces me sería útil que el formulario que estoy utilizando tuviera algun sistema para detectar cuando se está minimizando el formularo; Y mejor aun que permitiera interactuar con esta acción.
Utilizo a menudo una opción de configuración que llamo: «Minimizar al Tray». Muchas aplicaciones lo utilizan y se trata simplemente de, en lugar de minimizar la aplicación, ocultarla y mostrar un icono junto al reloj en la barra de tareas de Windows.
Para ellos la forma más sencilla que he encontrado es la que explico a continuación. Hay que decir que estoy usando Delphi 5, así que tal vez en alguna versión posterior (que además cuentan con el componnte para el Tray) habrá alguna solución más sencilla.
1
2
3
// Capturar mensajes al formprocedure WMSysCommand(var Msg: TWMSysCommand);message WM_SYSCOMMAND;
// Capturar mensajes al form
procedure WMSysCommand(var Msg: TWMSysCommand);
message WM_SYSCOMMAND;
// Capturar mensajes....
procedure TFormMain.WMSysCommand(var Msg: TWMSysCommand);
begin
// Minimizando?
if (Msg.CmdType = SC_MINIMIZE) then begin
actionOcultar.Execute;
end
else begin
DefaultHandler(Msg);
end;
end;
En mi caso, lo que hago en el procedimiento es llamar al método de ocultar. Importante que en mi caso no deseo que se realice el Minimizar, por eso, la llamada a DefaultHandler está en el else. Si se desea que igualmente se realice esa llamada, esta debe estar fuera del IF.
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Ya están actualizados en la nueva web los trucos que tenía en la antigua; Tal vez las fechas y el orden no coincidan del todo, pero creo que es lo menos importante.
Están accesible por el Tag: Trucos o desde el acceso de la página principal donde hay creado un pequeño índice de todos los existentes.
Si detectáis algun error (que seguro los hay) os ruego que me lo comuniquéis.
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Utilizando ADO se puede acceder a casi toda la información de la Base de Datos, Tablas y Columnas, pero no a toda. En el caso de las Bases de datos de Access, por ejemplo, la propiedad descripción, que utilizamos para añadir un texto descriptivo a las columnas de las tablas, no es accesible.
Para obtenerla, hace falta acceder directamente a la información del «catálogo» utiliando ADOX. Para poder utilizar ADOX, lo primero que debemos hacer es importar la librería a en Delphi;
Esto se puede hacer desde el menú de: Proyect/Import Type Library.
La librería en concreto es la llamada «Microsoft ADO Ext. for DDL and Security» y proceso paso a paso, podéis verlo es esta página de Zarko Gajic.
Una vez importada la librería, basta con abrir la Base de Datos, acceder a una tabla y a un columna; A partir de ahí ya tenemos todos los datos(propiedades) referentes a esa columna.
El código es sencillo (basta con tener un formulario con un memo (Memo1) y un botón (button1)):
procedure TForm1.Button2Click(Sender:TObject);const
DB_CONNECTION='Provider=Microsoft.Jet.OLEDB.4.0;'+'Data Source=%s';
DATABASENAME ='c:\Archivos de '+'programa\Archivos comunes\Borland Shared\Data'+'\dbdemos.mdb';var
i, j:Integer;
Con:OleVariant;
fCatalog:Catalog;
Column: _Column;
Table:_Table;
Str1, Str2:string;begin// Limpiar la salida
Memo1.Lines.Clear;// Conectar con la Base de Datos
Con := CreateOleObject('ADODB.Connection');// Abrir
Con.Open(Format(DB_CONNECTION,[DATABASENAME]));// protecciontry// Acceder a la Base de Datos
fCatalog := CoCatalog.Create;
fCatalog._Set_ActiveConnection(Con);// Acceder a la tabla de empleados
Table := fCatalog.Tables['employee'];// recorrer las columnasfor i :=0to(Table.Columns.Count-1)dobegin// Acceder a la columna
Column := Table.Columns[i];// Datos de columna
Memo1.Lines.Add(' ');
Memo1.Lines.Add(Format('Columna: %s',[Column.Name]));
Memo1.Lines.Add('---------------------------------');
Memo1.Lines.Add(Format(' Tamaño: %d',[Column.DefinedSize]));
Memo1.Lines.Add(Format(' Precisión: %d',[Column.Precision]));// recorrer las propiedades de la columnafor j :=0to(Column.Properties.Count-1)dobegin// Cada propiedad, Nombre y valor
Str1 := Column.Properties[j].Name;
Str2 := Column.Properties[j].Value;// Saltamos las propiedades Jet...if(Length(Str1) > 0)thenbegin// Saltar las Jetif(Str1[1] <> 'J')thenbegin
Memo1.Lines.Add(Format(' %s: %s',[Str1, Str2]))end;//ifend;//ifend;// forend;// forfinally// Liberar y cerrar
Column :=nil;
Table :=nil;
fCatalog :=nil;
Con.Close;end;end;
procedure TForm1.Button2Click(Sender: TObject);
const
DB_CONNECTION='Provider=Microsoft.Jet.OLEDB.4.0;' +
'Data Source=%s';
DATABASENAME = 'c:\Archivos de ' +
'programa\Archivos comunes\Borland Shared\Data' +
'\dbdemos.mdb';
var
i, j:Integer;
Con:OleVariant;
fCatalog:Catalog;
Column: _Column;
Table:_Table;
Str1, Str2:string;
begin
// Limpiar la salida
Memo1.Lines.Clear;
// Conectar con la Base de Datos
Con := CreateOleObject('ADODB.Connection');
// Abrir
Con.Open(Format(DB_CONNECTION,[DATABASENAME]));
// proteccion
try
// Acceder a la Base de Datos
fCatalog := CoCatalog.Create;
fCatalog._Set_ActiveConnection(Con);
// Acceder a la tabla de empleados
Table := fCatalog.Tables['employee'];
// recorrer las columnas
for i := 0 to (Table.Columns.Count - 1) do begin
// Acceder a la columna
Column := Table.Columns[i];
// Datos de columna
Memo1.Lines.Add(' ');
Memo1.Lines.Add(Format('Columna: %s',[Column.Name]));
Memo1.Lines.Add('---------------------------------');
Memo1.Lines.Add(Format(' Tamaño: %d',[Column.DefinedSize]));
Memo1.Lines.Add(Format(' Precisión: %d',[Column.Precision]));
// recorrer las propiedades de la columna
for j := 0 to (Column.Properties.Count - 1) do begin
// Cada propiedad, Nombre y valor
Str1 := Column.Properties[j].Name;
Str2 := Column.Properties[j].Value;
// Saltamos las propiedades Jet...
if (Length(Str1) > 0) then begin
// Saltar las Jet
if (Str1[1] <> 'J') then begin
Memo1.Lines.Add(Format(' %s: %s',[Str1, Str2]))
end; //if
end; //if
end; // for
end; // for
finally
// Liberar y cerrar
Column := nil;
Table := nil;
fCatalog := nil;
Con.Close;
end;
end;
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Procedimiento que muestra cómo ordenar un TStringGrid a partir de los datos de una columna. El texto está basado en esta página Web donde hay un algoritmo de ordenación. El problema es que sólo es para datos numéricos. En este truco he añadido un par de parámetros para poder definir columnas de otro tipo (u ordenación de otro tipo) y además marcar si que quiere de forma Ascendente o Descendente (que tampoco está en el truco original).
Yo he añadido métodos para ordenar por enteros y Float, aunque ampliando se pueden añadir para alguno más.
// Ordena un TStringGrid.procedure SortStringGrid(var GenStrGrid: TStringGrid;
ThatCol:Integer;
ColData:TGridData=gdString;
SortOrder:TSortOrder=soASC);const
TheSeparator ='@';var
CountItem, I, J, K, ThePosition:integer;
MyList: TStringList;
MyString, TempString:string;
str:string;
vali:Integer;
valf:Double;begin
CountItem := GenStrGrid.RowCount;
MyList := TStringList.Create;
MyList.Sorted:=False;trybeginfor I :=1to(CountItem -1)dobegin
Str := GenStrGrid.Rows[I].Strings[ThatCol];if(ColData = gdInteger)thenbegin
vali :=StrToIntDef(Str,0);
Str :=Format('%*d',[15,vali]);end;if(ColData = gdFloat)thenbegin
valf :=StrToFloat(Str);
Str :=Format('%15.2f',[valf]);end;
MyList.Add(Str + TheSeparator + GenStrGrid.Rows[I].Text);end;
Mylist.Sort;for K :=1to Mylist.Countdobegin
MyString := MyList.Strings[(K -1)];
ThePosition :=Pos(TheSeparator, MyString);
TempString :='';{Eliminate the Text of the column on which we have
sorted the StringGrid}
TempString :=Copy(MyString,(ThePosition +1),Length(MyString));
MyList.Strings[(K -1)]:='';
MyList.Strings[(K -1)]:= TempString;end;if(SortOrder = soASC)thenbeginfor J :=1to(CountItem -1)dobegin
GenStrGrid.Rows[J].Text:= MyList.Strings[(J -1)];end;endelsebeginfor J :=1to(CountItem -1)dobegin
I :=(CountItem - J);
GenStrGrid.Rows[I].Text:= MyList.Strings[(J -1)];end;end;end;finally
MyList.Free;end;end;
// Ordena un TStringGrid.
procedure SortStringGrid(var GenStrGrid: TStringGrid;
ThatCol: Integer;
ColData:TGridData=gdString;
SortOrder:TSortOrder=soASC);
const
TheSeparator = '@';
var
CountItem, I, J, K, ThePosition: integer;
MyList: TStringList;
MyString, TempString: string;
str:string;
vali:Integer;
valf:Double;
begin
CountItem := GenStrGrid.RowCount;
MyList := TStringList.Create;
MyList.Sorted := False;
try
begin
for I := 1 to (CountItem - 1) do begin
Str := GenStrGrid.Rows[I].Strings[ThatCol];
if (ColData = gdInteger) then begin
vali := StrToIntDef(Str, 0);
Str := Format('%*d', [15,vali]);
end;
if (ColData = gdFloat) then begin
valf := StrToFloat(Str);
Str := Format('%15.2f',[valf]);
end;
MyList.Add(Str + TheSeparator + GenStrGrid.Rows[I].Text);
end;
Mylist.Sort;
for K := 1 to Mylist.Count do begin
MyString := MyList.Strings[(K - 1)];
ThePosition := Pos(TheSeparator, MyString);
TempString := '';
{Eliminate the Text of the column on which we have
sorted the StringGrid}
TempString := Copy(MyString, (ThePosition + 1), Length(MyString));
MyList.Strings[(K - 1)] := '';
MyList.Strings[(K - 1)] := TempString;
end;
if (SortOrder = soASC) then begin
for J := 1 to (CountItem - 1) do begin
GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];
end;
end
else begin
for J := 1 to (CountItem - 1) do begin
I := (CountItem - J);
GenStrGrid.Rows[I].Text := MyList.Strings[(J - 1)];
end;
end;
end;
finally
MyList.Free;
end;
end;
AÑADO: Me falta una cosa.
Además habrá que definir en la unit los dos tipos que se utilizan para la ordenación:
1
2
3
4
5
Type//: Tipo de Dat de la columna por la que queremos ordenar.
TGridData =(gdString, gdInteger, gdFloat);//: Tipos de ordenación.
TSortOrder =(soASC, soDESC);
Type
//: Tipo de Dat de la columna por la que queremos ordenar.
TGridData = (gdString, gdInteger, gdFloat);
//: Tipos de ordenación.
TSortOrder = (soASC, soDESC);
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…