Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Vardiya Planlama
#1
Merhaba, 
Üretim planlaması oluşturmak istiyorum. Vardiya zaman aralıkları şu şekildedir.1. vardiya 00:00:00 - 08:00:00 arası, 2. vardiya 08:00:00 - 16:00:00 arası,  3. vardiya 16:00:00 - 00:00:00 arası. Programda seçtiğim Başlangıç tarih ve saati ile bitiş tarih ve saati arasında bir kaç günlük fark olabilir. Örneğin 16.08.2023 09:00:00 ile 17.08.2023 18:00:00 arası tarihleri dateedit ve timeedit yardımıyla seçmiş olalım. Planı oluştur butonuna bastığımda aşağıdaki verilerin aynısı gibi memoya çıktı almak istiyorum.

Memonun ilk satırına "BaslangicTarihi": 16.08.2023 09:00:00, "BitisTarihi":16:08:2023 16:00:00, "Vardiya":2
Memonun ikinci satırına "BaslangicTarihi": 16.08.2023 16:00:00, "BitisTarihi":17:08:2023 00:00:00, "Vardiya":3
Memonun üçüncü satırına "BaslangicTarihi": 17.08.2023 00:00:00, "BitisTarihi":17:08:2023 08:00:00, "Vardiya":1
Memonun dördüncü satırına "BaslangicTarihi": 17.08.2023 08:00:00, "BitisTarihi":17:08:2023 16:00:00, "Vardiya":2
Memonun beşinci satırına "BaslangicTarihi": 17.08.2023 16:00:00, "BitisTarihi":17:08:2023 18:00:00, "Vardiya":3

Mantık şu şekilde ilk kaydın bitiş vardiya saati, bir sonraki kaydın başlangıç saati şeklinde tarih aralığına göre ilerlemesi gerekiyor. 3-4 gündür bununla uğraşıyorum. Chatgpt ye bile izah ettim anlaşamadık Smile 

Yardımcı olabilirseniz sevinirim. Teşekkürler.
Cevapla
#2
Selamlar
Öncelikle başlangıç ve bitiş tarih ve saaterinin olduğu datetime alanlarına +1 koyarak döngü ile, bitiş tarihine kadar dönerek memoya insert etmen gerek.
Örneğin :
for i := 0 to n
begin
memo1.lines.add ('Başlangıç Tarihi :' + datetostr(datetimebaslangic.date) + timetostr(datetimebaslangic.time) + '-' + datetostr(datetimebitis.date) + timetostr(datetimebitis.time) );
end;
// n olan yer için olmasa öncelikle bir değişkene toplan gün sayısını koy.
ChatgPT ye gerek yok. Çok basit bir şekilde yapabilirsin. Minik te olsa yolunu gösterdim. Bundan sonrası sende Smile
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#3
(17-08-2023, Saat: 15:00)shooterman Adlı Kullanıcıdan Alıntı: Selamlar
Öncelikle başlangıç ve bitiş tarih ve saaterinin olduğu datetime alanlarına +1 koyarak döngü ile, bitiş tarihine kadar dönerek memoya insert etmen gerek.
Örneğin :
for i := 0 to n
begin
memo1.lines.add ('Başlangıç Tarihi :' + datetostr(datetimebaslangic.date) + timetostr(datetimebaslangic.time) + '-' + datetostr(datetimebitis.date) + timetostr(datetimebitis.time) );
end;
// n olan yer için olmasa öncelikle bir değişkene toplan gün sayısını koy.
ChatgPT ye gerek yok. Çok basit bir şekilde yapabilirsin. Minik te olsa yolunu gösterdim. Bundan sonrası sende Smile

Valla ne while ne for döngülerini kullanmadığım kaldı ama bir türlü anlattığım senaryoda sonucu elde edemiyorum. En son şunu denedim ama yine de olmadı, son çare buraya yazdım. Bu tarih saatlerden çektiğim kadar hiç bir şeyden çekmedim zaten

procedure TForm1.Button2Click(Sender: TObject);
var
  BaslangicTarihi: TDateTime;
  BitisTarihi: TDateTime;
  BaslangicSaati: TTime;
  BitisSaati: TTime;
  Vardiya: Integer;
  MemoText: string;
begin
  BaslangicTarihi := StartDateEdit.Date;
  BitisTarihi := EndDateEdit.Date;
  BaslangicSaati := StartTimeEdit.Time;
  BitisSaati := EndTimeEdit.Time;



  while BaslangicTarihi + BaslangicSaati <= BitisTarihi + BitisSaati do
  begin
    if (BaslangicTarihi + BaslangicSaati >= BaslangicTarihi + EncodeTime(0, 0, 0, 0)) and
       (BaslangicTarihi + BaslangicSaati < BaslangicTarihi + EncodeTime(8, 0, 0, 0)) then
      Vardiya := 1 // 1. vardiya
    else if (BaslangicTarihi + BaslangicSaati >= BaslangicTarihi + EncodeTime(8, 0, 0, 0)) and
            (BaslangicTarihi + BaslangicSaati < BaslangicTarihi + EncodeTime(16, 0, 0, 0)) then
      Vardiya := 2 // 2. vardiya
    else
      Vardiya := 3; // 3. vardiya


      Memo1.Lines.Add(DateTimeToStr(BaslangicTarihi + BaslangicSaati)+', '+DateTimeToStr(BaslangicTarihi + BitisSaati)+', Vardiya:'+IntToStr(Vardiya));


    BaslangicTarihi := BaslangicTarihi + 1; 
    BaslangicSaati := BitisSaati;
  end;


end;
Cevapla
#4
(17-08-2023, Saat: 15:05)emrahozten Adlı Kullanıcıdan Alıntı:
(17-08-2023, Saat: 15:00)shooterman Adlı Kullanıcıdan Alıntı: Selamlar
Öncelikle başlangıç ve bitiş tarih ve saaterinin olduğu datetime alanlarına +1 koyarak döngü ile, bitiş tarihine kadar dönerek memoya insert etmen gerek.
Örneğin :
for i := 0 to n
begin
memo1.lines.add ('Başlangıç Tarihi :' + datetostr(datetimebaslangic.date) + timetostr(datetimebaslangic.time) + '-' + datetostr(datetimebitis.date) + timetostr(datetimebitis.time) );
end;
// n olan yer için olmasa öncelikle bir değişkene toplan gün sayısını koy.
ChatgPT ye gerek yok. Çok basit bir şekilde yapabilirsin. Minik te olsa yolunu gösterdim. Bundan sonrası sende Smile

Valla ne while ne for döngülerini kullanmadığım kaldı ama bir türlü anlattığım senaryoda sonucu elde edemiyorum. En son şunu denedim ama yine de olmadı, son çare buraya yazdım. Bu tarih saatlerden çektiğim kadar hiç bir şeyden çekmedim zaten

procedure TForm1.Button2Click(Sender: TObject);
var
  BaslangicTarihi: TDateTime;
  BitisTarihi: TDateTime;
  BaslangicSaati: TTime;
  BitisSaati: TTime;
  Vardiya: Integer;
  MemoText: string;
begin
  BaslangicTarihi := StartDateEdit.Date;
  BitisTarihi := EndDateEdit.Date;
  BaslangicSaati := StartTimeEdit.Time;
  BitisSaati := EndTimeEdit.Time;



  while BaslangicTarihi + BaslangicSaati <= BitisTarihi + BitisSaati do
  begin
    if (BaslangicTarihi + BaslangicSaati >= BaslangicTarihi + EncodeTime(0, 0, 0, 0)) and
       (BaslangicTarihi + BaslangicSaati < BaslangicTarihi + EncodeTime(8, 0, 0, 0)) then
      Vardiya := 1 // 1. vardiya
    else if (BaslangicTarihi + BaslangicSaati >= BaslangicTarihi + EncodeTime(8, 0, 0, 0)) and
            (BaslangicTarihi + BaslangicSaati < BaslangicTarihi + EncodeTime(16, 0, 0, 0)) then
      Vardiya := 2 // 2. vardiya
    else
      Vardiya := 3; // 3. vardiya


      Memo1.Lines.Add(DateTimeToStr(BaslangicTarihi + BaslangicSaati)+', '+DateTimeToStr(BaslangicTarihi + BitisSaati)+', Vardiya:'+IntToStr(Vardiya));


    BaslangicTarihi := BaslangicTarihi + 1; 
    BaslangicSaati := BitisSaati;
  end;


end;
Pc başına geçeyim, az sonra bakıcam kodlamaya, yapabilirsem hemen bir örnek göndereyim size
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#5
(17-08-2023, Saat: 15:11)shooterman Adlı Kullanıcıdan Alıntı:
(17-08-2023, Saat: 15:05)emrahozten Adlı Kullanıcıdan Alıntı: Valla ne while ne for döngülerini kullanmadığım kaldı ama bir türlü anlattığım senaryoda sonucu elde edemiyorum. En son şunu denedim ama yine de olmadı, son çare buraya yazdım. Bu tarih saatlerden çektiğim kadar hiç bir şeyden çekmedim zaten

procedure TForm1.Button2Click(Sender: TObject);
var
  BaslangicTarihi: TDateTime;
  BitisTarihi: TDateTime;
  BaslangicSaati: TTime;
  BitisSaati: TTime;
  Vardiya: Integer;
  MemoText: string;
begin
  BaslangicTarihi := StartDateEdit.Date;
  BitisTarihi := EndDateEdit.Date;
  BaslangicSaati := StartTimeEdit.Time;
  BitisSaati := EndTimeEdit.Time;



  while BaslangicTarihi + BaslangicSaati <= BitisTarihi + BitisSaati do
  begin
    if (BaslangicTarihi + BaslangicSaati >= BaslangicTarihi + EncodeTime(0, 0, 0, 0)) and
       (BaslangicTarihi + BaslangicSaati < BaslangicTarihi + EncodeTime(8, 0, 0, 0)) then
      Vardiya := 1 // 1. vardiya
    else if (BaslangicTarihi + BaslangicSaati >= BaslangicTarihi + EncodeTime(8, 0, 0, 0)) and
            (BaslangicTarihi + BaslangicSaati < BaslangicTarihi + EncodeTime(16, 0, 0, 0)) then
      Vardiya := 2 // 2. vardiya
    else
      Vardiya := 3; // 3. vardiya


      Memo1.Lines.Add(DateTimeToStr(BaslangicTarihi + BaslangicSaati)+', '+DateTimeToStr(BaslangicTarihi + BitisSaati)+', Vardiya:'+IntToStr(Vardiya));


    BaslangicTarihi := BaslangicTarihi + 1; 
    BaslangicSaati := BitisSaati;
  end;


end;
Pc başına geçeyim, az sonra bakıcam kodlamaya, yapabilirsem hemen bir örnek göndereyim size

Şimdiden teşekkür ederim.
Cevapla
#6
unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, dateutils;

type
 TForm1 = class(TForm)
   DateTimePicker1: TDateTimePicker;
   DateTimePicker2: TDateTimePicker;
   DateTimePicker3: TDateTimePicker;
   DateTimePicker4: TDateTimePicker;
   Memo1: TMemo;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i, gun : integer;
begin
gun := DaysBetween(DateTimePicker1.date, DateTimePicker3.date);
for I := 1 to gun do
 memo1.lines.Add(datetostr(datetimepicker1.Date + i));
end;

end.

(17-08-2023, Saat: 15:38)shooterman Adlı Kullanıcıdan Alıntı: unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, dateutils;

type
 TForm1 = class(TForm)
   DateTimePicker1: TDateTimePicker;
   DateTimePicker2: TDateTimePicker;
   DateTimePicker3: TDateTimePicker;
   DateTimePicker4: TDateTimePicker;
   Memo1: TMemo;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i, gun : integer;
begin
gun := DaysBetween(DateTimePicker1.date, DateTimePicker3.date);
for I := 1 to gun do
 memo1.lines.Add(datetostr(datetimepicker1.Date + i));
end;

end.

Saatleri koymadım bir de yazılar. Sen onları da memoadd stringine eklersin. 1 satırlar işlem bitiyor gördüğün üzereWink


Ek Dosyalar Resimler
   
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#7
(17-08-2023, Saat: 15:38)shooterman Adlı Kullanıcıdan Alıntı: unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, dateutils;

type
 TForm1 = class(TForm)
   DateTimePicker1: TDateTimePicker;
   DateTimePicker2: TDateTimePicker;
   DateTimePicker3: TDateTimePicker;
   DateTimePicker4: TDateTimePicker;
   Memo1: TMemo;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i, gun : integer;
begin
gun := DaysBetween(DateTimePicker1.date, DateTimePicker3.date);
for I := 1 to gun do
 memo1.lines.Add(datetostr(datetimepicker1.Date + i));
end;

end.

(17-08-2023, Saat: 15:38)shooterman Adlı Kullanıcıdan Alıntı: unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, dateutils;

type
 TForm1 = class(TForm)
   DateTimePicker1: TDateTimePicker;
   DateTimePicker2: TDateTimePicker;
   DateTimePicker3: TDateTimePicker;
   DateTimePicker4: TDateTimePicker;
   Memo1: TMemo;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i, gun : integer;
begin
gun := DaysBetween(DateTimePicker1.date, DateTimePicker3.date);
for I := 1 to gun do
 memo1.lines.Add(datetostr(datetimepicker1.Date + i));
end;

end.

Saatleri koymadım bir de yazılar. Sen onları da memoadd stringine eklersin. 1 satırlar işlem bitiyor gördüğün üzereWink


İş bu kadar kolay olsa keşke. While ve forlar ile işi beceremeyince ki kafamı daha fazla yormayıp amelelik yapmayı tercih ettim. Aşağıdaki kodu çalıştırdığınızda tam da istediğim sonucu alıyorum Smile  Ama kesinlikle doğru yöntem değil, daha basit yolu muhakkak olmalı.

procedure TForm1.Button3Click(Sender: TObject);

var
  BaslangicTarihi: TDateTime;
  BitisTarihi: TDateTime;
  BaslangicSaati: TTime;
  BitisSaati: TTime;
  Saatler: array of TTime;
  Tarih: TDateTime;
  Saat: TTime;
  i, gun: Integer;
  MemoText: string;
  vardiya: Integer;
begin
  BaslangicTarihi := StartDateEdit.Date;
  BitisTarihi := EndDateEdit.Date;
  BaslangicSaati := StartTimeEdit.Time;
  BitisSaati := EndTimeEdit.Time;
  SetLength(Saatler, 3);
  gun:=DaysBetween(BitisTarihi,BaslangicTarihi);
  if (BaslangicSaati >= EncodeTime(8,0,0,0)) and (BaslangicSaati <= EncodeTime(16,0,0,0)) then
  begin
  Saatler[0] := EncodeTime(16, 0, 0, 0);  // 16:00:00
  Saatler[1] := EncodeTime(23, 59, 59, 0);   // 00:00:00
  Saatler[2] := EncodeTime(8, 0, 0, 0);   // 08:00:00
  vardiya:=2;
  end;
  if (BaslangicSaati >= EncodeTime(16,0,0,0)) and (BaslangicSaati <= EncodeTime(23,59,59,0)) then
  begin
  Saatler[2] := EncodeTime(16, 0, 0, 0);  // 16:00:00
  Saatler[0] := EncodeTime(23, 59, 59, 0);   // 00:00:00
  Saatler[1] := EncodeTime(8, 0, 0, 0);   // 08:00:00
  vardiya:=3;
  end;
  if (BaslangicSaati >= EncodeTime(0,0,0,0)) and (BaslangicSaati <= EncodeTime(8,0,0,0)) then
  begin
  Saatler[1] := EncodeTime(16, 0, 0, 0);  // 16:00:00
  Saatler[2] := EncodeTime(23, 59, 59, 0);   // 00:00:00
  Saatler[0] := EncodeTime(8, 0, 0, 0);   // 08:00:00
  vardiya:=1;
  end;


  Memo1.Clear; // Memonun içeriğini temizle



      Tarih := BaslangicTarihi;
      Saat := Saatler[0];
      if vardiya = 2 then
      begin
        if (gun=0) and (BitisSaati<=Saat) then  // vardiya 2 den bir sonraki vardiyaya sarkmıyorsa
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=0) and (BitisSaati>Saat) then  // vardiya 2 den bir sonraki vardiyaya sarkıyorsa
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), TimeToStr(saat), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(Saat), DateToStr(Tarih), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati=StrToTime('00:00:00'))  then // bitiş saati 00:00:00 a eşitse
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati>StrToTime('00:00:00')) and (BitisSaati<StrToTime('08:00:00')) then //bitiş saati 1. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya-2;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati=StrToTime('08:00:00'))  then //bitiş saati 08:00:00 a eşitse
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya-2;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati>StrToTime('08:00:00')) and (BitisSaati<StrToTime('16:00:00'))  then  //bitiş saati 2. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya-2;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '08:00:00', DateToStr(Tarih+1), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati=StrToTime('16:00:00'))   then  //bitiş saati 16:00:00 a eşit ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya-2;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '08:00:00', DateToStr(Tarih+1), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati>StrToTime('16:00:00')) and (BitisSaati<StrToTime('23:59:59'))   then  //bitiş saati 3. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya-2;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '08:00:00', DateToStr(Tarih+1), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '16:00:00', DateToStr(Tarih+1), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;
         exit;
      end;

      if vardiya = 3 then
      begin
        if (gun=0) and (BitisSaati<=Saat) then  // vardiya 3 den bir sonraki vardiyaya sarkmıyorsa
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati=StrToTime('00:00:00'))  then // bitiş saati 00:00:00 a eşitse
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati>StrToTime('00:00:00')) and (BitisSaati<StrToTime('08:00:00')) then //bitiş saati 1. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya-2;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '00:00:00', DateToStr(Tarih+1), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati=StrToTime('08:00:00'))  then //bitiş saati 08:00:00 a eşitse
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya-2;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati>StrToTime('08:00:00')) and (BitisSaati<StrToTime('16:00:00'))   then //bitiş saati 2. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya-2;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '08:00:00', DateToStr(Tarih+1), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati=StrToTime('16:00:00'))   then //bitiş saati 16:00:00 a eşit ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya-2;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '08:00:00', DateToStr(Tarih+1), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=1) and (BitisSaati>StrToTime('16:00:00')) and (BitisSaati<StrToTime('23:59:59'))   then //bitiş saati 3. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih+1), '00:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya-2;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '00:00:00', DateToStr(Tarih+1), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '08:00:00', DateToStr(Tarih+1), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih+1), '16:00:00', DateToStr(Tarih+1), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;
      end;

      if vardiya = 1 then
      begin
        if (gun=0) and (BitisSaati<=Saat)  then  // vardiya 1 den bir sonraki vardiyaya sarkmıyorsa
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=0) and (BitisSaati>StrToTime('08:00:00')) and (BitisSaati<=StrToTime('16:00:00')) then //bitiş saati 2. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '08:00:00', DateToStr(Tarih), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;

        if (gun=0) and (BitisSaati>StrToTime('16:00:00')) and (BitisSaati<=StrToTime('23:59:59')) then //bitiş saati 3. vardiyada ise
        begin
          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), TimeToStr(BaslangicSaati), DateToStr(Tarih), '08:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

         vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '08:00:00', DateToStr(Tarih), '16:00:00', IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);

        vardiya:=vardiya+1;

          MemoText := Format('"BaslangicTarihi": %s %s, "BitisTarihi": %s %s, "Vardiya": %s',
          [DateToStr(Tarih), '16:00:00', DateToStr(Tarih), TimeToStr(BitisSaati), IntToStr(vardiya)]);
        Memo1.Lines.Add(MemoText);
        end;
      end;

end;

Cevapla
#8
Merhaba.

Bu kadar çabaya anlaşılır olmaya gayret ederek kısa bir çözüm sunmaya çalışayım. 
Eğer işinizi görüyorsa ne ala.

Öneri, önce en yakın vardiya saatine kilitlenirseniz çözüm kendiliğinden gelecektir... 
Başarılar.



Uses System.DateUtils;

type
  tVardiya = record
    BasSaat   : TTime;
    SureSaat  : Word;
  end;
  tVardList = array of tVardiya;

function VardiyaHesapla( aStart, aEnd: TDateTime ): string;
var
  i : Integer;
  LVardList : tVardList;
begin
  setLength( LVardList, 3 );

  // Vardiya aralıklarını belirledik.
  LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
  LVardList[0].SureSaat := 8;

  LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
  LVardList[1].SureSaat := 8;

  LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
  LVardList[2].SureSaat := 8;

  // önce başlama tarih/saatini en yakın vardiyaya kilitleyelim...
  // frac() fonksiyonu date time için time kısmını verir.
  if frac(aStart) >= LVardList[2].BasSaat then aStart := Int(aStart) + LVardList[2].BasSaat
  else
  if frac(aStart) >= LVardList[1].BasSaat then aStart := Int(aStart) + LVardList[1].BasSaat
  else
    aStart := Int(aStart) + LVardList[0].BasSaat;

  while aStart <= aEnd do
  begin
    i := Low(LVardList);
    while i <= High(LVardList) do
    begin
      if FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', aStart) then
      begin
 
        Result := Result
                + sLineBreak
                + Format('Vardiya No. %d Başlama : %s Bitiş : %s', [
                      i+1
                    , FormatDateTime('DD.MM.YYYY HH.nn.SS', aStart)
                    , FormatDateTime('DD.MM.YYYY HH.nn.SS', IncHour(aStart, LVardList[i].SureSaat) )
                    ]);

        aStart := IncHour(aStart, LVardList[i].SureSaat);
        i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
      end;
      inc(i);
    end;
  end;

  finalize(LVardList);

end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Memo1.Lines.Text := VardiyaHesapla(   StartDateEdit.Date  + StartTimeEdit.Time
                                      , EndDateEdit.Date    + EndTimeEdit.Time
                                      );

end;



f0lf1rfbvhq7oiorblfk.gif



Record Tipinin ne işe yaradığına başka örnek için belki lazım olabilir diye yatırım diyelim.

3 Vardiya için

 // Vardiya aralıklarını belirledik.
 LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
 LVardList[0].SureSaat := 8;

 LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
 LVardList[1].SureSaat := 8;

 LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
 LVardList[2].SureSaat := 8;
verince sonuç şu oluyorken :

Vardiya No. 2 Başlama : 16.08.2023 08.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 3 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 3 Başlama : 17.08.2023 16.00.00 Bitiş : 18.08.2023 00.00.00


Aşağıdaki gibi farklı aralıklı saatlik çalışma dilimleri için örnek

 // Vardiya aralıklarını belirledik.
 LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
 LVardList[0].SureSaat := 8;

 LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
 LVardList[1].SureSaat := 3;

 LVardList[2].BasSaat  := EncodeTime(11, 00, 00, 00);
 LVardList[2].SureSaat := 1;

 LVardList[3].BasSaat  := EncodeTime(12, 00, 00, 00);
 LVardList[3].SureSaat := 1;

 LVardList[4].BasSaat  := EncodeTime(13, 00, 00, 00);
 LVardList[4].SureSaat := 3;

 LVardList[5].BasSaat  := EncodeTime(16, 00, 00, 00);
 LVardList[5].SureSaat := 8;

için sonuç
Vardiya No. 2 Başlama : 16.08.2023 08.00.00 Bitiş : 16.08.2023 11.00.00
Vardiya No. 3 Başlama : 16.08.2023 11.00.00 Bitiş : 16.08.2023 12.00.00
Vardiya No. 4 Başlama : 16.08.2023 12.00.00 Bitiş : 16.08.2023 13.00.00
Vardiya No. 5 Başlama : 16.08.2023 13.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 6 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 11.00.00
Vardiya No. 3 Başlama : 17.08.2023 11.00.00 Bitiş : 17.08.2023 12.00.00
Vardiya No. 4 Başlama : 17.08.2023 12.00.00 Bitiş : 17.08.2023 13.00.00
Vardiya No. 5 Başlama : 17.08.2023 13.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 6 Başlama : 17.08.2023 16.00.00 Bitiş : 18.08.2023 00.00.00
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#9
(17-08-2023, Saat: 22:17)mrmarman Adlı Kullanıcıdan Alıntı: Merhaba.

Bu kadar çabaya anlaşılır olmaya gayret ederek kısa bir çözüm sunmaya çalışayım. 
Eğer işinizi görüyorsa ne ala.

Öneri, önce en yakın vardiya saatine kilitlenirseniz çözüm kendiliğinden gelecektir... 
Başarılar.



Uses System.DateUtils;

type
  tVardiya = record
    BasSaat   : TTime;
    SureSaat  : Word;
  end;
  tVardList = array of tVardiya;

function VardiyaHesapla( aStart, aEnd: TDateTime ): string;
var
  i : Integer;
  LVardList : tVardList;
begin
  setLength( LVardList, 3 );

  // Vardiya aralıklarını belirledik.
  LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
  LVardList[0].SureSaat := 8;

  LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
  LVardList[1].SureSaat := 8;

  LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
  LVardList[2].SureSaat := 8;

  // önce başlama tarih/saatini en yakın vardiyaya kilitleyelim...
  // frac() fonksiyonu date time için time kısmını verir.
  if frac(aStart) >= LVardList[2].BasSaat then aStart := Int(aStart) + LVardList[2].BasSaat
  else
  if frac(aStart) >= LVardList[1].BasSaat then aStart := Int(aStart) + LVardList[1].BasSaat
  else
    aStart := Int(aStart) + LVardList[0].BasSaat;

  while aStart <= aEnd do
  begin
    i := Low(LVardList);
    while i <= High(LVardList) do
    begin
      if FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', aStart) then
      begin
 
        Result := Result
                + sLineBreak
                + Format('Vardiya No. %d Başlama : %s Bitiş : %s', [
                      i+1
                    , FormatDateTime('DD.MM.YYYY HH.nn.SS', aStart)
                    , FormatDateTime('DD.MM.YYYY HH.nn.SS', IncHour(aStart, LVardList[i].SureSaat) )
                    ]);

        aStart := IncHour(aStart, LVardList[i].SureSaat);
        i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
      end;
      inc(i);
    end;
  end;

  finalize(LVardList);

end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Memo1.Lines.Text := VardiyaHesapla(   StartDateEdit.Date  + StartTimeEdit.Time
                                      , EndDateEdit.Date    + EndTimeEdit.Time
                                      );

end;



f0lf1rfbvhq7oiorblfk.gif



Record Tipinin ne işe yaradığına başka örnek için belki lazım olabilir diye yatırım diyelim.

3 Vardiya için

 // Vardiya aralıklarını belirledik.
 LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
 LVardList[0].SureSaat := 8;

 LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
 LVardList[1].SureSaat := 8;

 LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
 LVardList[2].SureSaat := 8;
verince sonuç şu oluyorken :

Vardiya No. 2 Başlama : 16.08.2023 08.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 3 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 3 Başlama : 17.08.2023 16.00.00 Bitiş : 18.08.2023 00.00.00


Aşağıdaki gibi farklı aralıklı saatlik çalışma dilimleri için örnek

 // Vardiya aralıklarını belirledik.
 LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
 LVardList[0].SureSaat := 8;

 LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
 LVardList[1].SureSaat := 3;

 LVardList[2].BasSaat  := EncodeTime(11, 00, 00, 00);
 LVardList[2].SureSaat := 1;

 LVardList[3].BasSaat  := EncodeTime(12, 00, 00, 00);
 LVardList[3].SureSaat := 1;

 LVardList[4].BasSaat  := EncodeTime(13, 00, 00, 00);
 LVardList[4].SureSaat := 3;

 LVardList[5].BasSaat  := EncodeTime(16, 00, 00, 00);
 LVardList[5].SureSaat := 8;

için sonuç
Vardiya No. 2 Başlama : 16.08.2023 08.00.00 Bitiş : 16.08.2023 11.00.00
Vardiya No. 3 Başlama : 16.08.2023 11.00.00 Bitiş : 16.08.2023 12.00.00
Vardiya No. 4 Başlama : 16.08.2023 12.00.00 Bitiş : 16.08.2023 13.00.00
Vardiya No. 5 Başlama : 16.08.2023 13.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 6 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 11.00.00
Vardiya No. 3 Başlama : 17.08.2023 11.00.00 Bitiş : 17.08.2023 12.00.00
Vardiya No. 4 Başlama : 17.08.2023 12.00.00 Bitiş : 17.08.2023 13.00.00
Vardiya No. 5 Başlama : 17.08.2023 13.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 6 Başlama : 17.08.2023 16.00.00 Bitiş : 18.08.2023 00.00.00

@mrmarman  Abi çok teşekkür ederim. Üretim planlaması ile ilgili mükemmel bir paylaşım oldu.
Cevapla
#10
(17-08-2023, Saat: 22:17)mrmarman Adlı Kullanıcıdan Alıntı: Merhaba.

Bu kadar çabaya anlaşılır olmaya gayret ederek kısa bir çözüm sunmaya çalışayım. 
Eğer işinizi görüyorsa ne ala.

Öneri, önce en yakın vardiya saatine kilitlenirseniz çözüm kendiliğinden gelecektir... 
Başarılar.



Uses System.DateUtils;

type
  tVardiya = record
    BasSaat   : TTime;
    SureSaat  : Word;
  end;
  tVardList = array of tVardiya;

function VardiyaHesapla( aStart, aEnd: TDateTime ): string;
var
  i : Integer;
  LVardList : tVardList;
begin
  setLength( LVardList, 3 );

  // Vardiya aralıklarını belirledik.
  LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
  LVardList[0].SureSaat := 8;

  LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
  LVardList[1].SureSaat := 8;

  LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
  LVardList[2].SureSaat := 8;

  // önce başlama tarih/saatini en yakın vardiyaya kilitleyelim...
  // frac() fonksiyonu date time için time kısmını verir.
  if frac(aStart) >= LVardList[2].BasSaat then aStart := Int(aStart) + LVardList[2].BasSaat
  else
  if frac(aStart) >= LVardList[1].BasSaat then aStart := Int(aStart) + LVardList[1].BasSaat
  else
    aStart := Int(aStart) + LVardList[0].BasSaat;

  while aStart <= aEnd do
  begin
    i := Low(LVardList);
    while i <= High(LVardList) do
    begin
      if FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', aStart) then
      begin
 
        Result := Result
                + sLineBreak
                + Format('Vardiya No. %d Başlama : %s Bitiş : %s', [
                      i+1
                    , FormatDateTime('DD.MM.YYYY HH.nn.SS', aStart)
                    , FormatDateTime('DD.MM.YYYY HH.nn.SS', IncHour(aStart, LVardList[i].SureSaat) )
                    ]);

        aStart := IncHour(aStart, LVardList[i].SureSaat);
        i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
      end;
      inc(i);
    end;
  end;

  finalize(LVardList);

end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Memo1.Lines.Text := VardiyaHesapla(   StartDateEdit.Date  + StartTimeEdit.Time
                                      , EndDateEdit.Date    + EndTimeEdit.Time
                                      );

end;



f0lf1rfbvhq7oiorblfk.gif



Record Tipinin ne işe yaradığına başka örnek için belki lazım olabilir diye yatırım diyelim.

3 Vardiya için

 // Vardiya aralıklarını belirledik.
 LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
 LVardList[0].SureSaat := 8;

 LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
 LVardList[1].SureSaat := 8;

 LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
 LVardList[2].SureSaat := 8;
verince sonuç şu oluyorken :

Vardiya No. 2 Başlama : 16.08.2023 08.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 3 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 3 Başlama : 17.08.2023 16.00.00 Bitiş : 18.08.2023 00.00.00


Aşağıdaki gibi farklı aralıklı saatlik çalışma dilimleri için örnek

 // Vardiya aralıklarını belirledik.
 LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
 LVardList[0].SureSaat := 8;

 LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
 LVardList[1].SureSaat := 3;

 LVardList[2].BasSaat  := EncodeTime(11, 00, 00, 00);
 LVardList[2].SureSaat := 1;

 LVardList[3].BasSaat  := EncodeTime(12, 00, 00, 00);
 LVardList[3].SureSaat := 1;

 LVardList[4].BasSaat  := EncodeTime(13, 00, 00, 00);
 LVardList[4].SureSaat := 3;

 LVardList[5].BasSaat  := EncodeTime(16, 00, 00, 00);
 LVardList[5].SureSaat := 8;

için sonuç
Vardiya No. 2 Başlama : 16.08.2023 08.00.00 Bitiş : 16.08.2023 11.00.00
Vardiya No. 3 Başlama : 16.08.2023 11.00.00 Bitiş : 16.08.2023 12.00.00
Vardiya No. 4 Başlama : 16.08.2023 12.00.00 Bitiş : 16.08.2023 13.00.00
Vardiya No. 5 Başlama : 16.08.2023 13.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 6 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 11.00.00
Vardiya No. 3 Başlama : 17.08.2023 11.00.00 Bitiş : 17.08.2023 12.00.00
Vardiya No. 4 Başlama : 17.08.2023 12.00.00 Bitiş : 17.08.2023 13.00.00
Vardiya No. 5 Başlama : 17.08.2023 13.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 6 Başlama : 17.08.2023 16.00.00 Bitiş : 18.08.2023 00.00.00

@mrmarman
 Sonucun bu şekilde çıkması için yine sanırım kodları uzatarak güncelledim Smile İlk satırdaki tarihin 08:00:00 değil, 09:00:00 olması gerekiyor. Son satırın saatin de 17:00:00 ile bitmesi gerekiyordu, şu şekilde;

Vardiya No. 2 Başlama : 16.08.2023 09.00.00 Bitiş : 16.08.2023 16.00.00
Vardiya No. 3 Başlama : 16.08.2023 16.00.00 Bitiş : 17.08.2023 00.00.00
Vardiya No. 1 Başlama : 17.08.2023 00.00.00 Bitiş : 17.08.2023 08.00.00
Vardiya No. 2 Başlama : 17.08.2023 08.00.00 Bitiş : 17.08.2023 16.00.00
Vardiya No. 3 Başlama : 17.08.2023 16.00.00 Bitiş : 17.08.2023 17.00.00

function VardiyaHesapla( aStart, aEnd: TDateTime ): string;
var
  i, x, toplam_satir, gercek_satir : Integer;
  LVardList : tVardList;
  BSTART, BEND: TDateTime;
begin
  BSTART:=aStart;
  BEND:=aEnd;
  setLength( LVardList, 3 );

  // Vardiya aralıklarını belirledik.
  LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
  LVardList[0].SureSaat := 8;

  LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
  LVardList[1].SureSaat := 8;

  LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
  LVardList[2].SureSaat := 8;

  // önce başlama tarih/saatini en yakın vardiyaya kilitleyelim...
  // frac() fonksiyonu date time için time kısmını verir.

  if frac(BSTART) >= LVardList[2].BasSaat then
  BSTART := Int(BSTART) + LVardList[2].BasSaat
  else
  if frac(BSTART) >= LVardList[1].BasSaat   then
  BSTART := Int(BSTART) + LVardList[1].BasSaat
  else
  BSTART := Int(BSTART) + LVardList[0].BasSaat;

  toplam_satir:=0;
  x:=0;
  while BSTART <= BEND do   // BU DÖNGÜDE KAÇ SATIR OLUŞACAĞINI toplam_satir DEĞİŞKENİNE ATIYORUZ
  begin

    i := Low(LVardList);
    while i <= High(LVardList) do
    begin
      if (FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', BSTART)) and (x=0) then
      begin
            BSTART := IncHour(BSTART, LVardList[i].SureSaat);

            i := High(LVardList);

            inc(toplam_satir);
            inc(x);
      end;
      if (FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', BSTART)) and (x>0) then
      begin

            BSTART := IncHour(BSTART, LVardList[i].SureSaat);

            i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
            inc(toplam_satir);
      end;
      inc(i);

    end;

  end;
//
  LVardList[0].BasSaat  := EncodeTime(00, 00, 00, 00);
  LVardList[0].SureSaat := 8;

  LVardList[1].BasSaat  := EncodeTime(08, 00, 00, 00);
  LVardList[1].SureSaat := 8;

  LVardList[2].BasSaat  := EncodeTime(16, 00, 00, 00);
  LVardList[2].SureSaat := 8;

  if frac(aStart) >= LVardList[2].BasSaat then
  aStart := Int(aStart) + LVardList[2].BasSaat
  else
  if frac(aStart) >= LVardList[1].BasSaat   then
  aStart := Int(aStart) + LVardList[1].BasSaat
  else
  aStart := Int(aStart) + LVardList[0].BasSaat;

  x:=0;
  gercek_satir:=0;
  while aStart <= aEnd do  // BURADA TOPLAM SATIRA GÖRE SON SATIR KAYDINDA SON TARİH SAATİ YAZDIRIYORUZ
  begin

    i := Low(LVardList);
    while i <= High(LVardList) do
    begin
      if (FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', aStart)) and (x=0) then
      begin

            Result := Result
                    + sLineBreak
                    + Format('Vardiya No. %d Başlama : %s Bitiş : %s', [
                          i+1
                        , FormatDateTime('DD.MM.YYYY HH.nn.SS', Form1.StartDateEdit.Date + form1.StartTimeEdit.Time)
                        , FormatDateTime('DD.MM.YYYY HH.nn.SS', IncHour(aStart, LVardList[i].SureSaat) )
                        ]);

            aStart := IncHour(aStart, LVardList[i].SureSaat);
            i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
            inc(x);
            inc(gercek_satir);
      end;
      if (FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', aStart)) and (x>0) and (gercek_satir=toplam_Satir-1)  then
      begin

            Result := Result
                    + sLineBreak
                    + Format('Vardiya No. %d Başlama : %s Bitiş : %s', [
                          i+1
                        , FormatDateTime('DD.MM.YYYY HH.nn.SS', aStart)
                        , FormatDateTime('DD.MM.YYYY HH.nn.SS', form1.EndDateEdit.Date + Form1.EndTimeEdit.Time)
                        ]);

            aStart := IncHour(aStart, LVardList[i].SureSaat);
            i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
            inc(gercek_satir);
            exit;
      end;

      if (FormatDateTime('HH.nn.SS', LVardList[i].BasSaat) = FormatDateTime('HH.nn.SS', aStart)) and (x>0)   then
      begin

            Result := Result
                    + sLineBreak
                    + Format('Vardiya No. %d Başlama : %s Bitiş : %s', [
                          i+1
                        , FormatDateTime('DD.MM.YYYY HH.nn.SS', aStart)
                        , FormatDateTime('DD.MM.YYYY HH.nn.SS', IncHour(aStart, LVardList[i].SureSaat) )
                        ]);

            aStart := IncHour(aStart, LVardList[i].SureSaat);
            i := High(LVardList); // Hizmet görüldü. Döngüden Çıkılsın.. Diğer saat kontrol edilsin.
            inc(gercek_satir);
      end;
      inc(i);

    end;

  end;

  finalize(LVardList);

end;
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Üretim planlama hakkında boreas 2 1.936 19-06-2020, Saat: 11:25
Son Yorum: uparlayan



Konuyu Okuyanlar: 1 Ziyaretçi