Ahorro de Código
#1
Escrito 21 diciembre 2008 - 05:37
Procedures y With do
me parece que me han hecho un 100% la vida mas facil antes cada ves que necesitaba un codigo lo desarrollaba, ahora solo lo invoco con los procedures y me ahorro mucho codigo tambien con el With Do ..... si alguien sabe como ahorrar mas código alimenten este Hilo creo que será de muchisima utilidad
#2
Escrito 21 diciembre 2008 - 05:38
#3 Guest_Jose Fco_*
Escrito 21 diciembre 2008 - 05:42
Un Saludo.
#4
Escrito 21 diciembre 2008 - 05:42
Bueno una vez que ves la presentación de Egostar para CodeGear con relacion a Action Manayer te das cuenta de que se puede ahorrar no solo codigo si no muchísimo trabajo.
Ademas de que la explicación es muy buena, la idea de programar de esta forma es esplendida.
Saludos
#5
Escrito 21 diciembre 2008 - 05:54
Ejemplo si tengo
1: 20 Form
2: tabla llamada zEjemplo con 5 campos en el Form1 código anterior
Form1.zEjemplo.insert; Form1.zEjemplo.FieldbyName('campo1').asstring:=edit1.text; Form1.zEjemplo.FieldbyName('campo2').asstring:=edit2.text; Form1.zEjemplo.FieldbyName('campo3').asstring:=edit3.text; Form1.zEjemplo.FieldbyName('campo4').asstring:=edit4.text; Form1.zEjemplo.FieldbyName('campo5').asstring:=edit5.text; Form1.zEjemplo.Post;
con el With Do quedaría asi...
With Form1.zEjemplo do begin Insert; FieldbyName('campo1').AsString:edit1.text; FieldbyName('campo2').AsString:edit2.text; FieldbyName('campo3').AsString:edit3.text; FieldbyName('campo4').AsString:edit4.text; FieldbyName('campo5').AsString:edit5.text; Post; end;
y con respecto a los procedure....
tengo:
1 form
5 edits
1 boton nuevo
1 boton guardar
1 boton limpiar
1 boton cancelar
Anteriormente cada ves que necesitaba un código lo desarrollaba ejemplo
Código Nuevo:
edit1.enabled:=true; edit2.enabled:=true; edit3.enabled:=true; edit4.enabled:=true; edit5.enabled:=true; edit1.clear; edit2.clear; edit3.clear; edit4.clear; edit5.clear; edit1.setfocus;
como bien sabemos cada nada necesitamos habilitar y deshabilitar los edits de este formulario y tambien limpiarlo....pero no es muy bueno desarrollar el codigo cada ves que se necesite, yo he cambiado este hábito por declarar en la parte de public procedures
procedure limpiar;
procedure habilitar;
procedure deshabilitar;
despues de {$R *.dfm}
desarrollo cada procedure
y simplemente
cada ves que lo necesite pongo:
habilitar;
limpiar;
edit1.setfocus
en ves de:
edit1.enabled:=true; edit2.enabled:=true; edit3.enabled:=true; edit4.enabled:=true; edit5.enabled:=true; edit1.clear; edit2.clear; edit3.clear; edit4.clear; edit5.clear; edit1.setfocus;
creo que es muchisimo mas facil
#6
Escrito 21 diciembre 2008 - 06:18
#7
Escrito 21 diciembre 2008 - 06:18
1. Emplear procedimientos y funciones cuando se los considere oportuno. Si tras un buen análisis se observan tareas repetitivas, lo mejor es tenerlas en un procedimiento y/o función según sea el caso.
2. Si se debe trabajar muchísimo con un objeto: With ... do. En pocas líneas mejor me lo evito.
3. Si por alguna razón existe alguna variación entre rutinas que comparten alguna similitudes y que se repiten, analizo objetivamente si se puede emplear algun parámetro de tipo bandera, o control que determine que acción realizar. Por ejemplo:
procedure Limpiar(ArrayClase: array of TControlClass; ExceptionList: TObjectList; ... Flag: TFlag);
La idea es que este "Limpiar" pueda ofrecer no sólo las funciones para limpiar uno o varios tipos de controles. Sino que maneje alguna lista de excepciones (por poner ejemplo, deseo limpiar todos los edits excepto xxx) y se puede preveer cualquier parámetros adicional que sea oportuno para el contexto.
4. Nombres de variables simples, y cortas aplicadas al contexto en que se la usan (si el contexto es de una acción, el nombre debe reflejarlo). Yo me he acostumbrado al inglés, se reduce muchos caracteres y armoniza con el lenguaje.
5. Identación clara. Nada de if then, a menos que sea una línea. Evitar en lo posible el anidamiento excesivo de Ifs. En caso de muchos If, analizar si es posible una "conversión" a case. Aplico tablas de verdad a fin de reducir la complejidad de las condiciones y el anidamiento. Por ejemplo:
if Condicion1 then if Condicion2 then
En caso de ser posible, evitarse ese if, es mejor algo como:
if (Condicion1) and (Condicion2) then
6. Separar la lógica de la interfaz. Si bien hay situaciones en que no se puede, lo mejor es reducir el impacto entre ambas capas.
Y si me disculpas un momento, a ese código de limpiar se lo podría reducir si se emplease FindComponents y recorrer la lista en busca de componentes para hallar los componentes de una clase y cuyos nombre tienen un "denominador común".
en el caso de campo1, campo2, se puede hacer algo como:
for i := 1 to 5 do
Form1.ZEjemplo.FieldByName('campo' + IntToStr(i)).AsString := ...
Claro que por 5, no me molesto en hacer algo tan "enrreversado" Pero en un caso de muchos, vale la pena.
Bueno, eso se me ocurre por ahora,
Saludos,
¿Se ve la idea?
#8
Escrito 21 diciembre 2008 - 06:26
Hola, para reducir código yo sigo más o menos estas reglas:
1. Emplear procedimientos y funciones cuando se los considere oportuno. Si tras un buen análisis se observan tareas repetitivas, lo mejor es tenerlas en un procedimiento y/o función según sea el caso.
2. Si se debe trabajar muchísimo con un objeto: With ... do. En pocas líneas mejor me lo evito.
3. Si por alguna razón existe alguna variación entre rutinas que comparten alguna similitudes y que se repiten, analizo objetivamente si se puede emplear algun parámetro de tipo bandera, o control que determine que acción realizar. Por ejemplo:
delphi
procedure Limpiar(ArrayClase: array of TControlClass; ExceptionList: TObjectList; ... Flag: TFlag);
La idea es que este "Limpiar" pueda ofrecer no sólo las funciones para limpiar uno o varios tipos de controles. Sino que maneje alguna lista de excepciones (por poner ejemplo, deseo limpiar todos los edits excepto xxx) y se puede preveer cualquier parámetros adicional que sea oportuno para el contexto.
4. Nombres de variables simples, y cortas aplicadas al contexto en que se la usan (si el contexto es de una acción, el nombre debe reflejarlo). Yo me he acostumbrado al inglés, se reduce muchos caracteres y armoniza con el lenguaje.
5. Identación clara. Nada de if then, a menos que sea una línea. Evitar en lo posible el anidamiento excesivo de Ifs. En caso de muchos If, analizar si es posible una "conversión" a case. Aplico tablas de verdad a fin de reducir la complejidad de las condiciones y el anidamiento. Por ejemplo:
delphi
if Condicion1 then if Condicion2 then
En caso de ser posible, evitarse ese if, es mejor algo como:
delphi
if (Condicion1) and (Condicion2) then
6. Separar la lógica de la interfaz. Si bien hay situaciones en que no se puede, lo mejor es reducir el impacto entre ambas capas.
Y si me disculpas un momento, a ese código de limpiar se lo podría reducir si se emplease FindComponents y recorrer la lista en busca de componentes para hallar los componentes de una clase y cuyos nombre tienen un "denominador común".
en el caso de campo1, campo2, se puede hacer algo como:
for i := 1 to 5 do
Form1.ZEjemplo.FieldByName('campo' + IntToStr(i)).AsString := ...
Claro que por 5, no me molesto en hacer algo tan "enrreversado" Pero en un caso de muchos, vale la pena.
Bueno, eso se me ocurre por ahora,
Saludos,
¿Se ve la idea?
salu2 amigo delphius lo único que no usaba para reducir código con respecto a ti es la parte donde dices :
Código
1.
procedure Limpiar(ArrayClase: array of TControlClass; ExceptionList: TObjectList; ... Flag: TFlag);
La idea es que este "Limpiar" pueda ofrecer no sólo las funciones para limpiar uno o varios tipos de controles. Sino que maneje alguna lista de excepciones (por poner ejemplo, deseo limpiar todos los edits excepto xxx) y se puede preveer cualquier parámetros adicional que sea oportuno para el contexto.
q aunque debe ser facil no la entiendo y se ve super util tener un solo "Limpiar para todos los formularios" siempre y cuando el número de edits se asemeje al de otro formulario
me gustaria que me aclararas eso que acabo de mencionar y pues lo de campo1 campo2 campo3 fue solo un ejemplo pero no creo que alguien llame los campos de la tabla asi ya que no hace referencia a lo que es....... bueno me parece que no ayuda..... por que a la hora de modificar algo te vas a la tabla y ves y piensas que significara ¿campo3? jajajajaja (me pasó bastante tiempo )
#9 Guest_Jose Fco_*
Escrito 21 diciembre 2008 - 06:28
¿Se ve la idea?
Claro Maestro, eso esta perfecto.
Un Saludo.
PD: Un dia sere asi de grande yo tambien.
#10
Escrito 21 diciembre 2008 - 06:31
For i to 5 do begin With Form1.zEjemplo do begin Insert; FieldbyName('Campo1').asstring:=Edit+IntToStr(i).Text; FieldbyName('Campo2').asstring:=Edit+IntToStr(i).Text; FieldbyName('Campo3').asstring:=Edit+IntToStr(i).Text; FieldbyName('Campo4').asstring:=Edit+IntToStr(i).Text; FieldbyName('Campo5').asstring:=Edit+IntToStr(i).Text; Post; end; end;
#11
Escrito 21 diciembre 2008 - 06:36
gracias delphius creo que ese fué el fin del Hilo aprender algo de como Ahorrar Código
#12
Escrito 21 diciembre 2008 - 06:42
un procedure limpiar
con este código
For i:=0 to 10 do begin Edit+IntToStr(i).Clear; end;
en ves de...
Edit1.Clear; Edit2.Clear; Edit3.Clear; Edit4.Clear; Edit5.Clear; Edit6.Clear; Edit7.Clear; Edit8.Clear; Edit9.Clear; Edit10.Clear;
y con Enabled:=True y False y todo lo que se use con los Edits uffffffffffffffffffffff....
#13
Escrito 21 diciembre 2008 - 06:45
var nIdx: Integer; begin for nIdx := 0 to Form1.ComponentCount - 1 do begin if Form1.Components[nIdx] is TEdit then TEdit(Form1.Components[nIdx]).Clear; end; end;
Que creo es más conveniente digo yo
Saludos.
#14
Escrito 21 diciembre 2008 - 06:49
Ese último código no te va a funcionar. No se puede hacer esto:
Edit+IntToStr(i). Se necesita emplear de FindComponent().
Por otro lado el tema del Limpiar con esos parámetros, eso ya es una cuestión de como uno lleva el código. No interesa como se la implementación sino la idea: indicar que tipo de controles limpiar, y en caso de ser necesario: indicarles cuales de esa lista no. Los parámetros "Flags" pueden aportar otros enfoques, y dan un soporte extra al procedimiento.
Son ideas, amigo. No te preocupes por la implementación, sino que comprendas la idea. Hay muchas maneras de concebir esto. Por ejemplo:
procedure Limpiar(Control: string); procedure Limpiar(ArrayControl: array of TControl); procedure Limpiar(ListaDeControles: TObjectList; Excepto: string; ... );
Saludos,
#15
Escrito 21 diciembre 2008 - 07:55
if (Length(Edit1.Text)<1) or (Length(Edit2.Text)<1) or (Length(Edit3.Text)<1) then begin Application.MessageBox('Debe llenar todos los campos informativos',''); exit; end; if (Length(Edit4.Text)<1) and (Length(Edit5.Text)<1) and (Length(Edit6.Text)<1) then begin Application.MessageBox('Debe ingresar al menos 1 Número de teléfono',''); exit; end; With Form1.zAsesores do begin if Locate('cedula',Edit1.Text,[]) then begin Application.MessageBox('Disculpe, está cédula ya fué registrada',''); exit; end else begin Insert; FieldByName('registro').AsString:=DateToStr(Date); FieldByName('cedula').AsString:=Edit1.Text; FieldByName('nombresyapellidos').AsString:=Edit2.Text; FieldByName('direccion').AsString:=Edit3.Text; FieldByName('telefono').AsString:=Edit4.Text; FieldByName('celular').AsString:=Edit5.Text; FieldByName('celular2').AsString:=Edit6.Text; Post; Application.MessageBox('Asesor registrado con éxito!',''); BitBtn4.Click; exit; end; end; Application.MessageBox('Error Grave!',''); exit;
#16
Escrito 21 diciembre 2008 - 07:59
habilitar; limpiar; deshabilitar; BitBtn1.Enabled:=True;
#17
Escrito 21 diciembre 2008 - 09:58
Ummm no veo donde más se lo pueda optimizar. A mi modo de ver, está en su mínima expresión. A menos claro que estructures esas sentencias en procedimientos más chicos. Por ejemplo, esos chequeos iniciales pueden ir en una función Chequear, y dependiendo del valor devuelto seguir con el algoritmo o no. De la misma manera se podría hacer con la parte de inserción del registro.
En fin, eso es ha gusto tuyo, y según te dicte la experiencia. Es un algoritmo simple, y puede que por 35 líneas tal vez no sea útil separarlo en más.
Lo que si es bueno recomendarte, por lo que veo, es que usas ZTable (o algún análogo a Table en Zeos; desconozco Zeos). Es conveniente emplear ZQuery (o el análogo a Query) y valerse de SQL.
No se si he chequeado bien, pero me parece que por la forma en que está escrito el código que siempre recibes el mensaje "Error grave".
Bueno, eso veo yo.
Ha, por cierto mejor sería separar la lógica de la interfaz. Usa DataModules para estructurar mejor tus componentes de base de datos.
Saludos,
#18
Escrito 21 diciembre 2008 - 10:07
Hola lKinGl,
Ummm no veo donde más se lo pueda optimizar. A mi modo de ver, está en su mínima expresión. A menos claro que estructures esas sentencias en procedimientos más chicos. Por ejemplo, esos chequeos iniciales pueden ir en una función Chequear, y dependiendo del valor devuelto seguir con el algoritmo o no. De la misma manera se podría hacer con la parte de inserción del registro.
En fin, eso es ha gusto tuyo, y según te dicte la experiencia. Es un algoritmo simple, y puede que por 35 líneas tal vez no sea útil separarlo en más.
Lo que si es bueno recomendarte, por lo que veo, es que usas ZTable (o algún análogo a Table en Zeos; desconozco Zeos). Es conveniente emplear ZQuery (o el análogo a Query) y valerse de SQL.
No se si he chequeado bien, pero me parece que por la forma en que está escrito el código que siempre recibes el mensaje "Error grave".
Bueno, eso veo yo.
Ha, por cierto mejor sería separar la lógica de la interfaz. Usa DataModules para estructurar mejor tus componentes de base de datos.
Saludos,
me alegra que este programando bien :D, con respecto al error grave solo sucede si no consigue cedula y si no entra en el else....
#19
Escrito 21 diciembre 2008 - 10:09
#20
Escrito 22 diciembre 2008 - 12:08
con respecto a los datamodules..... nunca he sabido como se usa pero yo uso todos los ztables en un solo form que creo que es casi lo mismo
Casi pero no... es mejor hacerlo dentro de un DataModule... creo que yo, por darle a cada componente su uso "correcto", no sé, por ejemplo... de alguna manera un TLabel puede hacer algo similar a un TButton pero no por eso lo reemplazamos cierto ?
Pues un DataModule simplemente es un contenedor de elementos de conexión a la Base de Datos: Tables, Querys, etc... y permite organizarlo mejor creo yo...