Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-01-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Wink Cronómetro y listview

Hola amigos, tengo un problema cuando quiero iniciar un cronómetro en un listview porque quiero que al iniciarse un formulario este en cero, pero cuando aprieto un botón comience la cuenta, y lo que me pasa es que me da los minutos del cual se inició la aplicación al apretar el botón, y este no corre. Otra cosa como hago cuando llegue a tal minuto me cambie el valor de otra columna. Desde ya agradecido enormemente.
Responder Con Cita
  #2  
Antiguo 02-02-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Hola, sigo con esto es que hago lo siguiente

var
inicio : TDateTime;

Procedure TForm1.Create(Sender : TOject);
var
item : TListItem;
begin
inicio := now;
item := ListView1.Add;
item.Caption := 'PC01';
item.SubItems.Add('Libre');
end;


Procedure TForm1.Timer1Timer(Sender : TOject);
var
item : TListItem;
begin
item.SubItems.Add(FormatDataTime('HH:mm:ss', Now - inicio);
end;

y me sale un error en tiempo de ejecución. Pero si agrego ListView1.Add en el evento OnTimer me da el tiempo en cada segundo
Responder Con Cita
  #3  
Antiguo 02-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Código:
Procedure TForm1.Timer1Timer(Sender : TOject);
var 
item : TListItem;
begin
item.SubItems.Add(FormatDataTime('HH:mm:ss', Now - inicio);
end;
Piensa que item: Tlistitem es una variable local, no está realmente creada en memoria, y es más, no está apuntando al ListView que deseas.

La solución, acceder desde el timer al ListView:
Código:
Procedure TForm1.Timer1Timer(Sender : TOject);
begin
  ListView.items[3].SubItems[0] := (FormatDataTime('hh:nn:ss', Now - inicio);
end;
Yo accedo a la fila 3, al primer subitems.

Por cierto, la cadena para formatear la hora, aunque es la más intuitiva, no es la correcta, para mostrar los minutos tienes que poner "nn".


Saludos
Responder Con Cita
  #4  
Antiguo 02-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Cita:
Pero si agrego ListView1.Add en el evento OnTimer
Pregunta: ¿Realmente quieres añadir un SubElemento en cada segundo?
Responder Con Cita
  #5  
Antiguo 03-02-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Gracias por tu respuesta, pero te cuento que sigo teniendo el mismo error que sale que no puedo acceder a una dirección de memoria.
Responder Con Cita
  #6  
Antiguo 04-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Código:
var i, subi:Integer;
begin
i:= 3;
subi:=0;
  if i < ListView1.Items.Count then
  begin
    if subi < ListView1.Items[i].SubItems.Count then
    begin
      ListView1.Items[i].SubItems[subi] := 'Ocupado'
    end
    else
      ShowMessage('no tiene subItems'); // crear el SubItem aqui ???
  end
  else
    ShowMessage ('Elemento no existe'); // crear el Elemento aqui ???
A ver si detectamos la "maldita" direccion

Por otra parte, en Listview1.columns debe haber definido al menos 2 columnas, ( la 0 y 1)

Saludos
Responder Con Cita
  #7  
Antiguo 08-02-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Muchas gracias por tu respuesta . Te cuento que cuando me aparece la hora y hago click en otra parte del ListView, la hora se corta y aparece en donde hice click para seguir con el conteo. Otra cosa, como hago para que solo un subitem tome color ya que todos los subitems lo hacen. Te mando algo de código para que me puedas entender.

procedure TForm1.ListView1ColumnClick(Sender: TObject;
Column: TListColumn);
begin
nSortCol := Column.Index;
ListView1.AlphaSort;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
i : integer;
begin
if ListView1.Selected <> nil then
ListView1.Selected.SubItems[1] := FormatDateTime('hh:nn:ss', Now - inicio);
end;

procedure TForm1.Abrir1Click(Sender: TObject);
begin
inicio:=Now;
Timer1.Enabled := true;
end;

procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
var
i : integer;
begin
for i := 0 to ListView1.Items.Count - 1 do
begin
if ListView1.Items.Item[i].SubItems[0] = 'Libre' then
ListView1.Canvas.Font.Color := RGB(0,120,0);
end;
end;

Muchas gracias. Saludos
Responder Con Cita
  #8  
Antiguo 09-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Holas de nuevo

Cita:
Empezado por juanchi
hago click en otra parte del ListView, la hora se corta y aparece en donde hice click para seguir con el conteo.
De momento me surge una duda, se supone que la hora de inicio será distitnta para cada PC, por tanto, habría que guardarla en "algun sitio" .
Hay varias formas de hacerlo:
- Usando el objeto TObjectList. (vease ayuda de delphi )
- Usando una tabla en la que cada elemento es un registro con información asociada a cada PC.

Yo me quedaria con la primera opción. En cuanto a lo del timer:
Código:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  i : integer;
begin
  for i:=0 to pred(listview1.items.count) do
    if listview1.items[i].subItems[0] <>'Libre' then 
      ListView1.items[i].SubItems[1] := FormatDateTime('hh:nn:ss', Now - DatosPc[i].HoraInicio);
end;
En cuanto a lo de pintar de color, la verdad, no tengo ni idea. Lo primero que me viene a la mente es que los Subitems, son de tipo Tstring, así que no tiene una propiedad Font asociada. Puede que alguien del foro pueda ayudarte.

Saludos
Responder Con Cita
  #9  
Antiguo 12-02-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Hola , te cuento que para la hora tengo una tabla con intervalos de tiempo con valores enteros, y realizo lo siguiente:


procedure TForm1.Timer1Timer(Sender: TObject);
var
i : integer;
v : string;
tiempo : TDateTime;
begin
v := inttostr(Form4.TarifaHasta.AsInteger);
tiempo := strtotime(v);
for i:=0 to pred(listview1.items.count) do
if listview1.items[i].subItems[0] = 'Libre' then
ListView1.Selected.SubItems[1] := FormatDateTime('hh:nn:ss', now -tiempo );
end;

pero no me toma el valor de la tabla, voz que me recomendas. Hasta pronto y gracias por tu paciencia.

Saludos.
Responder Con Cita
  #10  
Antiguo 13-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Cita:
te cuento que para la hora tengo una tabla con intervalos de tiempo con valores enteros
mmm, Usas Bases de datos para el resto del programa ?

Si Usas Bases de datos, es más facil crear un campo HoraInicio (de tipo Date) asociado a cada Pc

Si no Usas Bases de datos, acabo de mirar bien el tipo TlistItem y tiene una propiedad llamada Data aqui se puede guardar un puntero a cualquier cosa, así que puedes crearte un puntero a un registro y guardar ahí la hora de inicio de cada Pc.

Para que veas como va. crea un programa nuevo, metele un Listview, un Boton y un timer con Interval a 1 seg.

Este es mi codigo.
Código:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type TInfo = record       // Tipo Informacion
        Hora : TDateTime;
end;
    TpTInfo = ^TInfo; // Tipo Puntero al tipo Informacion
type
  TForm1 = class(TForm)
    Button1: TButton;
    ListView1: TListView;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var H :TpTInfo;
begin
  with ListView1.items.Add do
  begin
     Caption := 'PC3';
     SubItems.Add('Ocupado');
     SubItems.Add('');
     New(H);
     H^.Hora:=Now;
     Data:= H;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  hora:TDateTime;
  i : integer;
begin
    with ListView1 do
    for i:=0 to pred(items.count) do
      if items[i].subItems[0] <>'Libre' then
      begin
        if Assigned(Items[i].data) then  // me aseguro de que se ha creado el registro
        begin
          hora :=TpTinfo(Items[i].data)^.Hora;
          items[i].SubItems[1] := FormatDateTime('hh:nn:ss', Now - Hora );
        end;
      end;

end;

end.
El ejemplo consiste en que cada vez que pulsas el boton se crea un nuevo elemento y aprovecha la propiedad Data para meter la hora en un registro asociado a cada elemento del Listview. En el registro TInfo podrías guardar toda la información que necesitaras.

Eso si. Todo lo que almacenas en Data, eres tú el que has de liberarlo antes de borrar algun elemento del listview.

Saludos, y espero que alguno de estos métodos te sirva.
_________________________________________________
Sugerencia: escribir el codigo fuente entre [ code] y [ /code] al postearlo en el foro. (sin el espacio que hay despues del corchete [, es mas facil leerlo)

Última edición por Lepe fecha: 13-02-2004 a las 13:16:11.
Responder Con Cita
  #11  
Antiguo 16-02-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Hola
Si uso tablas en el programa, lo que escribiste me sirvió para el tiempo libre, y quiero hacer otra para el prepago, o sea tener en la tabla tiempos de 30, 60, una hora y media, etc, y seleccionar el tiempo adecuado.

Saludos.
Responder Con Cita
  #12  
Antiguo 16-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
No le veo mucho problema, añadiendo en el uses Dateutil, puedes acceder a esta funcion (al menos en delphi 6):
Código:
 H^.HoraInicio:= now;
 H^.HoraFin:=incminute(H^.horainicio, Form4.TarifaHasta.AsInteger);
Para elegir la tarifa correcta, supongo que darás al usuario la opcion en pantalla, con un combo, un LookupCombo, no sé.....

Por cierto, me alegro que el código anterior te sirva para algo

Como te decia, antes de borrar un elemento del Listview, tienes que liberarlo con Dispose(TpTInfo(listview1.items[X].data)). Si hay elementos que no tienen el registro asociado, pues deberás hacer primero la comprobación de si ha sido creado o no.

Saludos
Responder Con Cita
  #13  
Antiguo 16-02-2004
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 24
__cadetill Va por buen camino
Cita:
Empezado por Lepe
... añadiendo en el uses Dateutil ....
Sólo decir, antes de que pregunten, que esta unit pertenece a las RX Lib, por lo que si no las teneis instaladas, os dará un error de compilación
Responder Con Cita
  #14  
Antiguo 16-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Cita:
Empezado por cadetill
Sólo decir, antes de que pregunten, que esta unit pertenece a las RX Lib, por lo que si no las teneis instaladas, os dará un error de compilación
Gracias por la aclaración. Ni yo mismo estaba al corriente

sodulaS
Responder Con Cita
  #15  
Antiguo 17-02-2004
juanchi juanchi is offline
Miembro
 
Registrado: sep 2003
Posts: 56
Poder: 21
juanchi Va por buen camino
Hola de nuevo .
Te cuento que he intentado pero no consigo que los valores enteros de la grilla de un formulario en la cual tengo los tiempos, y al seleccionar uno que los pase al listview como un tiempo decreciente. Gracias.

Saludos.
Responder Con Cita
  #16  
Antiguo 17-02-2004
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Para el tema de la rejilla, es copiado literalmente de la ayuda de delphi, adaptandolo te puede servir:
Código:
var
  i, j: Integer;
  s: string;
begin
  if DBGrid1.SelectedRows.Count>0 then
    with DBGrid1.DataSource.DataSet do
      for i:=0 to DBGrid1.SelectedRows.Count-1 do
      begin
        GotoBookmark(pointer(DBGrid1.SelectedRows.Items[i]));
        for j := 0 to FieldCount-1 do
        begin

          if (j>0) then s:=s+', ';
          s:=s+Fields[j].AsString;
        end;
        Listbox1.Items.Add(s);
        s:= '';
      end;
Cita:
Empezado por juanchi
y al seleccionar uno que los pase al listview como un tiempo decreciente.
No sé si lo he entendido. Creo que quieres restarle X minutos a una hora determinada. Si dispones de las Rusas (RxLib) puedes usar la funcion que posteé antes, pasandole un nº negativo. Si no dispones de ella, tendrías que hacer un cálculo. Sabiendo que una fecha es un nº real, 32723,05671 y que 1 unidad corresponde a 1 dia de tiempo, puedes hacer tu mismo el cálculo para saber: 30 minutos cuantos dias son, y restar ese valor directamente a una fecha dada.

Ahora te toca pensar a ti un poquito

Te aconsejo que te pares a estudiar un poquito el tema de las fechas en delphi, con 10 minutos peleandote, te aclarará muchas dudas.

ShowMessage(Formatdatetime('dd/mm/yyyy hh:nn:ss', now - MiValorDouble)

sodulaS
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 10:03:59.


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
Copyright 1996-2007 Club Delphi