Kalender mit Termineintrag



  • das gind aber schnell, vielen dank.

    weißt du denn auch wenn das letzte feld belegt ist, dass automatisch eine zeile hinzugefügt wird

    hat sich erledigt, ich mach dies einfach auf knopfdruck:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    StringGrid1->RowCount += 1;
    }
    


  • Nun möchte ich, wie ganz oben geschildert, die Daten (also das jeweilige Datum) im Kalender fett oder farbig markiert haben.

    ich habe mir schonmal den folgenden Code aus dem Forum angeguckt:

    void __fastcall TForm1::MonthCalendar1GetMonthInfo(TObject *Sender, DWORD Month,
    	  DWORD &MonthBoldInfo)
    {
    TCommonCalendar *Calendar = dynamic_cast <TCommonCalendar *> (Sender);
    unsigned bdays[5] = {2,4,6,8,10};
    unsigned int x = MonthBoldInfo;
    Calendar->BoldDays(bdays, sizeof(bdays)/sizeof(bdays[4]), x);
    MonthBoldInfo = x;
    }
    

    Ich weiß jetzt leider nicht wie ich die Daten vom StringGrid im Kalender darstellen kann



  • Mit sowas:

    StringGrid1->RowCount += 1;
    //oder
    StringGrid->RowCount++;
    

    Wäre ich vorsichtig. Die Member der VCL-Objekte sind oft "versteckte" Funktionen (bsp. GetRowCount(), SetRowCount()). In dem Fall funktioniert die Zuweisung nicht. Richtig wäre dann:

    StringGrid1->RowCount = StringGrid1->RowCount + 1;
    

    aufgelöst wäre das nämlich:

    StringGrid1->SetRowCount(StringGrid1->GetRowCount() + 1);
    

    mfg
    xXx



  • -=]xXx[=- schrieb:

    Die Member der VCL-Objekte sind oft "versteckte" Funktionen (bsp. GetRowCount(), SetRowCount()). In dem Fall funktioniert die Zuweisung nicht.

    Doch, tut sie; es hängt auch nicht davon ab, ob der Zugriff über Getter- und Setter-Funktionen oder direkt über das Feld erfolgt. Vielmehr ist der Typ entscheidend - bei skalaren Typen geht es, bei allen anderen nicht.

    In einem Nachbarthread hatte ich schon einmal auf meine Zusammenfassung der Property-Regeln verwiesen.



  • @ -=]xXx[=- und audacia
    Vielen Dank für den Hinweis. Werde es in Zukunft beachten.

    Hättet ihr auch ne Lösung wie ich die Datumseingaben im StringGrid im Kalender fett darstellen kann?



  • Hallo

    Siehe FAQ hier im BCB-Forum, Abschnitt StringGrid, Thread farbige Zellen/Zeilen

    bis bald
    akari



  • akari schrieb:

    Hallo

    Siehe FAQ hier im BCB-Forum, Abschnitt StringGrid, Thread farbige Zellen/Zeilen

    bis bald
    akari

    Hallo akari,

    ich habe mich glaub ich bissl undeutlich ausgedrückt:
    Ich möchte, das die Termine, die im StringGrid sind IM KALENDER (also im TMonthCalendar) fett dargestellt werden. Ich möchte NICHT die Zellen vom StringGrid farbig markieren oder ähnliches.
    Gibt es da ne Möglichkeit?



  • Hi,

    dafür gibt es im TMonthCalendar dieses Ereignis (Beispiel):

    void __fastcall TForm1::MonthCalendar1GetMonthInfo(TObject *Sender, DWORD Month, DWORD &MonthBoldInfo)
    
    {
       unsigned bolddays[7] = {1, 2, 5, 11, 18, 19, 20};
       unsigned Buffer = MonthBoldInfo;
       MonthCalendar1->BoldDays(bolddays,6,Buffer);
       MonthBoldInfo = Buffer;
    }
    //---------------------------------------------------------------------------
    

    mfg
    kpeter



  • damit kann ich aber nur die vorgegebenen 7 Daten fett darstellen.

    Ich möchte aber die Datumseinträge, die sich im StringGrid befinden, im Kalender fett darstellen!



  • Hi,

    die Lösung sticht doch ins Auge!

    Du musst halt den Monat als DWORD und die zu markierenden Tage als Array dieser Funktion übergeben.
    Wo ist da das Problem?

    mfg
    kpeter



  • mir sticht gar nichts ins auge 🙂

    danke kpeter für deinen lösungsansatz, doch ich komm wirklich nicht weiter. ich habe es schon so oft versucht, sogar mit string in unsingned int umzuwandeln und dann reinzuschreiben, doch es klappt nicht.
    wäre Dir und den anderen echt dankbar, wenn Ihr mir das mal zeigen könntet



  • das ist mein Programmcode für den Kalender:

    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	// StringGrid Spaltenueberschriften
    	StringGrid1->Cells[0][0] = "Datum";
    	StringGrid1->Cells[1][0] = "Uhrzeit";
    	StringGrid1->Cells[2][0] = "Termin";
    	StringGrid1->Cells[3][0] = "Bemerkung";
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::StringGrid1Click(TObject *Sender)
    {
    // manuelles Eingeben von Termineninformationen (nicht Datum)
    TStringGrid* Grid = dynamic_cast<TStringGrid*>(Sender);
    
    // falls Spalten 1-3 ausgewaehlt, dann Bearbeiten erlauben
    if (Grid->Col == 1 || Grid->Col == 2 || Grid->Col == 3) {
    	Grid->Options  = Grid->Options << goEditing;
    	}
    else Grid->Options  = Grid->Options >> goEditing;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::MonthCalendar1DblClick(TObject *Sender)
    {
    // Datum nur in die 1.Spalte ("Datum") eintragen
    if (StringGrid1->Col == 0) {
    	// wenn Zelle noch NICHT belegt
    	if(StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row].IsEmpty())
    	{
    		// ausgewaehltes Datum in die Zelle schreiben
    		StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] =
    		MonthCalendar1->Date.FormatString("dd.mm.yyyy");
    	}
    // falls Zelle belegt
    else {
    	int Wahl = Application->MessageBox("Zelle bereits belegt!\nFortsetzen?","Hinweis!", MB_YESNO | MB_ICONQUESTION);
    	// falls "ja" geklickt wird Datum ersetzt
    	if (Wahl == IDYES) {
    		StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] =
    		MonthCalendar1->Date.FormatString("dd.mm.yyyy");
    		}
    	}
    }
    else {
    MessageDlg("Bitte Spalte \"Datum\" wählen!", mtWarning, TMsgDlgButtons() << mbOK, 0);
    }
    }
    

    soweit klappt auch alles ok, doch der Kalender soll ja übersichtlich alle Termine fett darstellen, die im StringGrid sind.
    Das heißt alle Datumseinträge, die in der StringGrid-Spalte "Datum" sind, sollen im Kalender fett dargestellt werden.

    mit dem Code von kpeter:

    void __fastcall TForm1::MonthCalendar1GetMonthInfo(TObject *Sender, DWORD Month, DWORD &MonthBoldInfo)
    
    {
       unsigned bolddays[7] = {1, 2, 5, 11, 18, 19, 20};
       unsigned Buffer = MonthBoldInfo;
       MonthCalendar1->BoldDays(bolddays,6,Buffer);
       MonthBoldInfo = Buffer;
    }
    

    kann ich zwar einzelne Tage fett darstellen doch dies erfüllt nicht die Aufgabe.

    Ich habe bischen experimentiert und habe versucht eine Zahl im StringGrid im Kalender fett darzustellen, das klappt auch:

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    StringGrid1->Cells[0][1] = "1";
    StringGrid1->Cells[0][2] = "20";
    }
    
    //---------------------------------------------------------------------------
    void __fastcall TForm1::MonthCalendar1GetMonthInfo(TObject *Sender, DWORD Month,
    	  DWORD &MonthBoldInfo)
    {
    String k = StringGrid1->Cells[0][1];
    String q = StringGrid1->Cells[0][2];
    unsigned i = StrToInt(k);
    unsigned j = StrToInt(q);
    
    unsigned bolddays[2] = {i,j};
    unsigned Buffer = MonthBoldInfo;
    MonthCalendar1->BoldDays(bolddays,2,Buffer);
    MonthBoldInfo = Buffer;
    }
    

    Jetzt weiß ich zumindestens, dass sowas eigentlich klappt.
    Doch wie schon gesagt, weiß ich nicht wie ich das Datum in der StringGrid-Spalte "Datum" im Kalender fett darstellen kann



  • kenux schrieb:

    Doch wie schon gesagt, weiß ich nicht wie ich das Datum in der StringGrid-Spalte "Datum" im Kalender fett darstellen kann

    Hi,

    Damit das funktioniert, musst du eine korrekte Datumseingabe anbieten.
    So wie du herangehst, wird das eher eine Termin-Liste, in die man per Hand das Datum eintragen muss.

    Übernimm deine Werte aus den Zellen in eine StringList (Sortet = true) beginnend mit dem Datum als TDateTime-Wert,
    getrennt durch einen Delimiter.
    So kannst du die Werte bequem abspeichern und wieder einlesen. Wenn du soweit bist, kannst du beim Ereignis
    GetMonthInfo des TMonthCalendar die Einträge für diesen betreffenden Monat abfragen und
    fett darstellen.

    mfg
    kpeter



  • Problem gelöst! Hier der Code falls andere auch benutzen möchten:

    // AnsiString-Array zum Ablegen von 5 Terminen
    	AnsiString str[5];
    
    	// Variablen fuer bold days
    	int d1, d2, d3, d4, d5;
    
    	// fuer Zelle 1
    	if ( StringGrid1->Cells[0][1].Length() > 1) {
    	TStringList* dlist = new TStringList;
    	dlist->Add(StringGrid1->Cells[0][1]);
    	int Pos1 = dlist->Text.Pos("")+1;
    	int Pos2 = dlist->Text.Pos(".");
    	str[0] = dlist->Text.SubString(Pos1,Pos2-Pos1);
    	}
    
    	// fuer Zelle 2
    	if ( StringGrid1->Cells[0][2].Length() > 1) {
    	TStringList* dlist2 = new TStringList;
    	dlist2->Add(StringGrid1->Cells[0][2]);
    	int Pos1_2 = dlist2->Text.Pos("")+1;
    	int Pos2_2 = dlist2->Text.Pos(".");
    	str[1] = dlist2->Text.SubString(Pos1_2,Pos2_2-Pos1_2);
    	}
    
    	// fuer Zelle 3
    	if ( StringGrid1->Cells[0][3].Length() > 1) {
    	TStringList* dlist3 = new TStringList;
    	dlist3->Add(StringGrid1->Cells[0][3]);
    	int Pos1_3 = dlist3->Text.Pos("")+1;
    	int Pos2_3 = dlist3->Text.Pos(".");
    	str[2] = dlist3->Text.SubString(Pos1_3,Pos2_3-Pos1_3);
    	}
    
    	// fuer Zelle 4
    	if ( StringGrid1->Cells[0][4].Length() > 1) {
    	TStringList* dlist4 = new TStringList;
    	dlist4->Add(StringGrid1->Cells[0][4]);
    	int Pos1_4 = dlist4->Text.Pos("")+1;
    	int Pos2_4 = dlist4->Text.Pos(".");
    	str[3] = dlist4->Text.SubString(Pos1_4,Pos2_4-Pos1_4);
    	}
    
    	// fuer Zelle 5
    	if ( StringGrid1->Cells[0][5].Length() > 1) {
    	TStringList* dlist5 = new TStringList;
    	dlist5->Add(StringGrid1->Cells[0][5]);
    	int Pos1_5 = dlist5->Text.Pos("")+1;
    	int Pos2_5 = dlist5->Text.Pos(".");
    	str[4] = dlist5->Text.SubString(Pos1_5,Pos2_5-Pos1_5);
    	}
    
    	// falls Zelle belegt, in Int umwandeln
    	if ( StringGrid1->Cells[0][1].Length() > 1) {
    	d1 = str[0].ToInt();
    	} else d1 = 0;
    	if ( StringGrid1->Cells[0][2].Length() > 1) {
    	d2 = str[1].ToInt();
    	} else d2 = 0;
    	if ( StringGrid1->Cells[0][3].Length() > 1) {
    	d3 = str[2].ToInt();
    	} else d3 = 0;
    	if ( StringGrid1->Cells[0][4].Length() > 1) {
    	d4 = str[3].ToInt();
    	} else d4 = 0;
    	if ( StringGrid1->Cells[0][5].Length() > 1) {
    	d5 = str[4].ToInt();
    	} else d5 = 0;
    
    	// Im Kalender Termine fett darstellen
    	unsigned bolddays[5] = {d1,d2,d3,d4,d5};
    	unsigned Buffer = MonthBoldInfo;
    	MonthCalendar1->BoldDays(bolddays,4,Buffer);
    	MonthBoldInfo = Buffer;
    }
    

    und am besten Datum folgendermaßen formatieren :

    // ausgewaehltes Datum in die Zelle schreiben
    StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] =
    MonthCalendar1->Date.FormatString("d.mm.yyyy");
    

    Herzlichen Dank an alle, die mir dabei geholfen haben!



  • Hi,

    lösche wenigstens deine vielen TStringList an Ende der Routine.

    mfg
    kpeter



  • oder packe sie in auto_ptr.



  • kpeter schrieb:

    Hi,

    lösche wenigstens deine vielen TStringList an Ende der Routine.

    mfg
    kpeter

    ach das hab ich ja total vergessen, danke kpeter



  • Ich hätte da noch einen Tipp:

    Ich würde für die Integer einen Array nehmen.
    Und dann alles schön in eine For-Schleife packen.

    Dann würde dein Sourcecode 5 mal kleiner und 1000 mal variabler sein.
    Zudem müssen dann Änderungen nur noch an einem Ort durchgeführt werden und nicht x mal.



  • Krielon schrieb:

    Ich hätte da noch einen Tipp:

    Ich würde für die Integer einen Array nehmen.
    Und dann alles schön in eine For-Schleife packen.

    Dann würde dein Sourcecode 5 mal kleiner und 1000 mal variabler sein.
    Zudem müssen dann Änderungen nur noch an einem Ort durchgeführt werden und nicht x mal.

    Mit der for-Schleife habe ich es schon ausprobiert. Da werden aber Tage im Kalender fett markiert, die gar nicht angeklickt wurden.

    Am effektivsten müsste schon Variante sein, die ich gewählt habe



  • kenux schrieb:

    Da werden aber Tage im Kalender fett markiert, die gar nicht angeklickt wurden.

    Hi,

    so richtig dahintergekommen bist du noch nicht ;).

    Das Ereignis *GetMonthInfo(TObject Sender, DWORD Month, DWORD &MonthBoldInfo)
    wird mehrmals hintereinander aufgerufen.
    Je nachdem, wieviel Monate angezeigt werden, werden auch benachbarte nichtsichtbare Monate (aufsteigend) abgefragt.
    Dabei schickt die Komponente immer in Month den Monat als DWORD mit.

    Zur Veranschaulichung ein Beispiel:

    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
       strList = new TStringList;
       strList->Sorted = false;
       strList->Add("07.06.2009");
       strList->Add("12.06.2009");
       strList->Add("22.06.2009");
       strList->Add("23.06.2009");
       strList->Add("29.06.2009");
       strList->Add("07.07.2009");
       strList->Add("08.07.2009");
       strList->Add("09.07.2009");
       strList->Add("10.07.2009");
       strList->Add("07.08.2009");
       // beliebig ergänzen bzw.
       // gehören hier die Werte aus deinem StringGrid rein
       Memo1->Text = strList->Text;
    }
    //---------------------------------------------------------------------------
    
    __fastcall TForm1::~TForm1(void)
    {
       delete strList;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::MonthCalendar1GetMonthInfo(TObject *Sender, DWORD Month, DWORD &MonthBoldInfo)
    {
       if (Form1) ShowMessage("aktualisiere Monat : " + IntToStr((__int64)Month));  
    
       int tage = 0;
       unsigned bolddays[31];
       memset(bolddays, 0, sizeof(bolddays));
       for (int i = 0; i < strList->Count; i++) {
          TDateTime dt = strList->Strings[i];
          WORD yr    = YearOf(dt);
          WORD mt    = MonthOf(dt);
          WORD day   = DayOf(dt);
    
          if (mt == Month) {
             bolddays[tage] = day;
             tage++;
          }
       }
       unsigned int Buffer = MonthBoldInfo;
       MonthCalendar1->BoldDays(bolddays, 30, Buffer);
       MonthBoldInfo = Buffer;
    }
    //---------------------------------------------------------------------------
    

    mfg
    kpeter


Anmelden zum Antworten