Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Recortar un String (https://www.clubdelphi.com/foros/showthread.php?t=53203)

mjjj 13-02-2008 21:59:44

Recortar un String
 
Hola... tengo un pequeño problema

Tengo un Tstringgrid, en donde la columna 2, no quiero que sea mas larga que 50 caracteres. Tengo un codigo que va algo asi.

Código Delphi [-]
if (stringgrid1.Col = 2) then
if length(stringgrid1.Cells[2,stringgrid1.row]) <= 50 then
CharUpperBuff(@Key, 1) else
begin
str:=stringgrid1.Cells[2,stringgrid1.row];
delete(str,51,256);
stringgrid1.Cells[2,stringgrid1.row]:=str;
end;

Pero no funciona... cuando llego al caracter 51 me borra todo el texto

Como lo soluciono??

Gracias

maeyanes 13-02-2008 22:13:48

Hola...

Prueba así:

Código Delphi [-]
if (stringgrid1.Col = 2) then
  if length(stringgrid1.Cells[2, stringgrid1.row]) <= 50 then
    CharUpperBuff(@Key, 1) 
  else
  begin
    str := stringgrid1.Cells[2, stringgrid1.row];
    stringgrid1.Cells[2, stringgrid1.row] := Copy(str, 1, 50);
  end;


Saludos...

mjjj 13-02-2008 22:33:14

hola... sigue sin funcionar... el codigo este lo tengo en el evento presskey del stringgrid, pero no funciona.... es decir se borra todo el texto al llegar al caracter 51.

Se podra hacer de otrea manera??

maeyanes 13-02-2008 22:36:21

Hola...

Y si haces:

Código Delphi [-]
if (stringgrid1.Col = 2) then
  if length(stringgrid1.Cells[2, stringgrid1.row]) <= 50 then
    CharUpperBuff(@Key, 1) 
  else
    Key := #0

mjjj 13-02-2008 22:47:06

tampoco... ya lohabia probado... como el length es igual o mayor a 50... despues de eso se queda pegao... no se puede escribir ni borrar en esa celda....

Alguna otra idea??

muchas gracias por tu tiempo

ixMike 13-02-2008 22:50:13

Cita:

Empezado por mjjj (Mensaje 265671)
tampoco... ya lohabia probado... como el length es igual o mayor a 50... despues de eso se queda pegao... no se puede escribir ni borrar en esa celda....

Alguna otra idea??

muchas gracias por tu tiempo

No funciona porque tampoco acpeta el carácter #8, que es el de borrar. Prueba así:

Código Delphi [-]
if (stringgrid1.Col = 2) then
  if length(stringgrid1.Cells[2, stringgrid1.row]) <= 50 then
    CharUpperBuff(@Key, 1) 
  else
    if key>31 then Key := #0;

No aceptará carácteres, pero sí Enter, Retroceso, Tabulación...



Salu2.

maeyanes 13-02-2008 22:51:42

Hola...

Pues ya solo te quedaría comprobar que tecla se presionó, si es Backspace o Delete por ejemplo, las dejas pasar tal como vienen, si es letra o número o espacio en blanco, los conviertes en caracter nulo (#0)...

La otra es verificar si entre las propiedades de las columnas se puede especificar la longitud máxima de caracteres que puede contener...


Saludos...

mjjj 14-02-2008 00:51:03

gracias ixMike... ahi me funciono... pero surgio otro problema...

si es que pego un string que es mayor que 50 igual me lo escribe...

lo que deberia hacerse... creo yo... es que se deberia cortar si es que el string es mas largo que 50

Alguna idea??

muchas gracias

keyboy 14-02-2008 02:33:04

Te propongo una alternativa que cubriría todos los casos.

En el formulario donde tienes el StringGrid, coloca esta declaración:

Código Delphi [-]
type
  TStringGrid = class(Grids.TStringGrid)
  protected
    function GetEditLimit: Integer; override;
  end;

  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Esto define una clase derivada de TStringGrid que se llama igual. Al colocarla antes de la declaración del formulario, logras que el StringGrid que ahí tienes, sea ahora de la nueva clase.

En dicha nueva clase, lo que hacemos es redefinir el método virtual GetEditLimit. Este método indica cuál es el máximo número de caracteres que acepta una celda del grid. El método original simplemente regresa 0, indicando que no hay límite. Nosotros podemos definirlo para dar distintos valores, según las circunstancias:

Código Delphi [-]
function TStringGrid.GetEditLimit: Integer;
begin
  // Si estamos en la columna 2 ...
  if Col = 2 then
    Result := 50
  else
    Result := inherited GetEditLimit;
end;

Bye

keyboy 14-02-2008 02:48:25

Por cierto, veo que usas el evento KeyPress para convertir a mayúsculas el texto que se escribe. Pero ya entrados en gastos, puedes añadir un método más a la nueva clase:

Código Delphi [-]
  TStringGrid = class(Grids.TStringGrid)
  protected
    function GetEditLimit: Integer; override;
    function CreateEditor: TInplaceEdit; override;
  end;

CreateEditor es el encargado de crear el objeto TEdit que se usa para editar el contenido de una celda. Puedes aprovechar el momento en que se crea para establecer su propiedad CharCase:

Código Delphi [-]
type
  TExInplaceEdit = class(Grids.TInplaceEdit);

function TStringGrid.CreateEditor: TInplaceEdit;
begin
  // Creamos el objeto original
  Result := inherited CreateEditor;

  // Ponemos el objeto creado en mayúsculas
  TExInplaceEdit(Result).CharCase := ecUpperCase;
end;

Lo del TExInplaceEdit es un truco para poder acceder a la propiedad CharCase del TInplaceEdit, ya que está protegida y no puede usarse directamente.

Con esto te ahorras ya todo el evento KeyPress.

Bye

mjjj 14-02-2008 03:03:25

muchas gracias por tu tiempo.... pero tengo un problema me tira un error que dice asi:

[Pascal Error] U_NVAOC.pas(17): E2065 Unsatisfied forward or external declaration: 'TStringGrid.GetEditLimit'

en la linea de "function GetEditLimit: Integer; override;"

en que parte pongo el resto del codigo que me recomendaste?

Código Delphi [-]
function TStringGrid.CreateEditor: TInplaceEdit;
begin
  // Creamos el objeto original
  Result := inherited CreateEditor;

  // Ponemos el objeto creado en mayúsculas  TExInplaceEdit(Result).CharCase := ecUpperCase;
end;

gracias

keyboy 14-02-2008 16:25:01

Te la pongo más fácil:

Crea una nueva unidad, ExStringGrid.pas, con el siguiente código:

Código Delphi [-]
unit ExStringGrid;

interface

uses
  StdCtrls, Grids;

type
  TStringGrid = class(Grids.TStringGrid)
  protected
    function GetEditLimit: Integer; override;
    function CreateEditor: TInplaceEdit; override;
  end;

implementation

type
  TExInplaceEdit = class(Grids.TInplaceEdit);

{ TStringGrid }

function TStringGrid.CreateEditor: TInplaceEdit;
begin
  // Creamos el objeto original
  Result := inherited CreateEditor;

  // Ponemos el objeto creado en mayúsculas
  TExInplaceEdit(Result).CharCase := ecUpperCase;
end;

function TStringGrid.GetEditLimit: Integer;
begin
  // Si estamos en la columna 2 ...
  if Col = 2 then
    Result := 5
  else
    Result := inherited GetEditLimit;
end;

end.

que incluye toda la implementación de la clase derivada.

Luego, en tu formulario principal (o donde tengas el StringGrid), incluye la unidad:

Código Delphi [-]
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, ExStringGrid;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

El único requisito es que ExStringGrid debe aparecer después de la unidad Grids, de lo contrario no funciona.

Bye

mjjj 14-02-2008 18:01:11

gracias keyboy... funciono perfecto, pero ahora surgio otro problema...

justamente no se puede ingresar mas caracteres definidos, ya se tipenando o tratando con copy paste.... pero si es que utilizo otra forma de llenar esta columna si se puede... utilizando este codigo:

Código Delphi [-]
stringgrid1.Cells[2,stringgrid1.rowcount-1]:=ibquery2.FieldByName('nom_insum').AsString;

Como puedo restringir esto tambien??

De ante mano muchas gracias....

Saludos

ixMike 14-02-2008 18:08:28

Cita:

Empezado por mjjj (Mensaje 265906)
gracias keyboy... funciono perfecto, pero ahora surgio otro problema...

justamente no se puede ingresar mas caracteres definidos, ya se tipenando o tratando con copy paste.... pero si es que utilizo otra forma de llenar esta columna si se puede... utilizando este codigo:

Código Delphi [-]stringgrid1.Cells[2,stringgrid1.rowcount-1]:=ibquery2.FieldByName('nom_insum').AsString;


Como puedo restringir esto tambien??

De ante mano muchas gracias....

Saludos

¡¡Si esa es la forma más fácil de controlarlo!! ya que le pasas el dato, pásaselo con longitud 50 ;)

Si ya se diera el caso que no sabes cómo...

Código Delphi [-]
stringgrid1.Cells[2,stringgrid1.rowcount-1]:=Copy(ibquery2.FieldByName('nom_insum').AsString, 1, 50);

Salu2 :)

maeyanes 14-02-2008 18:09:22

Hola...

Para eso mejor hazlo como te indique en mi primera respuesta...

Código Delphi [-]
stringgrid1.Cells[2,stringgrid1.rowcount-1] := Copy(ibquery2.FieldByName('nom_insum').AsString, 1, 50);


Saludos...

Edit: Vaya, me ganaron la respuesta xDDDD

ixMike 14-02-2008 18:11:05

Cita:

Empezado por maeyanes (Mensaje 265911)
Edit: Vaya, me ganaron la respuesta xDDDD

:D:D para destacar hay que ser veloz cual rayo!!! o conseguir uno de esos despertadores/avisadores que tienen los moderadores ;):p

mjjj 15-02-2008 12:51:52

muchas gracias a todos... quedo funcionando tal cual queria

saludos


La franja horaria es GMT +2. Ahora son las 18:36:03.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi