您的位置:首页 > 其它

关于MSHFlexGrid的学习笔记

2010-12-07 17:08 281 查看
1.如何控制电子表格
Private Sub Command5_Click()
Dim xlsRowCount As Integer, xlsColCount As Integer '生成的表格的行数和列数
Dim xlsApp As Excel.Application
Dim xlsBook As Excel.Workbook
Dim xlsSheet As Excel.Worksheet
Dim i, j As Long
Set xlsApp = CreateObject("Excel.Application")
Set xlsBook = xlsApp.Workbooks.Add
Set xlsSheet = xlsBook.Worksheets(1)
On Error Resume Next
xlsRowCount = Grid.Rows
xlsColCount = Grid.Cols
With xlsSheet
'设置电子表格各列的宽度
For i = 1 To xlsColCount - 1
Columns(i).ColumnWidth = 5 '每一个汉字大概占2的宽度(在默认的12号字的情况下)
Next
'设置电子表格各行的高度
For i = 1 To xlsRowCount - 1
.Rows(i).RowHeight = 18
Next
'把MSFlexGrid1的内容写入到电子表格中
For i = 0 To xlsRowCount - 1
 For j = 0 To xlsColCount - 1
   .Cells(i + 1, j + 1).Value = Grid.TextMatrix(i, j)
 Next
Next
End With
xlsApp.Visible = True '显示电子表格  转自:雨后池塘(www.YuHou.net
'xlsBook.SaveAs App.Path & "/Test.xls" '保存,如果不指定保存路径及文件名,则默认存到“我的文档”下 Book1.xls
Set xlsApp = Nothing '交还控制给Excel

End Sub
MSHFlexGrid1.Col =1
MSHFlexGrid1.Sort =flexSortGenericDescending
2. MSHFlexGrid的属性
Sort 属性 (MSHFlexGrid)
设置一个值,根据选定的条件排序选择的行。这一属性在设计时不可用。
语法 object.Sort [=value]
Sort 属性的语法包含如下部分:
部分 描述
object 一个对象表达式,其值为“应用于”列表中的一个对象。
Value 一个整数或常数,指定排序类型。如设置值中所述。
设置值
value 的设置值如下所示:
常数 值 描述
flexSortNone 0 无。不执行排序。
flexSortGenericAscending 1 一般升序。执行估计文本不管是字符串或者是数字的升序排序。
flexSortGenericDescending 2 一般降序。执行估计文本不管是字符串或者是数字的降序排序。
flexSortNumericAscending 3 数值升序。执行将字符串转换为数值的升序排序。
flexSortNumericDescending 4 数值降序。执行将字符串转换为数值的降序排序。
flexSortStringNoCaseAsending 5 字符串升序。执行不区分字符串大小写比较的升序排序。
flexSortNoCaseDescending 6 字符串降序。执行不区分字符串大小写比较的降序排序。
flexSortStringAscending 7 字符串升序。执行区分字符串大小写比较的升序排序。
flexSortStringDescending 8 字符串降序。执行区分字符串大小写比较的降序排序。
flexSortCustom 9 自定义。使用 Compare 事件比较行。
说明
Sort 属性总是排序整个行。要指定排序的范围,设置 Row 和 RowSel 属性。如果 Row 和 RowSel 相同,MSHFlexGrid 将排序所有不固定行。
用于排序的关键字由 Col 和 ColSel 属性决定。排序总是在一个从左到右的方向上完成。例如,如果 Col =3 且 ColSel =1,排序根据列 1 的内容,然后是列 2 、列 3 的内容来进行。
用于行比较的方法由 value 决定,如设置值中的解释。设置值 9 (自定义)最灵活,但比其它设置慢,典型地大约是 10 分之一,使用这一设置的另一种可能是创建一个不可见列,用关键字填充,然后使用另一设置执行一个基于自定义的排序。这对基于日期的排序是一个好方法。
3.我想取出MSFlexGrid中用户用鼠标选中的某一行中的某一特定列的内容(比如说:第二列的内容),请问该怎么做?
Me.MSFlexGrid1.Row = i
Me.MSFlexGrid1.Col = j
是取不到固定行和列的,而且也不应该这样赋值,I,J的内容不确定,应该是:
k=Me.MSFlexGrid1.MouseRow
l=Me.MSFlexGrid1.MouseCol
代码如下:
Private Sub MSFlexGrid1_Click()
k = MSFlexGrid1.MouseRow
l = MSFlexGrid1.MouseCol
Text1.text=MSFlexGrid1.TextMatrix(k, 1)
End Sub
4.动态取值代码
Dim i As Long
Dim j As Integer
With MSFlexGrid1
For i = 0 To .Rows - 1
For j = 0 To .Cols - 1
Debug.Print .TextMatrix(i, j) '循环打印MSFlexGrid1的所有值
Next j
Next i
End With
5.使用combo组合
本来通过erp中基础分类档案的每级编码规则控制来展现msflexgrid控件的使用技巧,大家只要向控件添加一个msflexgrid及combo控件就好了,源码如下:

option explicit

private sub combo1_click()
msflexgrid1.text = combo1.text
end sub

private sub combo1_keypress(keyascii as integer)
if keyascii = vbkeyescape then
combo1.visible = false
msflexgrid1.setfocus
exit sub
end if
if keyascii = vbkeyreturn then
msflexgrid1.text = combo1.text
combo1.visible = false
msflexgrid1.setfocus
end if
end sub

private sub combo1_lostfocus()
combo1.visible = false
msflexgrid1.setfocus
exit sub
end sub

private sub form_load()
dim i as integer
dim width, text, archives
width = array("400", "2100", "800", "800", "800", "800", "800", "800", "800", "800", "800")
text = array("序号", "档案名称", "第1级", "第2级", "第3级", "第4级", "第5级", "第6mily: 宋体;"on" UnitName="pt" SourceValue="12" HasSpace="False" Negative="False" NumberType="1" TCSC="0">12.0pt;">级", "第7级", "第8级", "第9级")
archives = array("null", "科目", "项目分类", "固定资产分类", "部门分类", "员工分类", "供应商分类", "
ont-size: 12.0pt;">客户分类", "销售商分类", "地区分类", "出入库类别", "存货分类", "预留12", "预留13", "预留14", "预留15", "预留16", "预留17", "预留18", "预留19", "预留
'">20")
with msflexgrid1
.rows = 21
.cols = 11
.fixedcols = 2
.fixedrows = 1
end with

for i = 1 to 9
combo1.additem i
next i

for i = 0 to 10
msflexgrid1.colwidth(i) = width(i)
msflexgrid1.textmatrix(0, i) = text(i)
next i

for i = 1 to 20
with msflexgrid1
.textmatrix(i, 0) = i
.textmatrix(i, 1) = archives(i)
.rowheight(i) = 300
end with
next i
end sub

private sub msflexgrid1_click()
dim c as integer, r as integer
with msflexgrid1
c = .col
r = .row
if c > 1 and r > 0 then
combo1.left = .left + .colpos(c) + 50
combo1.top = .top + .rowpos(r) + 50
combo1.width = .colwidth(c)
combo1.text = .text
combo1.visible = true
combo1.setfocus
end if
end with
end sub
private sub msflexgrid1_keypress(keyascii as integer)
if keyascii = vbkeyreturn then
call msflexgrid1_click
end if
Printer.Height = 10 * 567
Printer.Width = 5 * 567
Printer.ScaleWidth = 210
Printer.ScaleHeight = 297
Printer.ScaleMode = 6 '设置打印的单位
Printer.PaperSize = vbPRPSA4 '定义纸张大小为A4
Printer.Orientation = vbPRORLandscape '横向打印
Printer.ScaleLeft = -0.75 * 1440
Printer.ScaleTop = -0.5 * 1440
Printer.CurrentX = 0
Printer.CurrentY = 0
PrintForm
Printer.EndDoc '(如无此句则打印机不工作)
Printer.NewPage '(无此句打印机不换页)
Printer.KillDoc '(无此句不能断开计算机和打印机的连接)
前面是打印设置的,注意PrintForm
6.VB中获取指定打印机的各种纸张类型及大小
放入一个MSFlexGrid,名称为fgd1,列数为4
'Option Explicit
Private Const DC_MAXEXTENT = 5
Private Const DC_MINEXTENT = 4
Private Const DC_PAPERNAMES = 16
Private Const DC_PAPERS = 2
Private Const DC_PAPERSIZE = 3
Private Declare Function DeviceCapabilities Lib "winspool.drv" Alias "DeviceCapabilitiesA" (ByVal lpDeviceName As String, ByVal lpPort As String, ByVal iIndex As Long, lpOutput As Any, lpDevMode As Any) As Long
Private Type POINTS
x As Long
y As Long
End Type
Private Sub Form_Load()
Dim i As Long
With fgd1
.Clear
.FormatString = "^纸张编号|^纸张名称|^纸张长度|^纸张宽度"
For i = 0 To .Cols - 1
.ColWidth(i) = 1700
Next i
.AllowUserResizing = flexResizeColumns
.Left = 0
.Width = Me.ScaleWidth
End With
GetPaperInfo
End Sub
Private Sub GetPaperInfo()
Dim i As Long, ret As Long
Dim Length As Integer, Width As Integer
Dim PaperNo() As Integer, PaperName() As String, PaperSize() As POINTS
'支持最大打印纸:
ret = DeviceCapabilities(打印机名称, "LPT1", DC_MAXEXTENT, ByVal 0&, ByVal 0&)
Length = ret / 65536
Width = ret - Length * 65536
'lblMaxLength.Caption = Length
'lblMaxWidth.Caption = Width
'支持最小打印纸:
ret = DeviceCapabilities(打印机名称, "LPT1", DC_MINEXTENT, ByVal 0&, ByVal 0&)
Length = ret / 65536
Width = ret - Length * 65536
'支持纸张种类数
ret = DeviceCapabilities(打印机名称, "LPT1", DC_PAPERS, ByVal 0&, ByVal 0&)
'纸张编号
ReDim PaperNo(1 To ret) As Integer
Call DeviceCapabilities(打印机名称, "LPT1", DC_PAPERS, PaperNo(1), ByVal 0&)
'纸张名称
Dim arrPageName() As Byte
Dim allNames As String
Dim lStart As Long, lEnd As Long
ReDim PaperName(1 To ret) As String
ReDim arrPageName(1 To ret * 64) As Byte
Call DeviceCapabilities(打印机名称, "LPT1", DC_PAPERNAMES, arrPageName(1), ByVal 0&)
allNames = StrConv(arrPageName, vbUnicode)
'loop through the string and search for the names of the papers
i = 1
Do
lEnd = InStr(lStart + 1, allNames, Chr$(0), vbBinaryCompare)
If (lEnd > 0) And (lEnd - lStart - 1 > 0) Then
PaperName(i) = Mid$(allNames, lStart + 1, lEnd - lStart - 1)
i = i + 1
End If
lStart = lEnd
Loop Until lEnd = 0
'纸张尺寸
ReDim PaperSize(1 To ret) As POINTS
Call DeviceCapabilities(Form2.Combo1.Text, "LPT1", DC_PAPERSIZE, PaperSize(1), ByVal 0&)
'显示在表格中
For i = 1 To ret
fgd1.AddItem PaperNo(i) & vbTab & PaperName(i) & vbTab & PaperSize(i).y & vbTab & PaperSize(i).x
Next i
'移除第一个空行
fgd1.Row = 1
fgd1.RemoveItem 1
End Sub
Private Sub Form_Resize()
With fgd1
.Left = 0
.Width = Me.ScaleWidth
.Height = Me.ScaleHeight
.Top = 0
End With
End Sub
7.Vb报表打印设计
数据库管理系统的开发人员经常感叹的一个问题就是:我们中国人的报表太复杂了!无规则、嵌套、斜线、交叉线等历来都是困挠开发人员的最大问题。设计一个数据库固然有一定的技巧,设计数据操作也固然需要一定的逻辑分析能力,但这些问题对一般的开发人员来说应该是不成为问题的。用户可是不管你采用了多么灵活的算法多么方便的操作,他们最感兴趣的是最后他们出来的报表如何漂亮,出报表的操作如何简单(最好是一个按钮解决所有的问题)。笔者在开发数据库管理系统方面也稍有些经验,从foxpro、delphi、powerbuilder一直到现在用的vb,都遇到过设计打印报表的问题,这些软件在设计报表的过程中可谓各有千秋,我这里不一一细说。我在这里只向大家介绍一种我迄今为止最为满意的一种设计打印报表的方法:利用vb操作excel来生成复杂的报表。
一. 用vb创建外部excel对象
大多数大型 activex-enabled 应用程序和其它 activex 部件,在它们的对象层次中都提供了一个顶层外部可创建对象。该对象提供了对该层次中其它对象的访问,并且还提供对整个应用程序起作用的方法和属性。 例如,每个 microsoft office 应用程序提供一个顶层 application 对象。下面语句显示了对microsoft excel的 application 对象的引用:
dim xlapp as excel.application
set xlapp = new excel.application
---- 然后,可以用这些变量来访问在excel应用程序中的从属对象、以及这些对象的属性和方法。例如:
set xlapp = createobject("excel.application")
‘激活excel应用程序
xlapp.visible = false ‘隐藏excel应用程序窗口
set xlbook = xlapp.workbooks.open(strdestination)
‘打开工作簿,strdestination为一个excel报表文件
set xlsheet = xlbook.worksheets(1)
‘设定工作表
---- 二. 用excel 97设计报表的模版文件
---- excel 97是一个非常优秀的创建报表的工具。它提供的单元格任意合并、拆分和绘图功能基本上能够满足设计所有复杂报表的需求。它对任意一个单元格的格式随意控制,更为随心所欲地设计报表提供了强大的支持。
---- 根据用户提供的报表,我们可以很快在excel里生成模版文件。所谓生成模版文件只是为了满足用户多方面的需求而设计的。也是为了适合报表以后的更改而做的一点预备工作。例如用户需要打印几百张职工履历表,但其格式都是一致的,并且随着时间和实际情况的变化,表格格式有可能需要改变,我们设计一个模版文件显然可以“以不变应万变”了。
---- 生成工作表时我们应当记录下要填充内容的单元格编号和该单元格内要填充的数据字段。这样形成一个表格,在写程序时一目了然。如:
cell(4,2) 职工姓名 cell(6,6) 毕业学校
cell(4,4) 职工性别 cell(6,7) 所学专业
cell(4,6) 职工民族 cell(6,9) 工作时间
---- 在程序里我们当然不要对模版文件进行操作了,我们只需要对模版文件的一个拷贝进行操作就行(这也是我们设计模版文件的一个目的和好处)。如下面的例子:
dim strsource, strdestination as string
strsource = app.path & "/excels/registerfee.xls"
‘registerfee.xls就是一个模版文件
strdestination = app.path & "/excels/temp.xls"
filecopy strsource, strdestination
‘将模版文件拷贝到一个临时文件
---- 三. 生成工作表内容
---- 有了上述两步工作的铺垫,我们下面接着就只要根据(表一)的格式给各单元格赋值了。如:
datprimaryrs.recordset.movefirst
‘datprimaryrs为data控件
if isnull(datprimaryrs.recordset!姓名) = false then
xlsheet.cells(4, 2) = datprimaryrs.recordset!姓名
end if
if isnull(datprimaryrs.recordset!性别) = false then
xlsheet.cells(4, 4) = datprimaryrs.recordset!性别
end if
if isnull(datprimaryrs.recordset!民族) = false then
xlsheet.cells(4, 6) = datprimaryrs.recordset!民族
end if
………………
四. 打印报表
生成了工作表后,就可以对excel发出打印指令了。
注意在执行打印操作之前应该对excel临时文件执行一次保存操作,以免在退出应用程序后excel还提示用户是否保存已修改的文件,让用户觉得莫名其妙。如下语句:
xlbook.save ‘保存文件
xlsheet.printout ‘执行打印
xlapp.quit ‘退出excel
设置DataReport的Margins属性
原来默认都是1440修改小一点或者是0
左边距:LeftMargin= 500
右边距:RightMargin= 500

上边距:TopMargin= 500
下边距:BottomMargin= 500
获取打印页边距 uses Printers;
procedure TForm1.Button1Click(Sender: TObject);
var EscapeCode : integer;
Margin : TPoint;
begin if PrintDialog1.Execute then begin
{$IFDEF WIN32}
Margin.x :=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
Margin.y :=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
{$ELSE}
EscapeCode := GETPRINTINGOFFSET;
if Escape(Printer.Handle,
QUERYESCSUPPORT,
sizeof(EscapeCode),
@EscapeCode,
nil) <> 0 then
if Escape(Printer.Handle,
GETPRINTINGOFFSET,
0, nil,
@Margin) < 1 then begin
EscapeCode := GETPHYSPAGESIZE;
if Escape(Printer.Handle,
QUERYESCSUPPORT,
sizeof(EscapeCode),
@EscapeCode,
nil) <> 0 then
if Escape(Printer.Handle,
GETPHYSPAGESIZE,
0,
nil,
@Margin) > 0 then begin
Margin.x := (Margin.x -
GetDeviceCaps(Printer.Handle, HorzRes)) div 2;
Margin.y := (Margin.y -
GetDeviceCaps(Printer.Handle, VertRes)) div 2;
end else begin
Margin.x := 0;
Margin.y := 0;
end;
end; {$ENDIF} Memo1.Lines.Add(IntToStr(Margin.x));
Memo1.Lines.Add(IntToStr(Margin.y));
end; end;

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/realtek_2005/archive/2008/04/11/2280818.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: