15. april 2004 - 15:19
Der er
40 kommentarer og 2 løsninger
Brug af funktioner i DataModul
Hej, Jeg står og mangler lidt hjælp til noget kode. Jeg har en form hvor jeg har en listbox. Denne listbox vil jeg gerne have fyldt op med noget data fra en database. Men det skal ske via et kald til en funktion på et DataModule. Dette er funktionen der skal kalde funktionen på DataModulet: void __fastcall TfrmOpretKval::FormCreate(TObject *Sender) { list<string> Firmaer; Firmaer = dmTP->HentFirma(); while (!Firmaer.empty()) { lstFirma->AddItem(Firmaer.front().c_str(),0); Firmaer.pop_front(); } } Funktionen på dataModulet ser således ud: list<string> TdmTP::HentFirma() { list<string> NavneList; Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT Navn FROM tblFirma"); Query1->Open(); while (!Query1->Eof) { NavneList.push_front(Query1->FieldByName("Navn")->AsString.c_str()); Query1->Next(); } return NavneList; } Der er forbindelse til DB og det virker hvis Query og Database komponenterne ligger på formen "frmOpretKval" Med dette kode får jeg en access violation... bla bla fejl... Nogen der kan hjælpe her? Kort sagt går det vel ud på at kalde en funktion på et dataModul!
Annonceindlæg fra Cognizant
15. april 2004 - 15:21
#1
Det skal selvfølgelig lige siges at denne linie: Firmaer = dmTP->HentFirma(); er jeg ikke sikker på er som den skal være!
15. april 2004 - 15:22
#2
Mon ikke det er fordi du opretter NavneList på stack'en? Hvis du i stedet giver den med som argument til funktionen og blot fylder i den der, tror jeg det hjælper...
15. april 2004 - 15:23
#3
kan du uddybe lidt?
15. april 2004 - 15:25
#4
void TdmTP::HentFirma(list<string>& NavneList) { Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT Navn FROM tblFirma"); Query1->Open(); while (!Query1->Eof) { NavneList.push_front(Query1->FieldByName("Navn")->AsString.c_str()); Query1->Next(); } } //Kald list<string> NavneList; HentFirma(NavneList);
15. april 2004 - 15:40
#5
hmmm... Jeg får stadig samme fejl! Funktionerne ser nu således ud: void TdmTP::HentFirma(list<string>& NavneList) { Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT Navn FROM tblFirma"); Query1->Open(); while (!Query1->Eof) NavneList.push_front(Query1->FieldByName("Navn")->AsString.c_str()); } void __fastcall TfrmOpretKval::FormCreate(TObject *Sender) { list<string> NavneList; dmTP->HentFirma(NavneList); while (!NavneList.empty()) { lstFirma->AddItem(NavneList.front().c_str(),0); NavneList.pop_front(); } }
15. april 2004 - 15:43
#6
nogen gode forslag?
15. april 2004 - 15:46
#7
Har du prøvet at debugge for at se hvor fejlen kommer? Jeg kan desværre ikke lige genvejstasterne til BCB på hånden, så hvis du ikke ved hvad "at debugge" er, så prøv at kigge i menuerne.
15. april 2004 - 15:49
#8
Den stopper på: Database1->StartTransaction(); og hvis jeg siger "step over" så stopper den på næste linie: Query1->SQL->Clear(); og næste: Query1->SQL->Add("SELECT Navn FROM tblFirma"); og næste: Query1->Open(); :-/
15. april 2004 - 15:51
#9
Hvis du fortsætter, kan du så ikke se hvor fejlen er?
15. april 2004 - 15:52
#10
Altså, når du udfører en bestemt linie, går programmet ned...
15. april 2004 - 15:52
#11
I think so...
15. april 2004 - 15:55
#12
Projekt p2.exe raised exception class EAccessViolation with message 'Access violation in address 00403843 in module p2.exe. Read of address '00000058'. Process Stoped. Use Step Over or Run to continue.
15. april 2004 - 15:56
#13
og så bliver denne linie markeret: Database1->StartTransaction();
15. april 2004 - 15:56
#14
Jep, hvilken linie stod du ved da det skete?
15. april 2004 - 15:57
#15
Database1->StartTransaction();
15. april 2004 - 15:59
#16
Kan du se om Database1 er et gyldigt objekt? I VC++ kan man fx sætte musepointeren over teksten og se hvad adressen er. Måske er Database1 ikke et gyldigt objekt, har du initialiseret det?
15. april 2004 - 16:02
#17
Ja det spiller... Den er connected til en MS SQL server og database via en odbc
15. april 2004 - 16:04
#18
Nu prøvede jeg lige, at indsætte et breakpoint på linien: Database1->StartTransaction(); når jeg så holder musen hen over står der Database1 = ????? Er det meningen?
15. april 2004 - 16:17
#19
Stadig der?
15. april 2004 - 16:21
#20
Jeg kan ikke huske hvordan BCB viser forskellige tilstande, men det ser jo ikke så fornuftigt ud. Hvor bliver objektet oprettet?
15. april 2004 - 16:25
#21
h filen for datamodulet: #include <DB.hpp> #include <DBTables.hpp> #include <string> #include <list> using namespace std; //--------------------------------------------------------------------------- class TdmTP : public TDataModule { __published: // IDE-managed Components TDatabase *Database1; TQuery *Query1; private: //list<string> lorteliste; public: void HentFirma(list<string> NavneLli); int FindFirmaID(string navn); int FindProjektID(string navn); list<string> HentProjekt(int FirmaID); __fastcall TdmTP(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TdmTP *dmTP; //--------------------------------------------------------------------------- #endif
15. april 2004 - 16:25
#22
cpp filen for dataModulet: //--------------------------------------------------------------------------- #include <vcl.h> #include <list> #pragma hdrstop #include "dm.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" using namespace std; TdmTP *dmTP; //--------------------------------------------------------------------------- __fastcall TdmTP::TdmTP(TComponent* Owner) : TDataModule(Owner) { } //--------------------------------------------------------------------------- void TdmTP::HentFirma(list<string> NavneList) { Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT Navn FROM tblFirma"); Query1->Open(); while (!Query1->Eof) { NavneList.push_front(Query1->FieldByName("Navn")->AsString.c_str()); Query1->Next(); } return lorteliste; } list<string> TdmTP::HentProjekt(int FirmaID) { list<string> NavneList; Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT Navn FROM tblProjekt"); Query1->Open(); while (!Query1->Eof) { NavneList.push_front(Query1->FieldByName("Navn")->AsString.c_str()); Query1->Next(); } return NavneList; } int TdmTP::FindFirmaID(string navn) { int FirmaID; Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT FirmaID FROM tblFirma WHERE Navn ="); Query1->SQL->Add("( :NAVN)"); Query1->ParamByName("NAVN")->AsString = navn.c_str(); Query1->Open(); FirmaID = Query1->FieldByName("FirmaID")->AsInteger; return FirmaID; } int TdmTP::FindProjektID(string navn) { int ProjektID; Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT ProjektID FROM tblProjekt WHERE Navn ="); Query1->SQL->Add("( :NAVN)"); Query1->ParamByName("NAVN")->AsString = navn.c_str(); Query1->Open(); ProjektID = Query1->FieldByName("ProjektID")->AsInteger; return ProjektID; }
15. april 2004 - 16:26
#23
void HentFirma(list<string> NavneLli); skal selvfølgelig være: void HentFirma(list<string> NavneList); var bare ved at rette...
15. april 2004 - 16:29
#24
I'm going crazy...
15. april 2004 - 16:30
#25
Så vidt jeg kan se opretter du aldrig et TDatabase objekt? Fx Database1 = new TDatabase();
15. april 2004 - 16:31
#26
Database1 er jo bare en pointer til et TDatabase objekt, men hvis du aldrig har oprettet det objekt, så...
15. april 2004 - 16:33
#27
så hvad...
15. april 2004 - 16:33
#28
giv mig et par guldkorn...
15. april 2004 - 16:35
#29
Altså, hvis du ikke har et objekt, kan du heller ikke kalde en metode på det...
15. april 2004 - 16:36
#30
15. april 2004 - 16:36
#31
Fx: __fastcall TdmTP::TdmTP(TComponent* Owner) : TDataModule(Owner) { Database1 = new TDatabase(); }
15. april 2004 - 16:37
#32
det er sådan Database1 og Query1 ligger!
15. april 2004 - 16:50
#33
Kan ikke få "new TDatabase();" til at virke...
15. april 2004 - 16:53
#34
tryl for mig! PLEASE!!!!!!!!!!
15. april 2004 - 16:54
#35
Som sagt, jeg kender ikke BCB's måde at håndtere det på, men hvis Database1 ikke "peger" på et gyldigt objekt, fungerer det naturligvis ikke...
15. april 2004 - 17:01
#36
hvad er det for et objekt den skal pege på? Jeg har jo sat en komponent ind der ER Database1 og denne komponent er jo connected til db'en...
15. april 2004 - 17:08
#37
Hvis Database1 var gyldig, ville det vel ikke crash'e når du kalder StartTransaction, vel..?
15. april 2004 - 17:19
#38
næ det ville den vel ikke...
15. april 2004 - 17:28
#39
men kan du fortælle mig hvad jeg skal gøre? har du kigge på linket jeg lagde?
15. april 2004 - 18:13
#40
Nogen der kan fortælle mig hvorfor skidtet fungerer når jeg ligger komponenterne Database1 og Query1 over på min alm. form og bruger disse to funktioner: void __fastcall TfrmOpretKval::FormCreate(TObject *Sender) { list<string> NavneList; HentFirma(NavneList); while (!NavneList.empty()) { lstFirma->AddItem(NavneList.front().c_str(),0); NavneList.pop_front(); } } //--------------------------------------------------------------------------- void TfrmOpretKval::HentFirma(list<string>& NavneList) { Database1->StartTransaction(); Query1->SQL->Clear(); Query1->SQL->Add("SELECT Navn FROM tblFirma"); Query1->Open(); while (!Query1->Eof) { NavneList.push_front(Query1->FieldByName("Navn")->AsString.c_str()); Query1->Next(); } }
16. april 2004 - 08:43
#41
Hej igen... Jeg ved der er flere i dette forum, der sværger til BCB, så vi må håbe på hjælp fra dem... Mit bud er: - Når komponenterne ligger på formen, har den ansvaret for at oprette objekterne og konfigurere dem. - Når du selv bruger klasserne som members, skal du instantiere og konfigurere dem. (Altså sætte brugernavn, password osv...)
29. april 2004 - 14:59
#42
lukker - løsningen var Application->createform(__classID, Tdatamod, datamod)
Kurser inden for grundlæggende programmering