DBGrid相同数据合并成一个格[最好用Delphi回答]

最近遇到一个软件:
DBGrid控件显示列的时候,其相同值合并为一个值显示
界面很美观;
即:
在一列中,如果遇到相同值时,便合并为一个单元格
跟Excel中的功能差不多,我想问一问哪位计算机程序高手告诉我这个问题;
谢谢
我不是希望在Excel中显示合并单元格
而是用界面控件直接显示

另外:请bugmenot同志详细说明一下ehlib到底用哪个版本的?怎样安装?安装后怎样使用?附原代码哦
感谢各位:如果帮我解决这个问题,分值再加

A 1 1
A 1 2
A 1 3
B 1 1
B 2 2
B 2 3

显示为:

A 1 1
-----2
-----3
B 1 1
---2 2
-----3
其中'-'为空格
谢谢各位

时间关系,无法写具体控件,以下对你有帮助:

☆☆ 本过程能够将TDBGridEh的多层表头导出到Excel中,并且还能够将给定字段的相同的值合并一起,例如:

(本地抄袭者死!早晨一则精华被抄骗得300分,郁闷!)

procedure BatchDBGridEhDataToExcel(DBGrid:TDBGridEh;Title:string;DrawGridLine:Boolean;
RangeFields:TStringList);

该过程将TDBGridEh中的数据导出到Excel中。本过程能够将TDBGridEh的多层表头导出到Excel中,并且还能够将给定字段的相同的值合并一起,例如:

参数:

DBGrid:TDBGridEh为要导出数据的网格控件,Title为报表的标题,DrawGridLine控制是否绘制网格线,RangeFields为需要合并数据的字段列表。

在“打印”按钮的OnClick事件中填写如下代码:

var
RangeFields:TStringList;
begin
file://true为绘制网格线//
RangeFields:=TStringList.Create;
RangeFields.Add('TJDWMC');
try
if RadioButton1.Checked then
BatchDBGridEhDataToExcel(DBGrid_JTGS,Caption,true,RangeFields)
else
BatchDBGridEhDataToExcel(DBGrid_LYJ,Caption,true,RangeFields);
finally
RangeFields.Free;
end;
end;

执行后启动Excel程序,显示界面如下所示:

注意:在合并网格时会出现是“否合并网格”对话框,请电击“是”即可。

需要声明的常量:

const
file://Excel用到的常量//
xlHairline = $00000001;
xlMedium = $FFFFEFD6;
xlThick = $00000004;
xlThin = $00000002;
const
file://Excel用到的常量//
xlContinuous = $00000001;
xlDash = $FFFFEFED;
xlDashDot = $00000004;
xlDashDotDot = $00000005;
xlDot = $FFFFEFEA;
xlDouble = $FFFFEFE9;
xlSlantDashDot = $0000000D;
xlLineStyleNone = $FFFFEFD2;
const
xlAll = $FFFFEFF8;
xlAutomatic = $FFFFEFF7;
xlBoth = $00000001;
xlCenter = $FFFFEFF4;
xlChecker = $00000009;
xlCircle = $00000008;
xlCorner = $00000002;
xlCrissCross = $00000010;
xlCross = $00000004;
xlDiamond = $00000002;
xlDistributed = $FFFFEFEB;
xlDoubleAccounting = $00000005;
xlFixedValue = $00000001;
xlFormats = $FFFFEFE6;
xlGray16 = $00000011;
xlGray8 = $00000012;
xlGrid = $0000000F;
xlHigh = $FFFFEFE1;
xlInside = $00000002;
xlJustify = $FFFFEFDE;
xlLightDown = $0000000D;
xlLightHorizontal = $0000000B;
xlLightUp = $0000000E;
xlLightVertical = $0000000C;
xlLow = $FFFFEFDA;
xlManual = $FFFFEFD9;
xlMinusValues = $00000003;
xlModule = $FFFFEFD3;
xlNextToAxis = $00000004;
xlNone = $FFFFEFD2;
xlNotes = $FFFFEFD0;
xlOff = $FFFFEFCE;
xlOn = $00000001;
xlPercent = $00000002;
xlPlus = $00000009;
xlPlusValues = $00000002;
xlSemiGray75 = $0000000A;
xlShowLabel = $00000004;
xlShowLabelAndPercent = $00000005;
xlShowPercent = $00000003;
xlShowValue = $00000002;
xlSimple = $FFFFEFC6;
xlSingle = $00000002;
xlSingleAccounting = $00000004;
xlSolid = $00000001;
xlSquare = $00000001;
xlStar = $00000005;
xlStError = $00000004;
xlToolbarButton = $00000002;
xlTriangle = $00000003;
xlGray25 = $FFFFEFE4;
xlGray50 = $FFFFEFE3;
xlGray75 = $FFFFEFE2;
xlBottom = $FFFFEFF5;
xlLeft = $FFFFEFDD;
xlRight = $FFFFEFC8;
xlTop = $FFFFEFC0;
xl3DBar = $FFFFEFFD;
xl3DSurface = $FFFFEFF9;
xlBar = $00000002;
xlColumn = $00000003;
xlCombination = $FFFFEFF1;
xlCustom = $FFFFEFEE;
xlDefaultAutoFormat = $FFFFFFFF;
xlMaximum = $00000002;
xlMinimum = $00000004;
xlOpaque = $00000003;
xlTransparent = $00000002;
xlBidi = $FFFFEC78;
xlLatin = $FFFFEC77;
xlContext = $FFFFEC76;
xlLTR = $FFFFEC75;
xlRTL = $FFFFEC74;
xlFullScript = $00000001;
xlPartialScript = $00000002;
xlMixedScript = $00000003;
xlMixedAuthorizedScript = $00000004;
xlVisualCursor = $00000002;
xlLogicalCursor = $00000001;
xlSystem = $00000001;
xlPartial = $00000003;
xlHindiNumerals = $00000003;
xlBidiCalendar = $00000003;
xlGregorian = $00000002;
xlComplete = $00000004;
xlScale = $00000003;
xlClosed = $00000003;
xlColor1 = $00000007;
xlColor2 = $00000008;
xlColor3 = $00000009;
xlConstants = $00000002;
xlContents = $00000002;
xlBelow = $00000001;
xlCascade = $00000007;
xlCenterAcrossSelection = $00000007;
xlChart4 = $00000002;
xlChartSeries = $00000011;
xlChartShort = $00000006;
xlChartTitles = $00000012;
xlClassic1 = $00000001;
xlClassic2 = $00000002;
xlClassic3 = $00000003;
xl3DEffects1 = $0000000D;
xl3DEffects2 = $0000000E;
xlAbove = $00000000;
xlAccounting1 = $00000004;
xlAccounting2 = $00000005;
xlAccounting3 = $00000006;
xlAccounting4 = $00000011;
xlAdd = $00000002;
xlDebugCodePane = $0000000D;
xlDesktop = $00000009;
xlDirect = $00000001;
xlDivide = $00000005;
xlDoubleClosed = $00000005;
xlDoubleOpen = $00000004;
xlDoubleQuote = $00000001;
xlEntireChart = $00000014;
xlExcelMenus = $00000001;
xlExtended = $00000003;
xlFill = $00000005;
xlFirst = $00000000;
xlFloating = $00000005;
xlFormula = $00000005;
xlGeneral = $00000001;
xlGridline = $00000016;
xlIcons = $00000001;
xlImmediatePane = $0000000C;
xlInteger = $00000002;
xlLast = $00000001;
xlLastCell = $0000000B;
xlList1 = $0000000A;
xlList2 = $0000000B;
xlList3 = $0000000C;
xlLocalFormat1 = $0000000F;
xlLocalFormat2 = $00000010;
xlLong = $00000003;
xlLotusHelp = $00000002;
xlMacrosheetCell = $00000007;
xlMixed = $00000002;
xlMultiply = $00000004;
xlNarrow = $00000001;
xlNoDocuments = $00000003;
xlOpen = $00000002;
xlOutside = $00000003;
xlReference = $00000004;
xlSemiautomatic = $00000002;
xlShort = $00000001;
xlSingleQuote = $00000002;
xlStrict = $00000002;
xlSubtract = $00000003;
xlTextBox = $00000010;
xlTiled = $00000001;
xlTitleBar = $00000008;
xlToolbar = $00000001;
xlVisible = $0000000C;
xlWatchPane = $0000000B;
xlWide = $00000003;
xlWorkbookTab = $00000006;
xlWorksheet4 = $00000001;
xlWorksheetCell = $00000003;
xlWorksheetShort = $00000005;
xlAllExceptBorders = $00000006;
xlLeftToRight = $00000002;
xlTopToBottom = $00000001;
xlVeryHidden = $00000002;
xlDrawingObject = $0000000E;
const

{ The list of VtFont styles }

{ FontStyleConstants }

VtFontStyleBold = 1;
VtFontStyleItalic = 2;
VtFontStyleOutline = 4;

{ The list of VtFont effects }

{ FontEffectsConstants }

VtFontEffectStrikeThrough = 256;
VtFontEffectUnderline = 512;

-------------------------------------------------------------------------------------------------------

procedure SetTitleInExcel(Sheet:OleVariant;
FirstRow,FirstCol,LastRow,LastCol:integer;Title:string);
var
RangeStr:string;
Range:Variant;
begin
Sheet.Activate;
RangeStr:=GetRangStr(FirstRow,FirstCol,LastRow,LastCol);
Range:=Sheet.Range[RangeStr];
Range.Merge(true);
Range.Font.Size:=14;
Range.Font.Name:='黑体';
Range.Font.FontStyle:=VtFontStyleBold;
Range.HorizontalAlignment := xlCenter;
Range.VerticalAlignment := xlCenter;
Range.Value:=Title;
end;

function GetRangStr(FirstRow,FirstCol,LastRow,LastCol:integer):string;
var
iA,iB:integer;
begin
result:=';
if (FirstRow<1)or(LastRow<1)or(LastRow<1)or(LastCol<1) then
Exit;

iA:=FirstCol div 26;
iB:=FirstCol mod 26;
if iB=0 then
begin
iA:=iA-1;
iB:=26;
end;

if iA=0 then
result:=Chr(Ord('A')+iB-1)+IntToStr(FirstRow)+':'
else
result:=Chr(Ord('A')+iA-1)+Chr(Ord('A')+iB-1)+IntToStr(FirstRow)+':';

iA:=LastCol div 26;
iB:=LastCol mod 26;
if iB=0 then
begin
iA:=iA-1;
iB:=26;
end;

if iA=0 then
result:=result+Chr(Ord('A')+iB-1)+IntToStr(LastRow)
else
result:=result+Chr(Ord('A')+iA-1)+Chr(Ord('A')+iB-1)+IntToStr(LastRow);
end;

procedure DrawGridInExcel(Sheet:OleVariant;
FirstRow,FirstCol,LastRow,LastCol:integer);
var
RangeStr:string;
Range:Variant;
begin
Sheet.Activate;
RangeStr:=GetRangStr(FirstRow,FirstCol,LastRow,LastCol);
Range:=Sheet.Range[RangeStr];
Range.Columns.Interior.ColorIndex:=0;
Range.Borders.LineStyle:=xlHairline;
Range.Font.Size:=8;
Range.Font.Name:='楷体_GB2312';
end;

procedure TransMuiltTitleStr(Text: string;List:TStrings);
var
str:string;
Index:integer;
begin
str:=Text;
List.Clear;
Index:=Pos('|',str);
while Index>0 do
begin
List.Add(Copy(str,1,Index-1));
str:=Copy(str,Index+1,Length(str)-Index);
Index:=Pos('|',str);
end;
if Index=0 then
List.Add(str);
end;

Function My_DataSetToExcelSheet(DataSet:TDataSet;m_Fields:tstringlist;Sheet:OleVariant;
RangeFields:TStrings;DrawGridLine:Boolean;var FirstRow,FirstCol:integer): Boolean;
var
DataFirstRow,Row,Col,i,j :Integer;
BK:TBookMark;
LastValue,CurrentValue:string;
RangeStr:string;
Range:Variant;
RangeFirstRow,RangeFirstCol:integer;
List:TStringList; file://用于存储复合标题各个行的字符串列表//
MaxTVCount:integer;//标题最大纵向行数//
begin
Result := False;
if not Dataset.Active then exit;
BK:=DataSet.GetBookMark;
DataSet.DisableControls;
Sheet.Activate;
try
file://定制复杂列标题//
MaxTVCount:=0;
List:=TStringList.Create;
try
Col:=FirstCol;
for i:=0 to m_Fields.Count-1 do
begin
Row:=FirstRow;

TransMuiltTitleStr(DataSet.FieldByName(m_Fields.Strings[i]).DisplayLabel,List);
if List.Count>MaxTVCount then
MaxTVCount:=List.Count;

for j:=0 to List.Count-1 do
begin
Sheet.Cells(Row,Col) :=List.Strings[j];
Inc(Row);
end;

Inc(Col);
end;
finally
List.Free;
end;

file://绘制网格//
if DrawGridLine then
begin
DrawGridInExcel(Sheet,FirstRow,1,FirstRow+DataSet.RecordCount+MaxTVCount-1,
m_Fields.Count);
end;
file://横向合并标题网格//
for i:=FirstRow to FirstRow+MaxTVCount-1 do
begin
file://记录当前行//
Row:=i;
file://如果列数大于零则计算//
if m_Fields.Count>0 then
begin
RangeFirstCol:=1;
LastValue:=Sheet.Cells.Item[Row,RangeFirstCol];

for j:=2 to m_Fields.Count do
begin
CurrentValue:=Sheet.Cells.Item[Row,j];
if CurrentValue<>LastValue then
begin
file://合并单元格//
if LastValue<>' then
begin
RangeStr:=GetRangStr(Row,RangeFirstCol,Row,j-1);
Range:=Sheet.Range[RangeStr];
file://Range.Merge(false);
Range.mergecells:=true;
Range.WrapText:=true;
Range.HorizontalAlignment := xlCenter;
Range.VerticalAlignment := xlCenter;
Range.Value:=LastValue;
end;

RangeFirstCol:=j;
LastValue:=Sheet.Cells.Item[Row,RangeFirstCol];
end;
end;
file://合并单元格//
if LastValue<>' then
begin
RangeStr:=GetRangStr(Row,RangeFirstCol,Row,m_Fields.Count);
Range:=Sheet.Range[RangeStr];
// Range.Merge(false);
Range.mergecells:=true;
Range.WrapText:=true;
Range.HorizontalAlignment := xlCenter;
Range.VerticalAlignment := xlCenter;
Range.Value:=LastValue;
end;

RangeFirstCol:=m_Fields.Count+1;
LastValue:=Sheet.Cells.Item[Row,RangeFirstCol];
end;
end;
file://纵向合并标题网格,将纵向最后一个不为空值的格与其下面所有空格合并到一起//
if MaxTVCount>1 then
for i:=1 to m_Fields.Count do
for j:=FirstRow+MaxTVCount-1 downto FirstRow do
begin
CurrentValue:=Sheet.Cells.Item[j,i];
if CurrentValue<>' then
begin
if j<>FirstRow+MaxTVCount-1 then
begin
file://合并单元格//
RangeStr:=GetRangStr(j,i,FirstRow+MaxTVCount-1,i);
Range:=Sheet.Range[RangeStr];
Range.Merge(false);
Range.WrapText:=true;
Range.HorizontalAlignment := xlCenter;
Range.VerticalAlignment := xlCenter;
Range.Value:=CurrentValue;
end;
Break;
end;
end;

file://数据的第一条的索引号//
DataFirstRow:=FirstRow+MaxTVCount;

Row:=DataFirstRow;

file://填写表格内容//
DataSet.First;
while Not DataSet.Eof do
begin
Col:=1;

for i:=0 to m_Fields.count-1 do
begin
Sheet.Cells(Row,Col):=DataSet.FieldByName(m_Fields.Strings[i]).AsString;
Inc(Col);
end;

Row:=Row+1;

DataSet.Next;
end;

if m_Fields.count>0 then
Col:=Col-1;

file://合并项目字段的值//
for i:=0 to RangeFields.Count-1 do
begin
Col:=m_Fields.IndexOf(RangeFields.Strings[i])+1;
if DataSet.RecordCount>0 then
begin
RangeFirstRow:=DataFirstRow;
LastValue:=Sheet.Cells.Item[RangeFirstRow,Col];

for j:=1 to DataSet.RecordCount-1 do
begin
CurrentValue:=Sheet.Cells.Item[DataFirstRow+j,Col];
if CurrentValue<>LastValue then
begin
file://合并单元格//
RangeStr:=GetRangStr(RangeFirstRow,Col,DataFirstRow+j-1,Col);
Range:=Sheet.Range[RangeStr];
Range.Merge(false);
Range.WrapText:=true;
Range.HorizontalAlignment := xlCenter;
Range.VerticalAlignment := xlCenter;
Range.Value:=LastValue;

RangeFirstRow:=DataFirstRow+j;
LastValue:=Sheet.Cells.Item[RangeFirstRow,Col];
end;
end;
file://合并单元格//
RangeStr:=GetRangStr(RangeFirstRow,Col,DataFirstRow+DataSet.RecordCount-1,Col);
Range:=Sheet.Range[RangeStr];
Range.Merge(false);
Range.WrapText:=true;
Range.HorizontalAlignment := xlCenter;
Range.VerticalAlignment := xlCenter;
Range.Value:=LastValue;

RangeFirstRow:=DataFirstRow+DataSet.RecordCount;
LastValue:=Sheet.Cells.Item[RangeFirstRow,Col];
end;
end;

Result := True;
finally
DataSet.GotoBookMark(BK);
DataSet.EnableControls;
end;
end;

procedure BatchDBGridEhDataToExcel(DBGrid:TDBGridEh;Title:string;DrawGridLine:Boolean;
RangeFields:TStringList);
var
s:tstringlist;
i:integer;
begin
if not DBGrid.DataSource.DataSet.active then
begin
MessageDlg('主结果集没有打开!',mtWarning,[mbok],0);
exit;
end;
s:=tstringlist.create;
try
for i:=0 to DBGrid.Columns.Count-1 do
begin
s.Add(DBGrid.Columns[i].FieldName);
DBGrid.DataSource.DataSet.FieldByName(
DBGrid.Columns[i].FieldName).DisplayLabel:=
DBGrid.Columns[i].Title.Caption;
end;
My_DataSetToExcel(DBGrid.DataSource.DataSet,s,RangeFields,DrawGridLine,true,
Title,');
finally
s.free;
end;
end;
温馨提示:内容为网友见解,仅供参考
第1个回答  2006-03-04
http://www.china-askpro.com/vbasic23.shtml
(vb相关的专家网站,站长会很乐意解答你的疑问)
例如:

表单的TCURRENCY类型,如何选择货币种类

如何使Tstringgrid中的数字都靠右

如何给DBGRID中特殊的字段赋予不同的颜色

TStringGrid中的单元格,如何用程序语句取值和赋值

出错提示为"IDEX IS READ ONLY"

TStringGrid控件在一个单元失去焦点时作出事件响应

如何设置DBGrid的ScrollBar状态

如何在数据网格(DBGrid)中插入其他的可视控件

如何锁定Delphi的DBGRID的列
第2个回答  2006-03-04
表单的TCURRENCY类型,如何选择货币种类

如何使Tstringgrid中的数字都靠右

如何给DBGRID中特殊的字段赋予不同的颜色

TStringGrid中的单元格,如何用程序语句取值和赋值

出错提示为"IDEX IS READ ONLY"

TStringGrid控件在一个单元失去焦点时作出事件响应

如何设置DBGrid的ScrollBar状态

如何在数据网格(DBGrid)中插入其他的可视控件

如何锁定Delphi的DBGRID的列
第3个回答  2006-03-05
其实最好用sql来解决.反正delphi也可以调用的

用group by就可以
第4个回答  2006-03-09
你的问题我没看明白不过看上去应该是不难!

名称 名称 名称
A 1 2
B 1 2
C 1 6
D 2 7

你要的显示是什么样的呢?

------------------------------------------------

我认为把下面的掩盖住就可以啦
用 DrawDataCell事件+TDBGrid(Sender).Canvas.FillRect(Rect);
对比是否跟上一个数据相同然后 掩盖,HOHO~

------------------------------------------------
无聊再说两句,这样做真的美观吗?我怎么就没看出
来美在哪里呢?呵呵 :)
第5个回答  2006-03-06
ehlib这个控件支持。

DBGrid相同数据合并成一个格[最好用Delphi回答]
procedure BatchDBGridEhDataToExcel(DBGrid:TDBGridEh;Title:string;DrawGridLine:Boolean; RangeFields:TStringList); 该过程将TDBGridEh中的数据导出到Excel中。本过程能够将TDBGridEh的多层表头导出到Excel中,并且还能够将给定字段的相同的值合并一起,例如:参数: DBGrid:TDBGridEh为要导出数据的网格控件,Title为报表的...

Delphi怎么把同一个数据表中相同字段的记录合并到一起
对不起,TDBGrid不支持记录合并,你可以改用其它数据展示控件,比如DevExpress控件包。

delphi中的TDBGrid的问题
这种数据编辑与数据浏览界面,完全可以合二为一,放在一个窗体上.比如左边是编辑界面,右边是浏览界面.没有必要使用那么多的窗体.DBGRID组件没有列双击事件,只有列单击事件.它的双击事件是针整个DBGRID的,这就是说双击DBGRID的边框也会触发双击事件.这样就不准确了,而列单击事件,是相当准确的,当单击某行的...

Delphi DBGrid 组件 行中数据可以求和吗
可以用计算字段来做的!在DBGRID的后台连接的dbtable 或QUERY,里加一个计算字段 然后在query的的计算事件中写入表达式即可!

delphi 如何将一串数据添加到dbgrid一列中,像这种效果?
DBGrid是用来连接数据库的。所以,你只要连接好数据库,数据库中有什么数据,DBGrid就显示什么。因此,你的操作实质上是对数据库的操作。要想操作数据库,可以用TQuery、TTable、TAdoQuery、TADOTable等,连接数据库,用TDataSource作为TQuery与DBGrid之间的连接。

delphi中的dbgrid数据操作
5 设置 datasource1的dataset 属性为 adoquery1 6.再放一个 DBNavigator1 设置 datasource=datasource1 7.设置 dbgrid1的 datasource=datasource1 保存 运行 即可.注 dbnavigator 控件 中有自带代码 ...可实现 添加,删除,修改..等 要用代码 如下:一、ADOTable对数据表的操作:增加、修改与...

Delphi中的DBGrid的使用问题
首先,DBGrid是用来显示数据的,当然也可以在控件中直接进行添加,更新等操作.这里需要注意的是,你的数据库要DBGrid指定的DataSet要已打开.并且,数据库不可设为只读.同时,注意主键字段等一些特定字段.插入数据:可放置一个button,点击Button后,DBGrid在最后显示出一个空行.你可以在DBGrid内输入个字段的值.代码...

delphi7 中如何把 DBGrid 中数据一条一条分别保存到 excel 文件_百度知 ...
这两个文件你可以任选一个。XL5CHS32.OLB是中文版Excel,XL5EN32.OLB是英文版的Excel。选中后回到了Import Tpye Library对话框,在此对话框中选择“create unit”.这个新创建的单元会放在你当前文件存放的同一个目录下。记住不能删。2、在你放按钮的窗体中添加一个ExcelApplication1控件,它放在Servers...

delphi中将dbGrid中的数据保存到excel
ExcelApp := CreateOleObject('Excel.Application');try \/\/ 打开一个excel文件 if not RzOpenDialog1.Execute then Exit;ExcelApp.WorkBooks.Open(RzOpenDialog1.FileName);try \/\/ 设置工作区 ExcelApp.WorkSheets[1].Activate;i := 0;while not Query. EOF do begin sheet.Cells[i, j] := ...

在DELPHI里,怎么把一个DBGrid中的值传到另一个DBGrid中?
DBGrid1.DataSource.DataSet.FieldByName('field2').Asstring;这是form1的DBGrid1的field1、Field2两列值。在form1.DBGrid1.OnDblClick(双击)的时候添加就可以了。没装Delphi,不知道有没有记错的地方。添加你可以选择其他控件,为不用非要用DBGrid,用ListView等控件也行,操作起来还比较简单。

相似回答