delphi7 从1-200组中随机抽取6组数据,抽完了然后从又从1-194组中抽6组,并继续至抽完所有。

vping9211 2012-06-28 03:40:49
delphi7 从1-200组中随机抽取6组数据,抽完了然后从又从1-194组中抽6组,并继续至抽完所有。这个程序怎么写?
...全文
176 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
vping9211 2012-06-29
  • 打赏
  • 举报
回复
谢谢,我试试你上面的代码
广州佬 2012-06-29
  • 打赏
  • 举报
回复
首先,你语句SID:=Random(s1.Count);中的SID能取值的范围仅在0..s1.Count-1这区域,而你“客户信息表”中的 id ,是否也一一对应呢?也就是说,id 是否从 0 排到 记录数-1 ?

是的话,就无需利用循环来“s1.Add(ADOQuery1.FieldByName('id').AsString);”这样来加载到s1或s2,直接用循环控制变量由 0..记录数-1 的值加载即可;

如果不是,那么:
ADOQuery1.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery1.Parameters.ParamByName('id').Value:=inttostr(SID);
又如何能利用 SID 来定位记录呢?!

第二,下面的循环嵌套失去了意义,并且 SID 的取值会重复:
  while (s1.Count div num)>=0 do //取出ispec为真前面的整num组
begin
for i:=0 to num-1 do
begin
SID:=Random(s1.Count);//位置1
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery1.Parameters.ParamByName('id').Value:=inttostr(SID);
ADOQuery1.Delete;//位置2
s1.Delete(SID);//位置3
end;

假设运行到位置1时,取值为2,执行到位置2、3时,将2的项删除;再循环运行到位置1时,SID 还有机会取为2,真这样的话,再运行到位置2、3时,将要去删除不存在的2的项了。另外,由于每次循环到位置1时,s1.Count数值都在变小,那么,SID 就永远没法取得靠在最大 ID 那头的值了(比如,ID最大值是200,第一次SID取值2、然后位置3使得s1.Count数值变为了199,再循环到位置1时,SID就没法取为200了)。

第三,在13楼代码中,又见“Timer1.Enabled:=True;”语句,估计你是希望定时进行抽奖了。但无法看到计时器事件干了些什么,而贴出来的代码,全部均为删除动作,如那边是抽奖,这边是将抽中了的记录删除,那么,删除就没必要用随机数来控制了呀?换了我,将不会去选一笔就删除一笔,这令控制复杂化了,我将会全部选好了后,一次过进行删除。

为什么不试试我在11楼的代码呢?
vping9211 2012-06-28
  • 打赏
  • 举报
回复
这是我最后综合你上面情况然后改动的,不知道为什么无法抽中一条删除数据库也跟着删除一条,老提示错误.明天根据你的程序再改改看.
procedure TfrmYHXT.btnStartClick(Sender: TObject);
var
i,j,k,icount,rcount,SID:Integer;
s1,s2:TStringList;
begin
s1:=TStringList.Create;
s2:=TStringList.Create;
try
Timer1.Enabled:=True;

ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select id from 客户信息表 where isspec<>0');
ADOQuery1.Open;
icount:=ADOQuery1.RecordCount;

ADOQuery2.Close;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('select id from 客户信息表 where isspec= 0');
ADOQuery2.Open;
rcount:=ADOQuery2.RecordCount;

Randomize;
if icount<>0 then
begin
ADOQuery1.First;
for i:=0 to icount-1 do
begin
s1.Add(ADOQuery1.FieldByName('id').AsString);
ADOQuery1.Next;
end;
k:=(s1.Count mod num);
while (s1.Count div num)>=0 do //取出ispec为真前面的整num组
begin
for i:=0 to num-1 do
begin
SID:=Random(s1.Count);
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery1.Parameters.ParamByName('id').Value:=inttostr(SID);
ADOQuery1.Delete;
s1.Delete(SID);
end;
end;
for i:=0 to (s1.Count mod num)-1 do //取出ispec为真的余下的部分组
begin
SID:=Random(s1.Count);
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery1.Parameters.ParamByName('id').Value:=inttostr(SID);
ADOQuery1.Delete;
s1.Delete(SID);
end;
end;
if rcount<>0 then
begin
ADOQuery2.First;
for i:=0 to rcount-1 do
begin
s2.Add(ADOQuery2.FieldByName('id').AsString);
ADOQuery2.Next;
end;
for i:=0 to num-k do //补足上面最后一组的不足部分;
begin
SID:=Random(s1.Count);
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery2.Parameters.ParamByName('id').Value:=inttostr(SID);
ADOQuery2.Delete;
s1.Delete(SID);
end;
while (s2.Count div num)>=0 do //取出ispec为假的前面num组;
begin
for i:=0 to num-1 do
begin
SID:=Random(s2.Count);
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery2.Parameters.ParamByName('id').Value:=inttostr(SID);
ADOQuery2.Delete;
s2.Delete(SID);
end;
end;
for i:=0 to (s1.Count mod num)-1 do //取出ispec为假的剩余组
begin
SID:=Random(s1.Count);
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('delete from 客户信息表 where id=:ID');
ADOQuery1.Parameters.ParamByName('id').Value:=inttostr(SID);
ADOQuery1.Delete;
s1.Delete(SID);
end;
end;
finally
s1.Free;
s2.Free;
end;
end;
广州佬 2012-06-28
  • 打赏
  • 举报
回复
以上代码在 windows_xp + delphi7 编译、运行通过。

用不用到timer控件,这要看你实际需求,如果希望隔一定时间自动抽奖,则可按你代码那样处理。
广州佬 2012-06-28
  • 打赏
  • 举报
回复
新建一个工程、双击窗体后,用下列代码覆盖你的unit1:
unit Unit1;

interface

uses
Windows, SysUtils, Classes, Controls, Forms, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure Button1Click(Sender: TObject);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses DB, ADODB;

var Button1: TButton;
Memo1: TMemo;
ADOQuery1: TADOQuery;
StatusBar1: TStatusBar;

{$R *.dfm}

//抽奖函数(参数为:数据集、显示的字段名、显示数据载体、每组个数)
function Lottery(ADOQuery: TADOQuery;Field_Name: string;ls: TStrings; Num: integer):boolean;
var i,j,Group:integer;
s:Tstringlist;
begin
Result:=false;
if ADOQuery.RecordCount<1 then exit;
ls.Clear;
s:=Tstringlist.Create;
try
Randomize;//初始化
//安排取数据的顺序:
for i:= 0 to ADOQuery.RecordCount-1 do
s.Insert(random(s.Count),inttostr(i));
Group:=ADOQuery.RecordCount div Num;
//满每组个数部分:
for i:= 0 to Group-1 do begin
ls.Append('第 '+inttostr(i+1)+' 组中奖的客户是:');
for j:= 0 to 6 do begin
ADOQuery.RecNo:=strtoint(s.Strings[i*6]);
ls.Append(ADOQuery.FieldByName(Field_Name).AsString);
end;
end;
//不足每组个数部分:
if ADOQuery.RecordCount mod Num >0 then begin
ls.Append('第 '+inttostr(Group*Num+1)+' 组中奖的客户是:');
for i:= 0 to ADOQuery.RecordCount mod Num -1 do begin
ADOQuery.RecNo:=strtoint(s.Strings[Group*Num+i]);
ls.Append(ADOQuery.FieldByName(Field_Name).AsString);
end;
end;
Result:=true;
finally
s.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const cp:array[0..2]of string=('连接串:','SQL串:','字段名:');
var Form:TForm;
edt:array[0..2]of TEdit;
lb:array[0..2]of TLabel;
i:integer;
Okbtn,Clbtn:TButton;
begin
Form:=TForm.Create(self);
try
Form.Position:=poScreenCenter;
Form.Caption:='连接设置';
Okbtn:=TButton.Create(Form);
with Okbtn do begin
Parent:=Form;
Left:=70;
Top:=150;
Caption:='确定';
ModalResult:=mrOk;
end;
Clbtn:=TButton.Create(Form);
with Clbtn do begin
Parent:=Form;
Left:=160;
Top:=150;
Caption:='取消';
ModalResult:=mrCancel;
end;
for i:=0 to 2 do begin
edt[i]:=TEdit.Create(Form);
with edt[i] do begin
Parent:=Form;
Top:=40+i*32;
Left:=120;
end;
lb[i]:=TLabel.Create(Form);
with lb[i] do begin
Parent:=Form;
Top:=43+i*32;
Left:=65;
Caption:=cp[i];
end;
end;
if form.ShowModal=mrOk then begin
ADOQuery1:=TADOQuery.Create(Form);
try
ADOQuery1.ConnectionString:=edt[0].Text;
ADOQuery1.Close;
ADOQuery1.SQL.Text:=edt[1].Text;
try
ADOQuery1.Open;
if Lottery(ADOQuery1,edt[2].Text,Memo1.Lines,6)then
StatusBar1.Panels[0].Text:='抽奖完毕'
else
StatusBar1.Panels[0].Text:='没数据提供抽奖';
except
StatusBar1.Panels[0].Text:='数据集参数设置错误,数据库无法打开';
end;
finally
ADOQuery1.Free;
end;
end;
finally
Form.Free;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Height:=380;
Width:=345;
Position:=poScreenCenter;
Memo1:=TMemo.Create(self);
Memo1.Parent:=Form1;
Memo1.Align:=alLeft;
Button1:=TButton.Create(self);
with Button1 do begin
Parent:=Form1;
Top:=20;
Left:=230;
Caption:='抽奖';
OnClick:=Button1Click;
end;
StatusBar1:=TStatusBar.Create(self);
StatusBar1.Parent:=Form1;
StatusBar1.Panels.Add;
end;

end.
vping9211 2012-06-28
  • 打赏
  • 举报
回复
可以不用到timer控件是吗?
广州佬 2012-06-28
  • 打赏
  • 举报
回复
procedure TForm1.Button1Click(Sender: TObject);
var i,j:integer;
s:Tstringlist;
begin
s:=Tstringlist.Create;
try
Randomize;//初始化
//安排取数据的顺序:
for i:= 0 to 199 do
s.Insert(random(s.Count),inttostr(i));
//前33组数据:
for i:= 0 to 32 do begin
showmessage('第 '+inttostr(i+1)+' 组中奖的客户是:');
for j:= 0 to 5 do begin
ADOQuery1.RecNo:=strtoint(s.Strings[i*6+j]);
showmessage(ADOQuery1.FieldByName('客户名称').AsString);
end;
end;
//第34组数据:
showmessage('第 34 组中奖的客户是:');
ADOQuery1.RecNo:=strtoint(s.Strings[198]);
showmessage(ADOQuery1.FieldByName('客户名称').AsString);
ADOQuery1.RecNo:=strtoint(s.Strings[199]);
showmessage(ADOQuery1.FieldByName('客户名称').AsString);
finally
s.Free;
end;
end;
广州佬 2012-06-28
  • 打赏
  • 举报
回复
呵呵,有明确的数据表的话,可以这样:
procedure TForm1.Button1Click(Sender: TObject);
var i,j:integer;
s:Tstringlist;
begin
s:=Tstringlist.Create;
try
Randomize;//初始化
//安排取数据的顺序:
for i:= 0 to 199 do
s.Insert(random(s.Count),inttostr(i));
//前33组数据:
for i:= 0 to 32 do begin
showmessage('第 '+inttostr(i+1)+' 组中奖的客户是:');
for j:= 0 to 6 do begin
ADOQuery1.RecNo:=strtoint(s.Strings[i*6]);
showmessage(ADOQuery1.FieldByName('客户名称').AsString);
end;
end;
//第34组数据:
showmessage('第 34 组中奖的客户是:');
ADOQuery1.RecNo:=strtoint(s.Strings[198]);
showmessage(ADOQuery1.FieldByName('客户名称').AsString);
ADOQuery1.RecNo:=strtoint(s.Strings[199]);
showmessage(ADOQuery1.FieldByName('客户名称').AsString);
finally
s.Free;
end;
end;
广州佬 2012-06-28
  • 打赏
  • 举报
回复
1、3楼的方式如果称为“删除方式”的话,我下面的就可称为“插入方式”了:
var data:array[0..199] of Variant;//存放着200组数据

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
s:Tstringlist;
begin
s:=Tstringlist.Create;
try
Randomize;//初始化
//安排取数据的顺序:
for i:= 0 to 199 do
s.Insert(random(s.Count),inttostr(i));
//前33组数据:
for i:= 0 to 32 do begin
{
data[strtoint(s.Strings[i*6])]);
data[strtoint(s.Strings[i*6+1])]);
data[strtoint(s.Strings[i*6+2])]);
data[strtoint(s.Strings[i*6+3])]);
data[strtoint(s.Strings[i*6+4])]);
data[strtoint(s.Strings[i*6+5])]);
}
showmessage('取出了第 '+inttostr(i+1)+' 组数据。');
end;
//第34组数据:
{
data[strtoint(s.Strings[198])]);
data[strtoint(s.Strings[199])]);
}
showmessage('取出了第 34 组数据,数据处理完毕。');
finally
s.Free;
end;
end;
vping9211 2012-06-28
  • 打赏
  • 举报
回复
这是我现在的代码,每组抽出来好多重复.
procedure TfrmYHXT.Timer1Timer(Sender: TObject);
var
info:array of Integer;
i,rcount:Integer;
begin
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from 客户信息表');
ADOQuery1.Open;
rcount:=ADOQuery1.RecordCount;
SetLength(info,num);
Randomize;
if rcount=0 then
begin
ShowMessage('客户数为零,无法抽奖');
Timer1.Enabled:=False;
end;
if rcount>=num then
begin
for i:=0 to num-1 do
begin
info[i]:=Random(rcount);
showmessage(IntToStr(info[i]));
end;

end;
if rcount<num then
begin
for i:=0 to rcount-1 do
begin
info[i]:=Random(rcount);

end;
end;

end;

procedure TfrmYHXT.btnStartClick(Sender: TObject);
begin
Timer1.Enabled:=True;
end;

procedure TfrmYHXT.btnStopClick(Sender: TObject);
begin
Timer1.Enabled:=False;
end;

end.
vping9211 2012-06-28
  • 打赏
  • 举报
回复
谁能给我写一段代码啊
haitao 2012-06-28
  • 打赏
  • 举报
回复
反复 调换 1-200组 中的第i组和第random(200)组
然后,取前6组,就行了
再后面的6组,再后面的6组,。。。。
babydog01 2012-06-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
Random()抽呗,200组标号放到列表,每次去一个,然后删除,专业不会重复选取
[/Quote]
就用这个方法,定义一个数据存放数据,抽取后,要删除,注意从高至低删除,以防出错。
s11ss 2012-06-28
  • 打赏
  • 举报
回复
其实还是相当于一次随机抽一个
bdmh 2012-06-28
  • 打赏
  • 举报
回复
Random()抽呗,200组标号放到列表,每次去一个,然后删除,专业不会重复选取

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧