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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
参考技术A http://www.china-askpro.com/vbasic23.shtml
(vb相关的专家网站,站长会很乐意解答你的疑问)
例如:

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

如何使Tstringgrid中的数字都靠右

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

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

出错提示为"IDEX IS READ ONLY"

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

如何设置DBGrid的ScrollBar状态

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

如何锁定Delphi的DBGRID的列
参考技术B 表单的TCURRENCY类型,如何选择货币种类

如何使Tstringgrid中的数字都靠右

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

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

出错提示为"IDEX IS READ ONLY"

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

如何设置DBGrid的ScrollBar状态

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

如何锁定Delphi的DBGRID的列
参考技术C 其实最好用sql来解决.反正delphi也可以调用的

用group by就可以
参考技术D 你的问题我没看明白不过看上去应该是不难!

名称 名称 名称
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回答]的主要内容,如果未能解决你的问题,请参考以下文章

报表中怎么把相同值的单元格合并成一个大格

Java后台传到前台的数据,在table里面怎么将相同的td合并成一行。数据是动态的,不确定有多少条

如何将EXCEL表格中的同一列有相同的内容 合并成一个单元格

如何将EXCEL表格中的同一列有相同的内容 合并成一个单元格?

多个相同表头的excel表格如何合并成一个

Tableau何如将两条数据合并成一条显示