Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++, WinAPI] Komunikacja z bazą danych MS Access

Ostatnio zmodyfikowano 2012-11-07 18:32
Autor Wiadomość
xevuel
» 2012-11-06 15:52:22
wypisac teraz do LPCSTR komorke z konkretnej kolumny (np "Miasto")
Jaki typ zwraca pFields->GetItem(i)->GetValue()? Jeśli coś a'la char* to prawdopodobnie wystarczy tylko rzutowanie na LPCSTR, bez wywoływania jakichś tam funkcji. W przeciwnym razie:
C/C++
while( !pRS->AdoNSEOF )
{
    int numerKolumnyMiasto = 3; //ew. mozesz pobierac nazwy kolumn i w trakcie dzialania programu sprawdzic, czy pod indeksem n nie kryje sie kolumna o nazwie "Miasto"
    {
        zmienna = bstr_t( pFields->GetItem( numerKolumnyMiasto )->GetValue() );
        //przekonwertuj zmienną na LPCSTR za pomocą linku który podałem we wcześniejszym poście
    }
    cout << endl;
    pRS->MoveNext();
}

jak ogolnie dzialaja te "ms access" statement, wygladaja podobnie do sql troche ale to nie to samo, nie wiem skad wziasc jakies zrodla opisujace te statement, czyli jak zmienic, dodac, wypisac rekord itd...
Wydaje mi się, że tutaj: http://msdn.microsoft.com/en-us/library/office/bb259125(v=office.12).aspx jest to opisane.

co to to cholerne COM (w przyjaznym do zrozumienia jezyku), zebym chociaz wiedzial mniej wiecej z czego korzystam.
Hmm.. Chyba najlepiej będzie dać Ci kolejnego linka: http://www.dimmension3.spine.pl/download/pdf/WinApi - COM.pdf :)
P-68612
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-06 15:59:25
Hey ho!

widze ze rano pisalismy mniej wiecej w tym samym czasie i widze ze bardzo podobne artykuly znalezlismy.
W SQL i PHP kiedys z nudow programowalem wiec w zapytaniach sie polapie, problem tylko w tym ze jak widze te zapytania sa troche inne niz orginalne (np Dane.[Imie]) ale to wynika pewnie z roznicy struktury tych baz podczas gdy sama skladnia sql chyba zostaje taka sama. szkoda tylko ze na accessie nie mozna tych zapytan wyprobowac najpierw bezposrednio zanim sie je wlozy do kodu C++ zeby sprawdzic co wyrzucaja i czy wogole cos wyrzucaja...no nic, pokombinuje sie jakos....

Wiem ze to troche obciach budowac program na Accessie ale ADO ma jak widze to do siebie ze w razie czego zawsze mozna po lekkiej modyfikacji zmienic Accessa na np SQL i juz jest pelne profi! lol

dzieki za linki, te z konwersja na string sie szczegolnie przydadza i oczywiscie za wczesniejsza pomoc z COMem.

Chyba oleje trening zeby sie jaknajszybciej po pracy do kompa przyssac, piwa tylko do lodowki zapomnialem wlozyc :-)

pozdrawiam,
berkov
P-68614
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-06 16:00:53
haha

znowu w tym samym czasie, juz czytam!
P-68615
DejaVu
» 2012-11-06 16:24:12
szkoda tylko ze na accessie nie mozna tych zapytan wyprobowac najpierw bezposrednio zanim sie je wlozy do kodu C++ zeby sprawdzic co wyrzucaja i czy wogole cos wyrzucaja...no nic, pokombinuje sie jakos....
Wydaje mi się, że istnieje możliwość testowania zapytań w programie MS Access - kilka lat temu obiła mi się taka informacja o uszy.


http://office.microsoft.com/pl-pl/access-help/jezyk-access-sql-podstawowe-pojecia-sownictwo-i-skadnia-HA010256402.aspx
P-68619
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-06 16:43:33
Ano! da sie.. nawet bym o tym nie pomyslal!
dzieki za info. w razie czego dziele sie artykulem ktory wlasnie znalazlem (niech zyje google):
http://www.cwnresearch.com/resources/databases/access /tutorials/access2000/SQLQueries/SQLQueries.html
P-68626
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-07 00:36:24
No i panowie!!! dziala!

C/C++
try
{
   
    _bstr_t roww = _bstr_t( pFields->GetItem(( long ) 0 )->GetValue() );
   
   
    MessageBox( 0,( LPCSTR ) roww, 0, 0 );
   
}
catch( _com_error & )
{
    MessageBox( 0, "Błąd numer 7", 0, 0 );
    CoUninitialize();
}

Co prawda trza sie bylo troche pomenczyc bo w GetItem nie wystarczylo wpisac 0 ale (long)0, nie wystarczylo najechac na getitem zeby sie pokazal typ zmiennej...  nie wiem jak na to nawet wpadlem hehe

z konwersja do LPCSTR tez mi troche zajelo a okazalo sie ze dziala najprostsze rozwiazanie (LPCSTR) _bstr_t, nie wiem czemu od razu tego nie sprobowalem!


co do Accessa i SQL to sprawdzilem i mozna robic query w Accessie bezposrednio w SQL. i dodam ze jest to prawdziwy, pelny SQL!
SELECT Miasto FROM Tabelka WHERE ID=6, mozna nawet "graficznie" zrobic sobie query a pozniej kliknac na SQL view i Access sam wygeneruje SQL z tabelki dla nas (Microsoft byl zawsze madrzejszy od uzytkownika :-) )

Ok .. teraz walcze z UPDATE.. jak naucze sie towrzyc nowe rekordy i uzupelniac istniejace to wrzuce tu jakis przykladowy pelny ale prosty kod dla innych! a pozniej w koncu bede mogl zabrac sie za pisanie swojego programu.


wypasione dzieki za pomoc!

W koncu pojde spac spokojne!
pozdroovko
berkov
P-68691
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-07 18:30:17
Witam,

Jeszcze raz dziekuje za pomoc.

Jak obiecalem wklejam przykladowy, ostateczny i dzialajacy kod, ktory potrafi zapisac oraz odczytac dane z Accessa.

Wlasciwie po wklejeniu do pustego Win32 projektu powinien zadzialac przy drobnych modyfikacjach takich jak np usatwienie sciezki do pliku access’a i wpisaniu do funckji db_zapisz i db_odczytaj odpowiednich wartosci ktore znajduja sie w naszym pliku access.

Dodam jeszcze ze aby uzyc bazy SQL nalezy wlascwie tylko zmodyfikowac:
connection->Open( "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\folder\\plik.accdb;", "", "", ADODB::adConnectUnspecified );

na odpowiedni “string” dla sql.
Nie testowalem polaczenia z sql ale wszystkie przyklady na necie odnosza sie zazwyczaj do baz danych postawionych na slq wiec bedzie latwo odnalezc.
Jest to cos a’la:
Provider=SQLOLEDB.1;Persist Security Info=False;User ID=username;Password=passwd;Initial Catalog=database;Data Source=(local);Integrated Security=SSPI;"
 
 
Oto kod zrodlowy:


C/C++
#include <windows.h>
#import "C:\Program Files\Common Files\System\ado\msado26.tlb" rename( "EOF", "ADOEOF" )
//tu nalezy wpisac sciezke do dowolnego pliku msadoXX.tlb z C:\Program Files\Common Files\System\ado\zxxx.xx
//Generalnie im wiekszy numer (msado26) dostepny, tym nowszy. Ja probowalem na 15 i na 26, na obu dziala. Mozna tez uzyc dll’a – np. msado15.dll

ADODB::_ConnectionPtr connection;
ADODB::_RecordsetPtr recordset;
HRESULT hr;


void db_polacz()
{
    hr = CoInitialize( NULL );
    if( FAILED( hr ) )
    {
        MessageBox( 0, "Blad 1", 0, 0 );
    }
   
   
    hr = connection.CreateInstance( __uuidof( ADODB::Connection ) );
    if( FAILED( hr ) )
    {
        MessageBox( 0, "Blad 2", 0, 0 );
    }
   
    hr = recordset.CreateInstance( __uuidof( ADODB::Recordset ) );
    if( FAILED( hr ) )
    {
        MessageBox( 0, "Blad 3", 0, 0 );
    }
   
    try
    {
        connection->CursorLocation = ADODB::adUseClient;
    }
    catch( _com_error & )
    {
        MessageBox( 0, "Blad 4", 0, 0 );
    }
   
    try
    {
        connection->Open( "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\folder\\plik.accdb;", "", "", ADODB::adConnectUnspecified );
    }
    catch( _com_error & )
    {
        MessageBox( 0, "Blad 5", 0, 0 );
        CoUninitialize();
    }
   
}

void db_odczytaj( LPCSTR tabela, LPCSTR kolumna, int indeks )
{
   
    db_polacz();
   
    _bstr_t query = "SELECT " +( _bstr_t ) kolumna + " FROM " +( _bstr_t ) tabela + " WHERE ID=" +( _bstr_t ) indeks;
   
    try
    {
        recordset->Open( query,
        _variant_t(( IDispatch * ) connection, true ),
        ADODB::adOpenUnspecified,
        ADODB::adLockUnspecified,
        ADODB::adCmdText );
    }
    catch( _com_error & )
    {
        MessageBox( 0, "Blad 6", 0, 0 );
        CoUninitialize();
    }
   
   
    ADODB::Fields * pFields = NULL;
    try
    {
        recordset->get_Fields( & pFields );
    }
    catch( _com_error & )
    {
        MessageBox( 0, "Blad 7", 0, 0 );
        CoUninitialize();
    }
   
   
    try
    {
        _bstr_t roww = _bstr_t( pFields->GetItem(( long ) 0 )->GetValue() );
        MessageBox( 0,( LPCSTR ) roww, "Info", 0 );
       
    }
    catch( _com_error & )
    {
        MessageBox( 0, "Blad 8", 0, 0 );
        CoUninitialize();
    }
   
   
   
}

void db_zapisz( LPCSTR tabela, LPCSTR kolumna, int indeks, LPCSTR tresc )
{
   
    db_polacz();
   
   
    try
    {
        _bstr_t query = "UPDATE " +( _bstr_t ) tabela + " SET " +( _bstr_t ) kolumna + " =\"" +( _bstr_t ) tresc + "\"  WHERE ID =" +( _bstr_t ) indeks;
        connection->Execute( query, 0, 0 );
       
    }
    catch( _com_error & )
    {
        MessageBox( 0, "Blad 9", 0, 0 );
        CoUninitialize();
    }
}

//A to juz samo wywoalnie funckji w Main – zaleznie od kopilatora inicjacja main wyglada roznie.
//W moim przypadku to Visual Studio 2012 i wyglada to tak.
//Oczywiscie nalezy dodac obsluge ivents jak w kazdym WinAPI no i sama tresc main ale bez tego tez po kompilacji powinno pojsc
//Ja wlozylem tutaj narazie same funkcje zapisu i odczytu zeby pokazac ze dzialaja

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )

{
   
    int indeks = 1;
    db_odczytaj( "Nazwa Tabeli", "Nazwa Kolumny", indeks ); //oczywiscie int indeks
    db_zapisz( "Nazwa Tabeli ", "Nazwa Kolumny", indeks, "Tresc" ); // oczywiscie int indeks
   
}


Pozdrawiam
berkov



p.s.
Do Moderatorow.
Aby latwiej bylo odnalezc to na necie proponuje zmiane tytulu (jesli to mozliwe) na cos a'la:
[C++, WinAPI] Jak się komunikować z bazą danych MS Access (lub SQL) w WinAPI przy pomocy ADO.
.
P-68736
DejaVu
» 2012-11-07 18:32:39
@up: za długa nazwa :) w każdym razie zamykam temat, bowiem został on już chyba wyczerpany :)
P-68737
1 « 2 »
Poprzednia strona Strona 2 z 2