【问题标题】:How to add field to ADO Recordset on runtime in Delphi 6?如何在 Delphi 6 运行时向 ADO Recordset 添加字段?
【发布时间】:2015-07-26 19:42:31
【问题描述】:

我有一个关于 ADO 记录集的简单问题。我有两个 _RecordSet 正在运行,我正在比较它们的区别。

代码如下。

    function TPT101_ANAF.DataSetKarsilastir(Eski: _Recordset; Yeni: _Recordset) :_Recordset;
    var
    varBookMark:OleVariant;
    begin
        Eski.MoveFirst;
        Yeni.MoveFirst;
        while not Yeni.EOF do
        begin
                Eski.Find('SİCİL = '''+Yeni.Fields['SİCİL'].Value+'''',0, adSearchForward, adBookmarkFirst);
                If (Eski.BOF = True) OR (Eski.EOF = True) Then
                begin
                PT101FDM.EXCELSET.Append;
                **/* i want to add differences to EXCELSET (From Yeni RecordSet)
                /* but the disconnected ADODataset error raising.**  
                PT101FDM.EXCELSET.Insert;
            end;
            Yeni.MoveNext;
    end;
    Result := PT101FDM.EXCELSET.Recordset;

结束;

我应该怎么做才能创建一个新的 RecordSet 并将数据写入其中。

注意:EXCELSET.Recordset 是另一个创建 excel 表的函数,因此它与数据库没有这样的东西。

【问题讨论】:

    标签: excel delphi ado recordset


    【解决方案1】:

    我认为,如果您使用预先存在的电子表格包含您要用于保存数据的工作表,这样做会更容易。然后,您可以构造一个 Sql 语句来创建一个具有您想要的结构的表,并将 TAdoCommand 的 CommandText 设置为该表,然后在其上调用 TAdoCommand.Execute,将工作表添加到电子表格中。 (显然,在 Excel 中手动添加工作表会更容易,但我假设您不想这样做,无论出于何种原因,无论如何,弄清楚如何做这样的事情很有趣/有用“艰难的道路”)。

    下面是一个在现有工作簿中创建新表的最小项目,我希望它足以让您继续前进。

    我发现让它工作的最棘手的一点是让 TAdoConnectionString 正确。特别是,在 IDE 的 AdoConnectionString 构建器中,您需要转到 全部选项卡并在扩展属性条目中输入适当的值,在我的例子中是“Excel 8.0”。

    请注意(无论如何在 D7 中):

    a) 如果您在 IDE 中对连接到它的数据集进行后续更改,并且

    b) 在 IDE 中,TAdoCommand 以某种方式获取创建的 Parameter 对象,在编译和运行程序之前需要将其删除。

    更新我假设一旦您创建了新的表格/工作表,您就可以使用您选择的标准 Delphi Ado 组件来填充它,但为了完整起见,我已经更新了下面的代码以显示一种方法。

    代码

      TForm1 = class(TForm)
        [...]
        ADOConnection1: TADOConnection;
        ADOQuery1: TADOQuery;
        ADOQuery2: TADOQuery;
        ListBox1: TListBox;
        ADOCommand1: TADOCommand;
        Button1: TButton;
        [...]
    const
      scSheetName = 'test';
      scCreateSheet = 'create table %s (id  integer, name char(80))';
      scSelect = 'select * from [%s]';
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      AdoQuery1.Close;
      AdoQuery2.Close;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if ListBox1.Items.IndexOf(scSheetName)  < 0 then begin
        AdoCommand1.CommandText := Format(scCreateSheet, [scSheetName]);
        AdoCommand1.Execute;
      end;
      AdoQuery2.SQL.Text := Format(scSelect, [scSheetName]);
      if AdoQuery2.Active then
        AdoQuery2.Close;
      AdoQuery2.Open;
      if AdoQuery2.RecordCount = 0 then begin
        AdoQuery2.InsertRecord([1, 'Name1']);
        AdoQuery2.InsertRecord([2, 'Name2']);
      end;
      GetTables;
    end;
    
    procedure TForm1.GetTables;
    begin
      AdoConnection1.GetTableNames(ListBox1.Items,True);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      AdoConnection1.Connected := True;
      AdoQuery1.Open; // this just selects whatever is on the first worksheet of the spreadsheet
      GetTables;
    end;
    

    Dfm

    object ADOConnection1: TADOConnection
      ConnectionString =
        'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\aa' +
        'ad7\Ado\Excel\Table1.xls;Mode=Share Deny None;Extended Propertie' +
        's=Excel 8.0;Persist Security Info=False;Jet OLEDB:System databas' +
        'e="";Jet OLEDB:Registry Path="";Jet OLEDB:Database Password="";J' +
        'et OLEDB:Engine Type=35;Jet OLEDB:Database Locking Mode=0;Jet OL' +
        'EDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions' +
        '=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Da' +
        'tabase=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don''t Co' +
        'py Locale on Compact=False;Jet OLEDB:Compact Without Replica Rep' +
        'air=False;Jet OLEDB:SFP=False'
      LoginPrompt = False
      Provider = 'Microsoft.Jet.OLEDB.4.0'
      Left = 16
      Top = 8
    end
    object ADOQuery1: TADOQuery
      Connection = ADOConnection1
      Parameters = <>
      SQL.Strings = (
        'select * from [sheet1$]')
      Left = 48
      Top = 16
    end
    object ADOCommand1: TADOCommand
      CommandText = 'create table test (id  integer,'#13#10'name char(80)'#13#10')'
      Connection = ADOConnection1
      Parameters = <>
      Left = 152
      Top = 16
    end
    object DataSource2: TDataSource
      Left = 184
      Top = 16
    end
    object ADOQuery2: TADOQuery
      Connection = ADOConnection1
      Parameters = <>
      SQL.Strings = (
        'select * from [test]')
      Left = 40
      Top = 288
    end
    

    【讨论】:

    • 嗨MartynA,非常感谢您的关注!您的回答肯定很有帮助,非常感谢。现在工作正常。 供参考: 我如何创建一个克隆 Yeni(RecordSet) 但没有数据且与数据库无关的 _Recordset 对象? 没有意义,但示例代码如下: newRecordSet.Fields[] := Yeni.Fields[]; newRecordSet.**ParentMember**.Connection := nil
    • 我不知道,但我会首先通过调用 CoRecordSet.Create(参见 AdoInt.Pas)创建一个新记录集,然后访问其 Fields 接口并在其上调用 Append(),复制每个 Yeni 的领域依次。我不知道这是否可行,以及除此之外还需要做什么。试试看,如果遇到困难,请发布“我如何……”问题。
    猜你喜欢
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多