21-03-1998
Cuando consultas la documentación del Delphi, muchas veces te encuentras con la palabra "TString" , por ejemplo el componente Tmemo (el que he usado para hacer el editor de texto) dice que su propiedad lines es del tipo TString, o también el componente TlistBox. Pues estos componentes hacen uso de un objeto llamado TString, que no es más que una lista formada por cadenas de caracteres (string). Se podria decir que es una "especie" de Array (matriz o vector) que contiene cadena, pero que nos permite realizar operaciones con sus elementos. Así que en este capítulo voy a explicaros las operaciones que se pueden hacer con este objeto, y decir que son aplicables a todos los componentes que tengan una propiedad de este tipo. Además como estamos trabajando en un entorno orientado al objeto de verdad, si necesitas almacenar una lista cadenas puedes crear este objeto en memoria sin tener que recurrir a un componente, con lo que ahorras memoria y ganas velocidad entre otras ventajas.
Esta es la lista de las operaciones que se pueden realizar:
Contar el número de elementos | Acceder a un elemento en particular |
Encontrar la posición que ocupa un elemento | Añadir un elemento al final. |
Mover un elemento | Eliminar un elemento |
Copiar una lista entera |
Bueno lo primero es saber como añadir un elemento a una lista. Coloca un
TEdit, un botón, y un TlistBox en un formulario, los encontraras todos en la página
Standard. Al botón pon en su propiedad caption el texto Añadir. Algo así como la imagen
adjunta. Y en el evento OnClick del botón colocaremos un código como el que sigue:
procedure TForm1.Button1Click(Sender:TObject); begin If Edit1.Text <> '' Then ListBox1.Items.Add (Edit1.Text); end; end.
Si quieres saber cuantos elementos hay en tu lista, solo hay que preguntarlo. Sería
una cosa así:
NumeroDeElementos : = ListBox1.Items.Count;
Fijate que devuelve un entero por lo tanto la variable debe de ser del tipo Integer.
Si observas detenidamente los dos ejemplos anteriores, te darás cuenta que los
métodos que he usado son Add, y Count, y que el resto es común. Esto es porque el
componente se llama ListBox1, y tiene entre sus propiedades una llamada Items, la cual es
del tipo TString, y es la que puede manejar la lista, así por lo tanto las operaciones se
deben aplicar a esa propiedad. En el caso de componente Memo la propiedad que es del tipo
TString se llama Lines, entonces la operación para obtener el número de elementos que
tiene un componente de este tipo seria como sigue:
NúmeroDeElementos : = Memo1.Lines.Count;
Para añadir un elemento en una posición determinada se usa el método Insert, un
ejemplo:
ListBox1.Items.Insert (2,'Tercer Elemento');
Con este ejemplo añado un elemento a la tercera posición. Si he dicho tercera posición, no es un error, ya que el primer elemento es el número cero. Por eso en el capítulo anterior para imprimir en contenido del Memo, usaba un bucle desde cero hasta el número de líneas menos una, ya esta última propiedad devuelve el número de elementos contados desde uno.
Si quieres mover un elemento usa el método move, así:
ListBox1.Items.Move (2,4);
Siendo su formato Origen, Destino, el ejemplo nueve el elemento tercero a la posición quinta.
Antes comente que TString era algo así como una Matriz, pues si es "como"
una matriz accedamos a sus elementos por la posoción que ocupa, teniendo en cuenta que el
primer elemento tiene como indice en número cero. Por ejemplo:
Label1.Caption := ListBox1.Items [2];
Este ejemplo copia el tercer elemento a una etiqueta.
Por ahora ha sido facil, pero para borrar un elemento debemos saber cual es su
posiciónl, así estas líneas de código lo hacen. Primero comprobamos si existe el
elemento (cuidado que distingue mayúsculas de minúsculas), en el caso que no exista
devuelve -1, sino devuelve su posición. Si existe procedemos a borrarlo.
If ListBox1.Items.IndexOf ('jorge') > -1 Then
Delete (ListBox1.Items.IndexOf ('jorge');
Con este sistema podemos borrar un elemento, pero si deseamos borrar toda la lista,
usamos el método Clear. Ejemplo:
ListBox1.Items.Clear;
En algún momento te encontraras que necesitas copiar todos los elementos de una lista
a otra. La solución podria ser leer todos los elementos de uno en uno, y grabarlos en la
otra lista, por medio de un bucle. Pero lo más eficaz es copiar la lista entera de una
operación. Por ejemplo:
ListBox2.Items := ListBox1.Items;
Antes os he comentado que cuando buscas un elemento debes tener cuidado con las
mayúsculas y las minúsculas, aqui os muestro un procedimiento que yo uso con frecuencia
para buscar un elemento en una lista sin tener en cuenta las mayúsculas o las
minúsculas:
For I := 0 to ListBox1.Items.Count -1 Do
Begin
If upcase (Micadena) = upcase(listBox1.Items[i] Then
ShowMesage ('Lo he encontrado');
End;
Quizas alguien este pensando que esto todo está bien, pero si trabajo con una lista y
luego no puedo guardarla para usarla más tarde, pues apaga y vamonos. Pues si recordais
el capítulo sobre el editor de texto, vereís que en componente Memo tiene un método
para guardar y cargar texto, pero si te fijas es un método que se aplica a la propiedad
Lines, la cual es un TString, a lo que me lleva que la "abilidad" para
cargar/guardar texto no es caracteristico del componente sino que es heredado del objeto
TString. Así una lista se puede cargar/guardar de la misma manera:
ListBox1.Items.LoadFromFile ('MiLista.txt'); //Para cargar
ListBox1.Items.SaveToFile ('MiLista'); //Para guardar
Todos los ejemplos que he puesto se basan en un componente visual, pero yo he comentado
que la listas pueden ser internas. Así que para crear una lista en memoria debemos crear
el objeto nosotros. así:
MiLista := TStringList.Create;
En cuanto crees la lista todo los métodos anteriores son aplicables normalmente. Por
ejemplo:
MiLista.Add ('Mi elemento');
No te olvides de destruir la lista de la memoria cuando no la necesites:
MiLista.Free;
Por cierto, cuando crees la lista, esta se comporta como una variable en lo que
respecta a ambito de variables. Osea que se declaras la variable en un procedimiento, solo
podras usar esa lista en ese procedimiento, si la declaras a nivel Privado (Private) la
podras usar en toda la unidad. Un ejemplo de una lista que se puede usar en toda una
unidad:
unit feo; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } MiLista : TStringList; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin MiLista := TStringList.Create; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin MiLista.Free; end; end.