Board index » cppbuilder » Problem getting an Access Recordset

Problem getting an Access Recordset

I'm using a TAccessApplication component to gain access to a Microsoft
Access Database.

I'm trying to use the OpenRecordset method of a _TableDefPtr object but when
I try to assign the result to a Adodb_2k::RecordsetPtr variable, I get an
error every time. I can do it inside the VBE for macros but not in C++
Builder.  What am I doing wrong?!  Its driving me nuts! :(

Here is the code I am using, It is run when a TButton is pressed. The code
successfully creates a new table and field, selects it, then tries to
create/open/get a Recordset object but fails.

DatabasePtr DbObj;
DbObj = AccessApplication1->CurrentDb();
_TableDefPtr TabDef;
TabDef = DbObj->CreateTableDef(WideString("Dummy Data
Table"),TNoParam(),TNoParam(),TNoParam());
_FieldPtr nFiptr;
nFiptr = TabDef->CreateField(WideString("Dummy Data Field"),dbByte,2);
nFiptr->Attributes=dbFixedField;
nFiptr->Required=true;
nFiptr->set_DefaultValue(0);
nFiptr->Size=1;
TabDef->Fields->Append((IDispatch *)nFiptr);
DbObj->TableDefs->Append((IDispatch *)TabDef);
AccessApplication1->DoCmd->SelectObject(acTable,WideString("Dummy Data
Table"),true);
Adodb_2k::RecordsetPtr RecSet1 =
TabDef->OpenRecordset(dbOpenTable,dbDenyWrite);//  <---- Error here!

Here is the VB code that is successful.  It doesn't do the exact same thing
though.  It doesn't create a new TableDef or Field, it just opens an
existing TableDef and creates/opens/gets a new Recordset object.

Dim DbObj As Database
Dim TabDef As TableDef
Dim RecSet1 As Recordset
Set DbObj = Application.CurrentDb
Set TabDef = DbObj.TableDefs.Item("Dummy Data Table")
Set RecSet1 = TabDef.OpenRecordset(dbOpenTable, dbDenyWrite) '<---No Error

Somebody, anybody, please help.

 

Re:Problem getting an Access Recordset


Hi. Leonard!

Is there any specific reason you are not using the standard database
components for this purpose? They are perfectly capable of working with
Access databases.

Questions on the AccessApplication ActiveX object may be most easily
solved by looking at the documentation for the Access ActiveX
interfaces. You may be able to find that at msdn.microsoft.com

------
Mark Cashman (TeamB - C++ Builder), creator of The Temp{*word*203}Doorway at
http://www.temporaldoorway.com
- Original digital art, writing, music and more -
C++ Builder / JBuilder Tips and The C++ Builder Programmer's Webring
(Join us!)
http://www.temporaldoorway.com/programming/index.htm
------

Re:Problem getting an Access Recordset


I am not creating a database application or an application that normally stores data.  What I am trying to do is export some raw
data to Access so that users can analyze and manipulate the data in a manner that they see fit.  The user would not normally be
manipulating the data in such that way otherwise.  In my application, the user does not use/edit the data as if it were a database,
only as raw data.  All I want to do is enable the user to export the data to an application the user may be more familiar with
without having to go through extra steps to set up.  I am also completely unfamiliar with the database components and with databases
and their setups in general.  Somebody else tried to take me through it step-by-step and I failed miserably.  In my case my computer
might not be setup in such a way to allow database communication, and if that is the case, others might not be setup too.

I am also looking for data transfer speed.  The user may end up wanting to send very large amounts of raw data (2G's or more) to
Access.  In general my thoughts were that setting it up as a database may introduce more overhead and more gateway
components/services. In short, I don't really want it to take an hour or more to export/reimport data.

The reason why I choose to post my message to this news group was because the component I am trying to use to send data to Access
came supplied with Builder from Borland.  I didn't import the type library(s). I wouldn't know which libraries to import anyway.

If I sound like a complete moron in any of my explanations or if I don't make any sense, please let me know.  I don't want to
live/program "in-the-dark".

Quote
"Mark Cashman" <mcash...@temporaldoorway.com> wrote in message news:3BC430B5.1ADC7B7F@temporaldoorway.com...
> Hi. Leonard!

> Is there any specific reason you are not using the standard database
> components for this purpose? They are perfectly capable of working with
> Access databases.

> Questions on the AccessApplication ActiveX object may be most easily
> solved by looking at the documentation for the Access ActiveX
> interfaces. You may be able to find that at msdn.microsoft.com

Re:Problem getting an Access Recordset


Hi, Leonard!

Well, it takes as long as it takes to get data from or put data to
Access. It is certainly easier to copy from your application database to
an external database using the C++Builder database components...

Here's a sample form with database components (you can copy this text
and paste it onto a form - the controls will appear)...

object Button1: TButton
  Left = 40
  Top = 32
  Width = 75
  Height = 25
  Caption = 'Button1'
  TabOrder = 0
  OnClick = Button1Click
end
object FromTable: TADOQuery
  ConnectionString =
    'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\My Documents\db1' +

    '.mdb;Persist Security Info=False'
  Parameters = <>
  SQL.Strings = (
    'SELECT * FROM Table1')
  Left = 48
  Top = 96
end
object ToTable: TADOQuery
  ConnectionString =
    'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\My Documents\db2' +

    '.mdb;Mode=ReadWrite;Persist Security Info=False'
  Parameters = <>
  Left = 48
  Top = 136
end

Here's the event handler to copy the data...

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    FromTable->First();

    while (!FromTable->Eof)
    {
        ToTable->Append();

        for
        (
            int FromTableFieldIndex = 0;
            FromTableFieldIndex < FromTable->FieldCount;
            FromTableFieldIndex++
        )
        {
            ToTable->FieldByName
            (

FromTable->Fields->Fields[FromTableFieldIndex]->FieldName

            )->Value =
FromTable->Fields->Fields[FromTableFieldIndex]->Value;
        };

        ToTable->Post();
        FromTable->Next();
    };

Quote
}

Just change the database connection string using the "ConnectionString"
property of the TADOQuery objects to be the appropriate from and to
databases... and everything should work. Now, if the source and
destination databases have different field names, you can simply setup a
lookup table (perhaps with the TStringList class using name=value pairs)
that matches the source table field name to the destination field name.
You can even make a rule that if a field is not found in that table, you
don't copy the data. And, of course, there's more possibilities, if you
need them. But see if this helps.

I hope it does...

------
Mark Cashman (TeamB - C++ Builder), creator of The Temp{*word*203}Doorway at
http://www.temporaldoorway.com
- Original digital art, writing, music and more -
C++ Builder / JBuilder Tips and The C++ Builder Programmer's Webring
(Join us!)
http://www.temporaldoorway.com/programming/index.htm
------

Other Threads