我在查询后得到的内容如下:
任务单号 物料名称 理论值 实际值
1 水 20 22
1 砂子 500 502
1 水泥 300 302
..
2 水 30 32
2 砂子 500 502
2 水泥 300 302
现客户需要如下格式:
任务单号 水理论值 水实际值 砂子理论值 砂子实际值 水泥理论值 水泥实际值 ...
1 20 22 500 502 300 302
2 30 32 500 502 300 302好像是交叉表问题,请问如何转换?SQL语句如何写!使用环境:D6+access+ADO
任务单号 物料名称 理论值 实际值
1 水 20 22
1 砂子 500 502
1 水泥 300 302
..
2 水 30 32
2 砂子 500 502
2 水泥 300 302
现客户需要如下格式:
任务单号 水理论值 水实际值 砂子理论值 砂子实际值 水泥理论值 水泥实际值 ...
1 20 22 500 502 300 302
2 30 32 500 502 300 302好像是交叉表问题,请问如何转换?SQL语句如何写!使用环境:D6+access+ADO
select * from table a where wuliaoname='shui'
left join
(
select * from table b where wuliaoname='shazi' and a.no=b.no
)
采用数据集的方式,完成起来好像不可能。
建议输出到Excel里面去作。这样就简单多了。
哪位有时间的老兄认真试试?
这个问题还是有点意义的。
(List_NO int,
Water_T int,
Water_A int,
Sand_T int,
Sand_A int,
Cement_T int,
Cement_A int)
循环开始:
Insert into #TempTable
values(
‘1’,
(select 理论值 from 表名 where 任务单号='1' and 物料名称='水'),
(select 实际值 from 表名 where 任务单号='1' and 物料名称='水'),
(select 理论值 from 表名 where 任务单号='1' and 物料名称='沙子'),
(select 实际值 from 表名 where 任务单号='1' and 物料名称='沙子'),
(select 理论值 from 表名 where 任务单号='1' and 物料名称='水泥'),
(select 实际值 from 表名 where 任务单号='1' and 物料名称='水泥'))
循环结束
select
List_NO as 任务单号,
Water_T as 水理论值,
Water_A as 水实际值,
Sand_T as 沙子理论值,
Sand_A as 沙子实际值,
Cement_T 水泥理论值,
Cement_A 水泥实际值
from #TempTable
var
TempTable:TatClientDataSet;
begin
TempTable:=nil;
Result:=nil;
if AFieldDefs<>nil then
begin
try
TempTable:=TatClientDataSet.Create(Application);
TempTable.FieldDefs.Assign(AFieldDefs);
TempTable.CreateDataSet;
Result:=(TempTable as TDataSet);
Except
if TempTable<>nil then
TempTable.Free;
Result:=nil;
raise;
end
end;
end;
{
SouDataset源数据集
ColField交叉表动态列字段
RowField交叉表行字段
DataField数据字段
}
function GenCrossTable(SouDataset:tdataset;ColField,RowField,DataField:string):tdataset;
var
Vdataset:tdataset;
tmpdataset:tatclientdataset;
DataSource:tdatasource;
tmpstrs:tstrings;
rowval,colval,dataval:string;
i,j:integer;
datatype:TFieldType;
DataSize:integer;
begin
result:=nil;
if (ColField=‘‘) or(RowField=‘‘)or(DataField=‘‘) then
showmessage(‘All Field not be NULL!‘)
else
begin
if (ColField=RowField)
or(ColField=DataField)
or(RowField=DataField) then
showmessage(‘All Field not be Equ!‘)
else
if (self.SouDataSet.FieldByName(ColField).DataType=ftString)
or (self.SouDataSet.FieldByName(ColField).DataType<>ftWideString)
or (self.SouDataSet.FieldByName(ColField).DataType<>ftFixedChar)
or (self.SouDataSet.FieldByName(ColField).DataType<>ftMemo)
or (self.SouDataSet.FieldByName(ColField).DataType<>ftFmtMemo) then
begin
try
tmpstrs:=tstringlist.Create;
Vdataset:=SouDataSet;
Vdataset.First;
for i:=0 to Vdataset.RecordCount-1 do
begin
if (varisnull(SouDataSet.FieldValues[colfield])=false) and (SouDataSet.FieldValues[colfield]<>‘‘) then
if tmpstrs.IndexOf(SouDataSet.FieldValues[colfield])=-1 then
begin
tmpstrs.Add(SouDataSet.FieldValues[colfield]);
end;
Vdataset.Next;
end;
//生成动态列标题
tmpdataset:=TClientDataSet.Create(Self);
tmpdataset.FieldDefs.Add(rowfield,ftstring,50,False);
for i:=0 to tmpstrs.Count-1 do
begin
with tmpdataset.FieldDefs do
begin
Add(tmpstrs.Strings[i],ftInteger,0,False);
end;
end;
tmpdataset.FieldDefs.Add(‘Sum‘,ftInteger,0,False);
DataSource:=tdatasource.Create(self);
DataSource.DataSet:=tmpdataset;
with DataSource do
begin
dataset:=Createtmptab(tmpdataset.FieldDefs);
dataset.Open;
end;
//建立临时表
Vdataset.First;
for i:=0 to Vdataset.RecordCount-1 do
begin
rowval:=SouDataSet.fieldbyname(rowfield).AsString;
colval:=SouDataSet.fieldbyname(colfield).AsString;
dataval:=SouDataSet.fieldbyname(datafield).AsString;
if dataval=‘‘ then dataval:=‘0‘;
if DataSource.DataSet.Locate(rowfield,rowval,[loPartialKey]) then
begin
DataSource.DataSet.Edit;
DataSource.DataSet.FieldByName(colval).AsString:=dataval;
DataSource.DataSet.FieldByName(‘Sum‘).AsInteger:=
DataSource.DataSet.FieldByName(‘Sum‘).AsInteger+strtoint(dataval);
DataSource.DataSet.Post;
end
else
begin
DataSource.DataSet.Append;
DataSource.DataSet.FieldByName(rowfield).AsString:=rowval;
for j:=1 to DataSource.DataSet.Fields.Count-1 do
DataSource.DataSet.Fields[j].AsCurrency:=0;
DataSource.DataSet.FieldByName(colval).AsString:=dataval;
DataSource.DataSet.FieldByName(‘Sum‘).AsString:=dataval;
DataSource.DataSet.Post;
end;
Vdataset.Next;
end;
result:=DataSource.DataSet;
//生成交叉表数据集
tmpstrs.Free;
except
end;
end
else
showmessage(‘ColField Must be of Type String!‘) ;
end;
end;
在ACcess中可以用临时表吗?我还不会用。另外我的物料名称在我写程序时并不知道是什么,所以你提供的SQL语句没办法在程序中实现,而且我不知道有多少种物料会出现。
to sxzz:
每个任务的物料数固定,但每个任务的物料名称可能不一样,如在第一个任务当中,用户可能使用的水泥1,而在第二个任务当中,用户可能用水泥2,水泥3等。
to hcjhjy:
能把你实现的方法告诉我吗?有源代码更好,谢谢!这关系到饭碗问题;急!
to zbderek:
谢谢你提供的方法,我研究一下代码。SouDataset源数据集
ColField交叉表动态列字段 在我提供的例子中是“物料名称“吗?
RowField交叉表行字段 是”任务单号“吗?
DataField数据字段 是”理论值“或”实际值“。另这能在Access中使用吗?我的开发环境为D6+Access+ADO.
例如下:
物料名称 单元号 通道号 模式 显示位置 电流
水 A0 1 1 1
外加剂1 A8 1 2 2
外加剂2 A8 2 2 3
粉煤灰 B0 1 2 4
水泥 B0 2 2 5
砂子 C0 1 1 6
石子1 c0 1 1 7
石子2 D0 1 2 8
石子3 E0 1 2 9
石子4 E0 2 2 10
即每一个客户一签合同之后,其物料是固定的,但每一个客户的配置都有可能不一样。配置一定,配方就跟着定了。但配方中有的物料是可选择的。例如:在A8和B0单元上就有选择存在。例如:水泥,用户在生产中可能选择水泥1,或者水泥2,水泥3等等。因为是由客户配置,所以我在建配方时给了一个选择号。如下:
配方表头省略。配方子表:
物料名称 选择号 标准用量
水
外加剂1
外加剂2
粉煤灰
水泥 1,2,3..(只能选一种使用,在显示界面上应显示为水泥1,或者水泥2,水泥3,在数据库中也必须如实保存)
砂子
石子1
石子2
石子3
石子4
把配方传给下位机生产后。采集数据时,我用了主从表,来保存每一车的物料消耗信息。
如下:
任务单号 物料名称 理论值 实际值
1 水 20 22
1 砂子 500 502
1 水泥1 300 302
..
2 水 30 32
2 砂子 500 502
2 水泥2 300 302
现客户需要的报表要象如下格式:
任务单号 水理论值 水实际值 砂子理论值 砂子实际值 水泥1理论值 水泥1实际值 水泥2理论值 水泥2实际值...
1 20 22 500 502 300 302 0 0
2 30 32 500 502 0 0 300 302在每一车中,其中物料名称可能都一样,但有可能不一样。因此在做报表时,有可能同时会出现水泥1理论值
、水泥1实际值、水泥2理论值、水泥3理论值等字段内容。至多有2种物料用户是可选择的,可选择的情况不会超过6种。
因为,事先我并不知道用户会使用什么物料。因此感觉很难,不知道如何下手。
我的老板说很容易,他没有做过WINDOWS程序。他是在DOS下用C语言开发的,而且每一个客户都有固定的的配置,客户不同,他就要修改源程序。请各位提供解决思路。