Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Lazarus, FreePascal, Kylix, etc.
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-07-2015
El_Chava El_Chava is offline
Miembro
 
Registrado: jun 2005
Posts: 62
Poder: 13
El_Chava Va por buen camino
Question Marca días inahbiles, periodo vacacional en un calendario stringGrig

Hola amigos esperando que se encuentren bien aquí de nuevo con una situación que espero me puedan ayudar a solucionar y es la siguiente. Estoy desarrollando un calendario de labores en el cual se deben especificar los días inhábiles, así como los 2 periodos vacacionales que se tienes en el año. Para eso lo que hice fue usar stringGrid para cada mes ya el procedimiento de llenar los meses con sus respectivos días y dependiendo del día en que comienzan en la semana ya esta programado el detalle es el siguiente. tengo un popmenu que al dar click sobre algún día del calendario del stringGrid le saldrá la opciones de día inhábil, primer periodo vacacional y segundo periodo vacacional. El detalle aquí es como puedo hacer que al dar click por ejemplo el día inhábil del popmenu me cambie de color esa celda por ejemplo color gris (como se ve en el archivo adjunto). ya que posteriormente de guardara en una base de datos. Espero me puedan ayudar de antemano muchas gracias.
p.d. Estoy usando lazarus y los componentes de calendario no cuenta con multselect por eso opte por usar StringGrid.

Estos son los códigos que he encontrado en el foro y he usado
Evento onDrawCell
Código Delphi [-]
procedure TFrmCalendarioOficial.StrEneroDrawCell(Sender: TObject; aCol,
  aRow: Integer; aRect: TRect; aState: TGridDrawState);
begin
   with TStringGrid(Sender) do
  begin
    if not (gdFixed in aState) then
    begin
      if ((gdSelected in aState) and (Cells[Acol,Arow]<>'')) then
        Canvas.Brush.Color := clHighlight
      else
        Canvas.Brush.Color := clWindow;
      Canvas.FillRect(aRect);
    end;
    Canvas.TextRect(aRect, ACol, ARow, Cells[ACol, ARow]);
  end;
end;
Evento OnMouseDown
Código Delphi [-]

//con este procedimientos de selecciona y se pinta la celda al dar click derecho del ratón para que el usario detecte que día va a marcar como inhábil o periodo vacacional
procedure seleccionar_dia(X, Y: Integer;StrMes:TStringGrid);
var aCol, aRow :integer;
       p:TPoint;
 begin
   with FrmCalendarioOficial do
    begin
     StrMes.MouseToCell(X, Y, aCol, aRow);
     StrMes.Row := aRow;
     StrMes.Col := aCol;
     p := StrMes.ClientToScreen(Point(x,y));
     PopupMenu1.popup(p.x, p.y);
    end;
 end; 

procedure TFrmCalendarioOficial.StrEneroMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  var aCol, aRow :integer;
      p:TPoint;
begin
      if button = mbright then
      seleccionar_dia( X, Y,StrEnero);
end;
Imágenes Adjuntas
Tipo de Archivo: pdf calendariolaborespop4.pdf (78,8 KB, 24 visitas)

Última edición por nlsgarcia fecha: 09-07-2015 a las 18:01:58. Razón: Sintaxis Delphi
Responder Con Cita
  #2  
Antiguo 09-07-2015
Avatar de Neftali
Neftali Neftali is offline
-Germán Estévez-
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 15.318
Poder: 10
Neftali Va camino a la famaNeftali Va camino a la fama
Lo lógico es que guardes el estado de los días en alguna estructura que luego te servirá para almacenarlos.
Cuando seleccionas un día como inhabil, debes almacenarlo en la estructura, al pintar en el StringGrid, sólo debes consultar la estructura para saber qué días pintar de cada color.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 09-07-2015
El_Chava El_Chava is offline
Miembro
 
Registrado: jun 2005
Posts: 62
Poder: 13
El_Chava Va por buen camino
Smile

hola Neftali

Cita:
Lo lógico es que guardes el estado de los días en alguna estructura que luego te servirá para almacenarlos.
Cuando seleccionas un día como inhabil, debes almacenarlo en la estructura, al pintar en el StringGrid, sólo debes consultar la estructura para saber qué días pintar de cada color.
Gracias por tu respuesta. Hasta el momento ya logre que al dar click con el botón izquierdo del mouse seleccionando el día y luego si le da click derecho en el popupmenu selecciona día inábil se ponga del color que hace referencia a los dias inahbiles. el problema es que si en el mismo mes hay otro día inhabil y deseo registrarlo pues me borra la marca del día que ya había marcado como inhabil. así que la pregunta aquí es ¿como mantener la celda con el color asignado sin que se borre? Espero me puedan ayudar a encontrar al solucion. En el archivo adjunto podra ver una imagen del avance.
Imágenes Adjuntas
Tipo de Archivo: pdf calendariolaborespop5.pdf (154,8 KB, 21 visitas)
Responder Con Cita
  #4  
Antiguo 09-07-2015
tmsanchez tmsanchez is offline
Miembro
 
Registrado: mar 2004
Ubicación: Mexico
Posts: 65
Poder: 14
tmsanchez Va por buen camino
HOla, no tengo delphi a la mano, pero ésta es una idea de cómo podría ser:

Guarda la información en un arreglo de dos dimensiones:

Código Delphi [-]
type
  TCalendarioMes = Array[1..7,1..5] of Integer;
var
  enero : TCalendarioMes;

procedure inicializaCalendario;
var
  i,j : Integer;
begin
  for i:= 1 to 7 do
    for j := 1 to 5 do
      enero[i,j] := 0;  // sin asignar
end;

procedure marcaAsignado(fila, columna: Integer);
begin
  enero[fila,columna] := 1;
end;

procedure desmarcaAsignado(fila, columna: Integer);
begin
  enero[fila,columna] := 0;
end;


Cuando selecciones la celda en el grid cambias el estado en el arreglo

Código Delphi [-]
procedure seleccionar_dia(X, Y: Integer;StrMes:TStringGrid);
var
  aCol, aRow :integer;
  p:TPoint;
begin
  with FrmCalendarioOficial do
  begin
    StrMes.MouseToCell(X, Y, aCol, aRow);      
    StrMes.Row := aRow;      
    StrMes.Col := aCol;
    marcaAsignado(aCol,aRow);          
    p := StrMes.ClientToScreen(Point(x,y));
    PopupMenu1.popup(p.x, p.y);
  end;
end;

procedure TFrmCalendarioOficial.StrEneroMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  aCol, aRow :integer;
  p:TPoint;
begin
  if button = mbright then
    seleccionar_dia( X, Y,StrEnero);
end;


Cuando verifiques si se tiene que resaltar consultas el arreglo

Código Delphi [-]
procedure TFrmCalendarioOficial.StrEneroDrawCell(Sender: TObject; aCol,   
  aRow: Integer; aRect: TRect; aState: TGridDrawState);
begin
  with TStringGrid(Sender) do
  begin
    if not (gdFixed in aState) then
    begin       // aqui puedes verificar si esta encendido o asignado
      if ((gdSelected in aState) and (Cells[Acol,Arow]<>'')) then
        Canvas.Brush.Color := clHighlight
      else
        Canvas.Brush.Color := clWindow;
      Canvas.FillRect(aRect);
    end;
  Canvas.TextRect(aRect, ACol, ARow, Cells[ACol, ARow]);
  end;
end;

Última edición por ecfisa fecha: 09-07-2015 a las 23:35:47. Razón: Corregir error WYSIWYG
Responder Con Cita
  #5  
Antiguo 10-07-2015
Avatar de Neftali
Neftali Neftali is offline
-Germán Estévez-
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 15.318
Poder: 10
Neftali Va camino a la famaNeftali Va camino a la fama
Cita:
Empezado por El_Chava Ver Mensaje
...el problema es que si en el mismo mes hay otro día inhabil y deseo registrarlo pues me borra la marca del día que ya había marcado como inhabil. así que la pregunta aquí es ¿como mantener la celda con el color asignado sin que se borre?
Lo que no se es cómo guardas la información de los días inhabiles.
Si marcas 2 días inhabiles en un mes, debes tenerlos almacenados en algún sitio, de forma que luego cuando pintes el grid (en el evento DrawCell) debes consultar esos días y pintarlos.

En el pintado de cada celda del stringgrid se debe hacer una consulta a la estructura, y si la celda que se está dibujando corresponde a un día inhabil, entonces debes pintarla.

¿Cómo se guardan esos días?
¿Qué estructura estás utilizando?
¿Qué función estás utilizando en el OnDrawColumnCell -o similar-?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #6  
Antiguo 10-07-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 9.795
Poder: 27
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola El_Chava.

Como te comenta Neftali todo puede variar según programes la estructuración de los datos.

Te pongo una idea de tantas en que podrías realizarlo. El ejemplo hace uso del mouse tanto para la elección única como múltiple de días y usa un PopupMenu cuyos ítems ponen el día o la selección en día feriado o laboral.

Por la imágen que adjuntaste pareciera que usas 12 StringGrids, el ejemplo usa uno solo (StringGridEnero), pero es muy simple modificarlo para que funcione con los restantes.
Código Delphi [-]
...
type
  TForm1 = class(TForm)
    RadioGroup1: TRadioGroup;
    StringGridEnero: TStringGrid;
    PopupMenu1: TPopupMenu;
    pmiFeriado: TMenuItem;
    pmiLaboral: TMenuItem;
    
    btSave: TButton;
    btReset: TButton;
    btLoad: TButton;
    procedure FormCreate(Sender: TObject);
    procedure PopupItemsClick(Sender: TObject);
    procedure StringGridDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure btSaveClick(Sender: TObject);
    procedure btLoadClick(Sender: TObject);
    procedure btResetClick(Sender: TObject);
  private
    FFileName : string;
    procedure SaveStringGrid(SG: TStringGrid; const aFileName: string);
    procedure LoadStringGrid(SG: TStringGrid; const aFileName: string);
  public
  end;

var
  Form1: TForm1;

implementation

const
  NOPRN     = #144;   // caracter no imprimible, dado la forma de cargarlo que uso (CommaText) 

// Carga unos datos en el StringGrid
procedure IniciarDemo(StringGrid: TStringGrid);
var
  c, r : Integer;
begin
 with StringGrid do
  begin
    FixedCols:= 0;
    FixedRows:= 1;
    ColCount := 7;
    RowCount := 6;
    Options  := Options + [goRangeSelect] - [goEditing];
    for r := 0 to RowCount-1 do Rows[r].QuoteChar:= #0;
    Rows[0].CommaText := 'LUN,MAR,MIE,JUE,VIE,SAB,DOM';
    Rows[1].CommaText := NOPRN+','+NOPRN+','+NOPRN+',1,2,3,4';
    Rows[2].CommaText := '5,6,7,8,9,10,11';
    Rows[3].CommaText := '12,13,14,15,16,17,18';
    Rows[4].CommaText := '19,20,21,22,23,24,25';
    Rows[5].CommaText := '26,27,28,29,30,31,'+NOPRN;
    for r := FixedRows to RowCount -1 do
      for c:= FixedCols to ColCount-1 do
        Objects[c, r] := TObject(False);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FFileName := ExtractFilePath(Application.ExeName)+'enero.dat';
  IniciarDemo(StringGridEnero);
end;

// OnDrawCell, evento asignado a cada StringGrid
procedure TForm1.StringGridDrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
const
  COLORCELL : array[Boolean] of TColor = (clWindow, clGray);
  FLAGS = DT_SINGLELINE or DT_CENTER or DT_VCENTER;
begin
  with TStringGrid(Sender) do
  begin
    if Boolean(Objects[ACol,ARow]) and (Cells[ACol,ARow] <> NOPRN) then
    begin
      Canvas.Brush.Color := COLORCELL[Boolean(Objects[ACol,ARow])];
      Canvas.FillRect(Rect);
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]), -1, Rect, FLAGS);
    end;
  end;
end;

// PopupMenu OnClick (Feriado/Laboral). Asociado a cada StringGrid
procedure TForm1.PopupItemsClick(Sender: TObject);
var
  c,r : Integer;
begin
  with TStringGrid(PopupMenu1.PopupComponent) do
    for c := Selection.Left to Selection.Right do
      for r := Selection.Top to Selection.Bottom do
         Objects[c,r] := TObject(TMenuItem(Sender).MenuIndex = 0);
end;

// Botón Guardar
procedure TForm1.btSaveClick(Sender: TObject);
begin
  SaveStringGrid(StringGridEnero, FFileName);
end;

// Botón Reset
procedure TForm1.btResetClick(Sender: TObject);
begin
  IniciarDemo(StringGridEnero);
end;

// Botón Cargar
procedure TForm1.btLoadClick(Sender: TObject);
begin
  LoadStringGrid(StringGridEnero, FFileName);
end;

// Guardar StringGrid
procedure TForm1.SaveStringGrid(SG: TStringGrid; const aFileName: string);
var
  c, r: Integer;
  d: Byte;
  b: Boolean;
begin
  with TFileStream.Create(aFileName, fmCreate) do
  try
    for c := SG.FixedCols to SG.ColCount-1 do
      for r := SG.FixedRows to SG.RowCount-1 do
      begin
        d := StrToIntDef(SG.Cells[c, r], 0);
        WriteBuffer(d, SizeOf(Byte));
        b := Boolean(SG.Objects[c, r]);
        WriteBuffer(b, SizeOf(Boolean));
      end;
  finally
    Free;
  end;
end;

// Cargar StringGrid
procedure TForm1.LoadStringGrid(SG: TStringGrid; const aFileName: string);
var
  c, r: Integer;
  d: Byte;
  b: Boolean;
begin
  with TFileStream.Create(aFileName, fmOpenRead) do
  try
    for c := SG.FixedCols to SG.ColCount-1 do
      for r := SG.FixedRows to SG.RowCount-1 do
      begin
        ReadBuffer(d, SizeOf(Byte));
        if d = 0 then
          SG.Cells[c, r] := NOPRN
        else
          SG.Cells[c,r] := IntToStr(d);
        ReadBuffer(b, Sizeof(Boolean));
        SG.Objects[c, r] := TObject(b);
      end;
  finally
    Free;
  end;
end;

Muestra:


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 10-07-2015
El_Chava El_Chava is offline
Miembro
 
Registrado: jun 2005
Posts: 62
Poder: 13
El_Chava Va por buen camino
Talking

Hola ecfisa, Neftali y tmsanchez primeramente muchas gracias por responder. Al fin logre lo que quería hacer y era que por el momento solo me marcaran los días en el stringGrid antes de guardarlos en la base de datos.Investigando por la red(y claro en el foro) encontre ejemplos y los adapte a los requerimientos que necesitaba Les dejo el código espero le sean de utilidad. Saludos.

procedimientos
Código:
procedure seleccionar_dia(X, Y: Integer;StrMes:TStringGrid);
var aCol, aRow :integer;
       p:TPoint;
 begin
   with FrmCalendarioOficial do
    begin
     StrMes.MouseToCell(X, Y, aCol, aRow);
     StrMes.Row := aRow;
     StrMes.Col := aCol;
     p := StrMes.ClientToScreen(Point(x,y));
     PopupMenu1.popup(p.x, p.y);
    end;
 end;
 
procedure celda_seleccionada(Sender: TObject);
var
  aRect:TRect;
begin
    with TStringGrid(sender) do
    begin
     aRect:= CellRect(Col,Row);
       if Cells[Col,Row]<>'' then
      begin
        Objects[Col, Row] := TObject(clSilver);
        Canvas.Brush.Color := TColor(Objects[Col, Row]);
        Canvas.FillRect(aRect);
        Canvas.Font.Color := clBlack;
        Canvas.TextOut(aRect.Left+2, aRect.Top+2, Cells[Col, Row]);
      end;
    end;
end;
En el evento OnCreate del formulario
Código:
 
procedure TFrmCalendarioOficial.FormCreate(Sender: TObject);
var
  c, f: Integer;
begin
  with StrEnero do
  begin
    for c := FixedCols to ColCount-1 do
      for f := FixedRows to RowCount-1 do
      begin
        Objects[c, f]:= TObject(clWhite); // color por defecto
      end;
  end;
end;
En el evento OnDrawCell del StringGrid
Código:
 
procedure TFrmCalendarioOficial.StrEneroDrawCell(Sender: TObject; aCol,
  aRow: Integer; aRect: TRect; aState: TGridDrawState);
begin
  with TStringGrid(Sender) do
  begin
    if (ARow >= FixedRows) then
    begin
     if ((gdSelected in aState) and (Cells[Acol,Arow]<>'')) then
        Canvas.Brush.Color := clHighlight
     else
      Canvas.Brush.Color := TColor(Objects[ACol, ARow]);
      Canvas.FillRect(aRect);
      Canvas.Font.Color := clBlack;
      Canvas.TextOut(aRect.Left+2, aRect.Top+2, Cells[ACol, ARow]);
    end;
  end;
end;
En el evento MouseDown del StringGrid
Código:
 
procedure TFrmCalendarioOficial.StrEneroMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  var aCol, aRow :integer;
      p:TPoint;
begin
   with TStringGrid(Sender) do
    begin
      MouseToCell(X, Y, ACol, ARow);
     case Button of
       // mbLeft :seleccionar_dia( X, Y,StrEnero);
        mbRight:  seleccionar_dia( X, Y,StrEnero);
      end;
    end;
end;
en el popupmenu al seleccionar Día inhábil
Código:
 
procedure TFrmCalendarioOficial.MenudiainhabilClick(Sender: TObject);
begin
 if strEnero.Focused then
  celda_seleccionada(StrEnero);
end;
Resultado
Responder Con Cita
  #8  
Antiguo Hace 2 Días
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 78
Poder: 2
Soa Pelaez Va por buen camino
Podrías subir tu proyecto o el formulario donde hiciste eso, estoy necesitando algo parecido, te agradecería que me colaboraras. Gracias.

Última edición por Casimiro Notevi fecha: Hace 2 Días a las 22:22:33.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Validar Calendario Días Habiles mantraxer21 Varios 2 05-11-2014 21:27:29
diferencia de dias , suponiendo que los meses son de 30 dias. ingabraham Varios 30 12-09-2010 22:37:48
Sumar Columna en StringGrig carlosh2006 Varios 2 28-08-2007 03:23:53
Titulos en StringGrig CamiloU OOP 3 09-02-2006 01:07:56
Calendario. fecha de noviembre 2005 me pone 31 dias y a diciembre 30 sakuragi PHP 2 21-11-2005 18:39:59


La franja horaria es GMT +2. Ahora son las 05:19:04.


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