前台接收数据的问题.大虾们,很急啊!!! (50分)

  • 主题发起人 主题发起人 子弹
  • 开始时间 开始时间

子弹

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个简单的com,只有一个函数getdata,它连接了数据库,并且返回一个数据集。
但由于是在com中,它的返回值只能是variant。
可是我怎么样才能在前台把这个variant值转变为数据集,供TDataSource调用呢?
 
clientDataSet.Data;
 
TDataset
_Recordset
都可以啊,你在type library中要use DB/ADODB啊,要不怎么会有以上两个东东?
呵,要一个就可以了啦!
 
这50分是我的了!!!
function TMYADOFuc.MYSQL(const sSQL: WideString): OleVariant;
var
MyADOConnection:VARIANT;
MyRecordSet:VARIANT;
begin
MyADOConnection:=CreateOleObject ('ADODB.Connection');
MyADOConnection.Open('Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=SDMS;Data Source=BH');
MyRecordSet:=CreateOleObject ('ADODB.RecordSet');
MyRecordSet.Open(sSQL,MyADOConnection);
MyRecordset.MoveFirst;
result:= MyRecordset;
end;
open语句中的sSQL为string变量,存储你需要执行的sql语句
 
我在客户端调用我自己写的Com,却总提示‘没有注册类别’是怎么回事啊?
我明明已经在Type Libary中注册过了啊,后来还在组件服务中安装了com,还是提示
一样的错误?
 
你是用什么写的com,我指的是构造模式
客户程序又是怎么调用com的,是不是Import Type Libary啊?
然后加进去一个xxx_TLB文件
说清楚点我可能可以帮你
这应该是一个新的问题了吧?
前面问题的分……
 
To xiaolinj79:
我是想知道中间层返回的值(variant类型),怎么样才能前端的tdatasource利用。
也就是variant怎么样才能与tdataset联系在一起。
我copy下我的代码:
//我写的简单中间层;
unit UntCom;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, ActiveX, Classes, ComObj, dprCom_TLB, StdVcl,UntDM;
type
TMyCOM = class(TTypedComObject, IMyCOM)
protected
function getData: OleVariant;
stdcall;
// procedure DMCreate;
end;

implementation
uses ComServ;
function TMyCOM.getData: OleVariant;
begin
DataModule2.ADOQuery1.sql.add('Select * from DWInfo');
result := DataModule2.ADOQuery1.RecordSet;
end;

initialization
TTypedComObjectFactory.Create(ComServer, TMyCOM, Class_MyCOM,
ciMultiInstance, tmApartment);
end.
//前端调用,返回的数据集能在DBGrid中Show出来就可以了。
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,DBClient, Grids, DBGrids, DB, StdCtrls,Project1_TLB;
type
TForm3 = class(TForm)
Button1: TButton;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form3: TForm3;
implementation
uses comobj;
{$R *.dfm}
procedure TForm3.Button1Click(Sender: TObject);
var
MyDataSet: TClientDataset;
MyTest: Olevariant;
begin
MyTest := CreateComObject(MyCOm) As MyCom ;
MyDataSet.Data := MyTest.GetData;
Datasource1.DataSet := MyDataSet;
end;

end.
//这段代码能Compile,但运行就出错提示‘类没有注册’,大虾们快帮我看看,
分不是问题,50分不够还可以加的。
 
你在Delphi环境中Run菜单下,先UnRegister一下,然后再Register。
另外,我不知道对于你的问题理解是否正确,
对于客户端显示中间层返回的Variant类型数据,可以
TClientDataSet(DBGrid.DataSource.DataSet).Data := 返回值
 
同意楼上的
TClientDataSet(DBGrid.DataSource.DataSet).Data := 返回值
的做法,我上面给的函数的返回值这样附值就可以了
例如
TClientDataSet(DBGrid.DataSource.DataSet).Data := MyCom.MySQL(sSQL);
 
exe方式我不太了解,估计是你的Com没有注册
你的com用Dll吧,应该这种方式我做过,所以清楚
new一个Active Library,再new一个Com Object
在Type Library里面加我上面写给你的方法
注册dll
客户端用Import Type Library,在列表中找到你刚才注册的Com dll
在客户unit里面的第一个use里面加上xxx_TBL,ActivX,ComObj
定义一个接口类变量MyCom:Ixxx(接口名)
在form的create里面加上这么一条语句
MyCom:=coIxxx.Create;
就可以用
Datasource1.DataSet := MyCom.MySQL(sSQL);
传递数据集了
 
TO xiaolinj79:
我是完全按照你的方法做的,可运行是还是提示‘ACCESS Violation at address
0047D632 in module 'dprInvote.exe'.Write of address 0000029’.。
我实在是想不出是哪儿错了。帮帮忙了,最好能给个能运行的代码参考一下。我真是很
无奈,这么简单的调用,搞了怎么久。
 
我想我的例子还保存着吧,把mail给我,我发给你
至于你遇到的问题,我也曾经遇到过,我得仔细回想一下解决的办法了
告诉我单步执行程序停在哪一句
是Datasource1.DataSet := MyCom.MySQL(sSQL);吗?
程序编译通过了吗?
 
To Xiaolinj79:
我的E_Mail : jocjf01@163.net。
//我的中间层函数;
function TMyCom.GetData(const sSql: WideString): OleVariant;
var
MyADOConnection:VARIANT;
MyRecordSet:OleVARIANT;
begin
MyADOConnection:=CreateOleObject ('ADODB.Connection');
MyADOConnection.Open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:/Com_Study/SysReg.mdb;Persist Security Info=False');
MyRecordSet:=CreateOleObject ('ADODB.RecordSet');
MyRecordSet.Open(sSQL,MyADOConnection);
MyRecordset.MoveFirst;
result:= MyRecordset;
end;
//整个函数都能运行完,但在End退出时出错了。
 
晚上有个约,回来再给你发例子吧,可能会晚一点:)
唉,为了50分,累死我也:)
因为我很缺分啊
 
服务端:
function getdata(): IDispatch;
begin
DataModule2.ADOQuery1.sql.add('Select * from DWInfo');
result := DataModule2.ADOQuery1.RecordSet;
end;

客户端:
ADOQuery1.Recordset := 接口.GetData();
就可以了。(TDataSource.DataSet -> ADOQuery1)
 
昨天回来得太晚了,程序刚发过去了
 
To xiaolin79:
我没收到啊!!,我的E-mail: jocjf01@163.net。
你把这个地址Copy到收件人上,就不会错了。你的程序不会很大把。
多次的烦你,请谅解!!!
 
错误是在客户端。
我Copy下我的代码:
//客户端代码
procedure TForm1.Button1Click(Sender: TObject);
var
TestCom: IMycom;
MyDataset: TClientDataSet;
s: olevariant;
begin
TestCom := CoMyCom.Create;
s := Testcom.GetData('Select * from pXTDM');
TClientDataSet(DataSource1.DataSet).Data := s;
end;

运行到TClientDataSet(DataSource1.DataSet).Data := s;时报错。
 
softdog:
我试了你的方法,但编译时有错误:
Incompatible types: 'IDispatch' and '_Recordset'
不知为什么?
 
不是吧,我再发了一次
程序不大,是一个测试程序
测试程序的时候用Ctrl F7查看变量的值
对你对错误的起因有帮助
主要看一下s的值对了没有
 
后退
顶部