DateTimePicker auslesen



  • Hallo

    Ich weis das Thema wurde im Forum bereits einige Male besprochen jedoch konnte ich bisher keine Antwort finden.

    Ich möchte gerne den Wert eines DateTimePickers auslesen und in eine Datenbank ablegen. Bisher habe ich irgendwie keine Möglichkeit dafür gefunden. Dabei habe ich einen DTP für das Datum und einen für die Zeit. Nun sollen aber beide Werte in eine Tabellenspalte abgelegt werden ( Date/Time ).

    Ist es möglich 2 DTP-Werte zu Verbinden ?
    Wie könnte ich die Werte aus dem DTP auslesen ?

    Würde mich sehr auf einen Denkanstoss freuen.

    mfg el-loco



  • Schau mal in die MSDN. Da gibt es bei COleDateTime die Funktionen SetDate und SetTime.
    In COleDateTime kannst du ja einfach als Wertevariablen für einen DateTimePicker nehmen. Du hast dann also insgesamt drei Variablen.

    Und in die Datenbank kriegst du das mit CRecordset, du musst aber auspassen, dass der Typ im Recordset auch COleDateTime ist, sonst bekommst du Wertebereichsprobleme und kannst auch nicht so einfach zuweisen.



  • Hi

    Von den Funktionen hab ich auch gelesen, danke. Aber ich blicke nicht durch die vielen Möglichkeiten. Also ich hoffe ich sehe das richtig: Ich setze für den DTP (Datum) eine Membervariable(Value) vom Typ COleDateTime. Mit SetTime bzw. SetDate kann ich das Datum einstellen welches beim erstellen des DTP angezeigt wird. (momentan zeigt er 1.1.1970). Der Benutzer kann dan das Datum und Zeit einstellen und der Wert kann dann mittels der Value-Variable in die DB geschrieben werden.

    Stimmt das soweit ?

    mfg el-loco



  • Ist anders als ich meinte aber nicht falsch. 🙂
    Mit COleDateTime::GetCurrentTime() bekommst du übrigens die aktuelle Zeit.

    Achja, beim Teil Richtung Datenbank scheint dir noch was zu fehlen, oder wo ist deine CRecordsetklasse in der Beschreibung?



  • Das Schreiben in die DB sollte eigentlich kein grosses Problem sein. Ich habe eine ODBC Klasse erstellt. Auch den Datentyp im Feld ist Date/Time. Müsste eigentlich gehen.

    Also ich werds mal versuchen. Vielen Dank für die Hilfe soweit.

    Nur die Frage ist noch: Wie verbinde ich 2 DTP Werte in eine Tabellenspalte ?

    mfg el-loco



  • Na, mit SetDate und SetTime. 🙂

    tmBeide.SetDate(tmDatum);
    tmBeide.SetTime(tmZeit);
    


  • Ach soo 💡

    Jetzt verstehe ich was du mit den 3 Veriablen meintest 😉

    Ich hoffe ich habe das richtig verstanden:

    m_InDieDB.SetDate(Valuemembervariable DTP (Datum))
    m_InDieDB.SetTime(Valuemembervariable DTP (Zeit))

    mfg el-loco



  • Ja, so meinte ich. 🙂



  • Okay, dann bin ich auf dem richtigen Weg 🙂

    folgendes habe ich gemacht:

    OleDateTime Lo_ToDB;
    
    Lo_ToDB.SetDate(m_StartDate.GetYear(),m_StartDate.GetMonth(), m_StartDate.GetDay());
    Lo_ToDB.SetTime(m_StartTime.GetHour(),m_StartTime.GetMinute(), m_StartTime.GetSecond());
    
    Lo_Entry.m_t_Zeitpunkt = Lo_ToDB;
    

    Leider erfolgt kein Eintrag in der Datenbank und "leider" auch keine Fehlermeldung.
    Fehlt da noch was oder mache ich etwas falsch?

    mfg el-loco



  • Lo_Entry ist eine von CRecordset abgeleitete Klasse?
    Wenn ja:
    Wo ist das Edit/Add und das Update? 🙂



  • ja. Lo_Entry ist eine Klasse von Typ CRecordset ( ODBC Consumer ).Sorry habe das Add und Update nicht im Forum gepostet, mein Fehler. Also es das Add und Update sind vorhanden. Das Programm läuft alle Befehle von Add bis zum Update ohne Fehler durch. Nur bei m_t_Zeitpunkt erfolgt kein Eintrag 😞

    mfg el-loco



  • Für die anderen Felder geht es aber? 😕

    Dann zeig bitte mal die DoFieldExchange, die Variablendeklaration im Header und sag, welchen Zeitstempel zu beispielsweise ausprobiert hast. 🙂



  • Ja. Alle Felder werden korrekt Ausgefüllt.

    Hier die DoDataExchange:

    void SMT_C_Supplement::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	DDX_Control(pDX, IDC_COMBO1, m_ListActivities);
    	DDX_Control(pDX, IDC_EDIT1, m_NewActivity);
    	DDX_DateTimeCtrl(pDX, IDC_DATETIMEPICKER5, m_StartDate);
    	DDX_DateTimeCtrl(pDX, IDC_DATETIMEPICKER2, m_StartTime);
    }
    

    Die Headerdatei:

    class SMT_C_Supplement : public CDialog
    {
    	DECLARE_DYNAMIC(SMT_C_Supplement)
    
    public:
    	SMT_C_Supplement(CWnd* pParent = NULL);   // standard constructor
    	virtual ~SMT_C_Supplement();
    
    // Dialog Data
    	enum { IDD = IDD_SMT_SUPPLEMENT };
    
    protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    
    	DECLARE_MESSAGE_MAP()
    public:
    	afx_msg void OnDtnDatetimechangeDatetimepicker3(NMHDR *pNMHDR, LRESULT *pResult);
    	afx_msg void OnCbnSelchangeCombo1();
    	long m_ProjectID;
    	CComboBox m_ListActivities;
    	afx_msg void OnDtnDatetimechangeDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult);
    	CEdit m_NewActivity;
    	afx_msg void OnBnClickedButton1();
    	int m_ChooseActivity;
    	int m_CreateActivity;
    	afx_msg void OnBnClickedRadio1();
    	afx_msg void OnBnClickedRadio2();
    	COleDateTime m_StartDate;
    	COleDateTime m_StartTime;
    };
    

    Hier der Datenbankeintrag:

    CString Ls_Activity;
    CString Ls_Query;
    CString Ls_Message;
    
    DB_C_Entry Lo_Entry;
    DB_C_Activity Lo_Activity;
    DB_C_Project Lo_Project;
    COleDateTime Lo_ToDB;
    
    Lo_ToDB.SetDate(m_StartDate.GetYear(),m_StartDate.GetMonth(),m_StartDate.GetDay());
    Lo_ToDB.SetTime(m_StartTime.GetHour(),m_StartTime.GetMinute(),m_StartTime.GetSecond());
    
    Lo_Entry.AddNew();
    Lo_Entry.m_s_Projektname = Lo_Project.m_s_ProjektName;
    Lo_Entry.m_s_Taetigkeitsname = "";
    Lo_Entry.m_s_Benutzername = "";		
    Lo_Entry.m_b_Nachtrag = 1;
    Lo_Entry.m_t_Zeitpunkt = Lo_ToDB;			
    Lo_Entry.m_b_Typ = "Start";
    Lo_Entry.Update();
    

    Was meinst du mit Zeitstempel ?

    Vielen Dank für deine Mühe. 😃

    mfg el-loco



  • Ähm, eigentlich wollte ich das DoFieldExchange sehen, aber ich habe den Fehler gefunden.

    Du darfst die Variablen erst NACH AddNew füllen. AddNew erzeugt doch erst den zu füllenden Datensatz. ⚠



  • Aach.. Noch früh am Morgen nach dem Feiertag, sorry

    also das verstehe ich jetzt nicht ganz 😕 .

    Die Variable Lo_ToDB wird vor AddNew() aufbereitet und dann in die DB geschrieben.

    Hier noch DoFieldExchange:

    void DB_C_Entry::DoFieldExchange(CFieldExchange* pFX)
    {
    	pFX->SetFieldType(CFieldExchange::outputColumn);
    // Macros such as RFX_Text() and RFX_Int() are dependent on the
    // type of the member variable, not the type of the field in the database.
    // ODBC will try to automatically convert the column value to the requested type
    	RFX_Long(pFX, _T("[i_EintragID]"), m_i_EintragID);
    	RFX_Text(pFX, _T("[s_Projektname]"), m_s_Projektname);
    	RFX_Text(pFX, _T("[s_Taetigkeitsname]"), m_s_Taetigkeitsname);
    	RFX_Text(pFX, _T("[s_Benutzername]"), m_s_Benutzername);
    	RFX_Bool(pFX, _T("[b_Nachtrag]"), m_b_Nachtrag);
    	RFX_Date(pFX, _T("[t_Zeitpunkt]"), m_t_Zeitpunkt);
    	RFX_Text(pFX, _T("[b_Typ]"), m_b_Typ);
    
    }
    

    Ich hoffe du meinstest das. 😉
    mfg el-loco



  • Du musst das Aufbereiten aber NACH AddNew machen, sonst ist das umsonst gewesen!

    Lo_Entry.AddNew();
    Lo_ToDB.SetDate(m_StartDate.GetYear(),m_StartDate.GetMonth(),m_StartDate.GetDay());
    Lo_ToDB.SetTime(m_StartTime.GetHour(),m_StartTime.GetMinute(),m_StartTime.GetSecond());
    
    Lo_Entry.m_s_Projektname = Lo_Project.m_s_ProjektName;
    Lo_Entry.m_s_Taetigkeitsname = "";
    Lo_Entry.m_s_Benutzername = "";       
    Lo_Entry.m_b_Nachtrag = 1;
    Lo_Entry.m_t_Zeitpunkt = Lo_ToDB;           
    Lo_Entry.m_b_Typ = "Start";
    Lo_Entry.Update();
    


  • Habs gemacht wie du gesagt hast. Leider ändert sich nichts. 😞

    Ich habe auch den Zusammenhang, dass nach AddNew() Variablen aufbereitet werden müssen noch nicht ganz begriffen. Vielleicht sollte ich mich mal besser nochmal hinter die Bücher stellen. 🙄

    mfg el-loco



  • Oder ich versuchs einmal "für Doofe" zu erklären. 🙂
    Was is dir lieber? Die Erklärung käme dann nachher, so nach 13:30 irgendwann.



  • Die Erlärung für "Neulinge" bitte. 😉

    mfg el-loco



  • Okay, die geht etwas schneller. 😃

    Also:
    Gehen wir mal davon aus, du hast schon Daten eingelesen und steht auf dem letzten Datensatz.
    Wenn du nun irgendwas in die Member schreibst, überschreibst du die Daten im letzten Datensatz. Aber nur im RAM, nicht in der DB.
    Willst du nun also einen neuen Datensatz haben, musst du AddNew aufrufen.
    Es wird eine "leere Zeile" hintenangestellt und der Cursor darauf gesetzt.
    Da rein kannst du nun schreiben - vergisst du ein Feld, ist es NULL.
    Wenn du fertig bist schreibst du den neuen Datensatz mit Update in die DB und holst ihn dir (sicherheitshalber) mit Requery neu wieder.

    Soviel dazu. Ich hab nochmal zwei Fragen:
    1.) Was für ein Typ ist m_t_Zeitpunkt?
    2.) Was für ein Datum versuchst du zu speichern. Irgendwas vor 1970 oder nach 2038?


Anmelden zum Antworten