您的位置:首页 > 编程语言 > VB

多用户打印中心VB简单实现

2008-03-10 11:00 162 查看
多用户打印中心VB简单实现
前段时间公司财务部门的发票打印系统功能撑不住了,求上门来,不好不帮。
帮他们写了套财务发票打印的东东。因为时间上的期限比较宽松,我也正好想
对之前的一些编程知识做一个整理,就小小的“发挥”了一下。
一共实现了以下功能:
1.用户操作(PC + SQL SERVER)

2.自由排版(可以在排版窗体内拖动各个项目的位置,打印时就按照这个位置
输出)。代码参考:http://download.csdn.net/source/325194

3.设置的保存和自动加载(很另类的实现方法,我不喜欢用INI或者注册表来
保存,觉得那样代码太罗嗦,而且还有很多限制,我用的是自定义数据结构+二
进制文件一步到位了,还兼有保密作用,呵呵)
代码参考:http://download.csdn.net/source/325194

4.表格控件(MSFLEXGRID)的编辑功能,虽说DATADRIG可以直接用来编辑
和连接数据库,但是我觉得它一来太笨重,二来不灵活,反到是功能简单的
FLEXGRID更能发挥。代码参考:http://download.csdn.net/source/369462
实例代码中我忘记加上鼠标滚轮的支持了,要加上的话GOOGLE上很多。

5.打印机信息的获得和设置(核心代码是从网上直接拷贝的,我只是改了实现
的界面)

6.操作和错误日志记录。就是写log文件,这个功能是在最后用户最终测试的
时候才添加上去的,因为用户根本无法仔细的描述出程序出错时的细节,他们
只是习惯性的对着WINDOWS弹出的任何对话框点“确定”,求人不如求己,
还是自己记录可靠。
同样用的是我的独门偷懒方法,核心代码就2句:
CMDS = "CMD.exe /c Echo """ & Msg & """ >> """ & App.Path & "/LOG.TXT"""
Shell CMDS, vbHide
谁用谁知道,呵呵

7.批量打印处理。用户可以在某个时间将指定的一堆发票一起打印出来。

放一起看,好复杂;
一项一项分开看,都是很熟悉的东西。
本文主要想把最后第7条和大家介绍一下。
先来说说我自己的一些小小体会。
以前在家里自己写代码的时候喜欢写一些好玩的东西,或者是自认为比较“有
技术”的东西,对什么数据库应用什么的向来不屑一顾,认为很无聊很没用。
不想后来进了公司写程序,有用的却偏偏是以前扔下的东西。
其实仔细想想也对,主要是使用对象不同,使用环境也不同,要求自然也就不
同了。
要是一个人用的话,数据库只要ACCESS就够了,打印机什么的都直接练在你
的电脑上,你爱咋打就咋打。可是放公司里就不行,除了你手头的电脑,其他
资源都是共享的,在编程的时候就必须要多考虑很多东西。而且我相信,这些
问题本身是和语言无关的,无论你用什么语言来实现,都会遇到这些问题。
语言只是工具,而不是解决方案。
这里我们遇到的是打印机的共享使用问题。
由于发票打印的特殊性,一般都是由一台针式打印机来打发票的。(不懂财务,
但是至少我从没见过用2台打印机同时打发票的。)
我的实现思路如下:
专门写一个打印处理程序用来处理打印任务,该程序运行在打印服务器上。
在打印机服务器上开一个共享文件夹,共享给所有可以打印发票的PC。
在共享文件夹内建立3个子目录:
如:
X:/PrintQueue/H =》高优先级
X:/PrintQueue/M =》中优先级
X:/PrintQueue/L =》低优先级
用途是存放不同优先级的打印任务
打印处理程序默认处理优先级从高到低。
打印处理程序每次打印完一个任务就按照H>M>L的顺序去扫描一下这3个文
件夹是否有打印文件。如果有文件则打印之,然后再次扫描。

而在客户端,默认的打印优先级都是中等,把待打印文件保存到打印服务器的
M/文件夹下。在急用的情况下指定高优先级输出,则保存到H/下,这样就能保
证下一张打印出来的就是这张发票了。而指定了低优先级打印的都被保存到L/
文件夹下,这些发票只能在其他优先级的发票全部输出完毕的情况下被打印。

这里指出一点:只要稍微修改一下打印服务器端的打印处理程序,也可以把低
优先级打印任务放在一个指定的时间输出(比如晚上10:00以后),只要修改一下
打印处理程序的扫描顺序,如:早上9:00到晚上10:00只扫描H/和M/文件夹
内的打印文件,晚上10:00之后再把L/加到扫描的顺序中去,(注意一下,千万
不能做成10:00之后只扫描L/文件夹,读者自己想一下原因吧。)

在前面我给出的界面排版代码中http://download.csdn.net/source/325194,我只给
出了保存输出位置的代码(因为在我实际的代码中那个窗体只是用来排版,而不
是用户的实际操作界面),而要实现本文的功能,也只需稍微改变一下保存的内
容。
此处我简单写一段以供参考:
'先定义个数据结构用来存放打印内容,分别指定打印位置,内容,和字体大小
Private Type PrintItem 
   X As Long
   Y As Long
   Txt As String
   FontSZ as Long
End Type
Dim PrintItems() As PrintItem

此处我们把问题简化一下,假设所有要打印的内容都在窗体的TEXT1控件数组
内,TEXT控件的内容由用户自己输入。(现场编写,未经调试)
'保存打印文件:
Private Sub PrintOut(Byval Priority as long)
Dim F as long
Dim I as long
Dim L as long
Dim M as long
Dim S as String

L=text1.count
Redim PrintItems(L)

For I=1 to L
   With Text1(I-1)
PrintItems(I).X=.Left * Xratio + X0    '这里几个系数后面再解释
PrintItems(I).Y=.top * Yratio + Y0
PrintItems(I).Txt=.text
PrintItems(I).Fontsz=. Fontsize * FRatio
   End With
Next

Select case Priority
   Case 0: s="//print-server/Printqueue/h/"
   Case 1: s="//print-server/Printqueue/m/"
   Case 2: s="//print-server/Printqueue/l/"
End select

S=S & format(now, "yymmddHHMMSS.prt") '总得给文件编个号吧
f=FREEFILE '获得空文件号
I = Len(PrintItems(0))*L
Open S For Random As F  Len = I
   For M=1 to L
      Put F, M, PrintItems(M)
   Next
Close F
End Sub

代码很少吧。
稍微解释下:
调用的时候:PrintOut  1 就表示按照默认中等优先级打印了。
你可以用OPTION控件数组来让用户设置优先级:Option1(0)~ Option1(2)

上面的过程中我在赋值的时候加了一些系数:
PrintItems(I).X=.Left * Xratio + X0  
PrintItems(I).Y=.top * Yratio + Y0
PrintItems(I).Fontsz=. Fontsize * Fratio
其实是用来调整打印输出位置的。因为实际打印输出的位置和界面上的控件位
置还是有所出入的,因此这里加上一下系数用来调整。
可以看出X0和Y0是用来调整整体位置的,而Xratio, Yratio则是用来调整缩放
比例的。Fratio则可以用来调整屏幕字体和打印字体之间的差距。
实际写程序的时候,你可以直接在程序内部用实际的数字来替代,也可以专门
做个界面来在运行时调整。只要经过不多的几次打印,你就能得到一个比较合
适的结果了。
恩,到这里,我们已经完成了一半的工作。即客户端的输出工作。
而打印服务器端的工作也是比较简单的。
首先,你可以直接用VB自带的那个FileListBox控件来得到指定文件夹下的所
有文件。
然后就是读取文件内容和打印输出了:
Dim PrintItems() As PrintItem   '这个定义和前面是一样的,不重复了

Public Sub GetPRTFile(Byval FileName as string)
Dim I As Long
Dim L As Long
Dim M As Long
Dim F As Long

L = 10  '这里需要直接指定,因为不是在客户端程序,所以无法通过TEXT1.COUNT之类
        '属性获得要打印的字段数量,只能手工设定。
ReDim PrintItems(L)

F = FreeFile
I = Len(PrintItems(0)) * (L)

Open FileName For Random As F Len = I
For M = 1 To L
   Get F, M, PrintItems(M)
Next
Close L

Printer.newdoc
For M = 1 To L
    PrintStr PrintItems(M).X,PrintItems(M).Y,PrintItems(M).FONTSZ,PrintItems(M).TXT
Next
End Sub
printer.enddoc
KILLFILE FileName ’打完就删,以免重复打印。
'这里还可以加上个打印记录LOG的过程调用,可以参考文章开头的第6条。
end sub

再补上个打印字符串的过程:
Public Sub PrintStr(ByVal X As Long, ByVal Y As Long, ByVal PString As String, ByVal FontS As Long)
Printer.CurrentX = x
Printer.CurrentY = y
Printer.FontSize = FontS
Printer.Print PString
End Sub

到此,整个工程核心部分已经完成。
请大家回顾一下,总代码不过区区数十行,实现了一个C/S多用户打印系统。
或许有人会说“既然有打印服务器,客户端直接打印就是了,何必再麻烦写那个打印处理程序呢?”
如果是一般的文档打印,确实可以直接从客户端提交打印任务,由打印服务器自动排队完成。
但是无法指定打印的优先级,也很难拿出打印记录(LOG)。最主要的一点就是只需要在打印处理程序上稍作更改,你就能实现更多的功能。毕竟这是你自己的代码。借用句广告词:俺滴地盘俺作主!

我写本篇文章其实也有些抱歉的意思在内,因为上次贴的那个关于打印预览自动排版的代码并补完整。
没有把打印的部分写进去,在这里算是补充完整.(http://download.csdn.net/source/325194)
免得有人说我骗分,呵呵。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息