设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12下一页
返回列表 发新帖
查看: 7028|回复: 11
打印 上一主题 下一主题

[报表] POS电脑小票直接打印到LPT1的错误捕捉

[复制链接]
跳转到指定楼层
1#
发表于 2011-2-8 22:55:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zyp 于 2011-2-8 23:00 编辑

各位Access中国的网友,大家新年好!

最近帮朋友弄一个超市收银系统, 在打印POS小票时, 采用直接向LPT1端口写入的办法来弄的, 代码大致如下:

Private Sub PrintXSD(lngXsid As Long)
On Error GoTo PrintErr
      Open "LPT1" For Output As #1
      Print #1, "XXX服装专卖店"
      Print #1, "--------------------------------"
      '此外省略....................................
      Close #1   
Exit_PrintXSD:
    Exit Sub
PrintErr:
    MsgBox Err.Number & "--" & Err.Description
    Resume Exit_PrintXSD
End Sub

当小票打印机正常联接时, 可以正常输出, 但是,一旦小票打印机没有正常工作时(比如没有打开电源), 则目前的程序没能捕捉到任何的错误信息, 直接死在那里了(一直在往LPT1端口输出),Ctrl+Break都没用, 如果此时打开小票打印机, 则能够打印出来, 程序又回到正常, 否则只能通过任务管理器才能将这个系统关掉了.

请问各位高手, 遇到这个情况该如何处理?

或者是说如何做到在Print前检测到并口上是否已经联接了打印机,并准备就绪.

谢谢!

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
 楼主| 发表于 2011-2-9 20:11:08 | 只看该作者
自己顶一下. 
还请大家出手相助!

谢谢!
3#
发表于 2011-2-10 08:34:05 | 只看该作者
是否可以使用MSComm控件来检测到并口上是否已经联接了打印机,并准备就绪.
MSComm 控件有很多属性,下面几个属性好像是设置打印机的通讯连接的
CommPort
设置并返回通讯端口号。

Settings
以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。

PortOpen
设置并返回通讯端口的状态。也可以打开和关闭端口。

Input
从接收缓冲区返回和删除字符。

Output
向传输缓冲区写一个字符串。

4#
发表于 2011-2-10 08:59:33 | 只看该作者
转载〕VB 通过MSComm控件取得打印机的状态:正常、缺纸、卡纸等:
此方法使用VB中的串口通信控件MSComm给打印机发送指令,然后打印机自动返回其状态值,根据不同的返回值就可以判断打印机是正常、缺纸、卡纸等状态。其中的指令适用于Star SP500系列。注意在使用此方法时不要安装打印机的驱动,或者在驱动中设置的串口端口与此程序中的要不能相同,否则程序会提示参数设置错误,其实就是端口已经被占用的原因。以下是程序代码:
Option Explicit

Dim Status As String
Dim StatusString As String
Dim TimeUp As Boolean

Private Sub Command1_Click()Sub Command1_Click()Sub Command1_Click()Sub Command1_Click()
On Error Resume Next
    Dim i As Long
    Status = ""               '状态返回值
    StatusString = ""      
   
    MSComm1.CommPort = 1         'COM端口号:如果是COM1则为1,以此类推;
    MSComm1.Settings = "38400,N,8,1"      '参数设置:波特率,奇偶校验,数据位,停止位;
    MSComm1.InputLen = 0

    MSComm1.PortOpen = True        '打开端口
   
    '给Star打印机发送“ENQ”指令或“ESC ACK SOH”指令,打印机自动返回状态值
    MSComm1.Output = Chr$(5) + Chr$(&HA) + Chr$(0)                    
    'MSComm1.Output = Chr$(&H1B) + Chr$(&H6) + Chr$(&H1)                 
   
    ' Poll for 8 byte status
    Do While Len(Status) < 8
        DoEvents
        Status = MSComm1.Input
    Loop
   
    For i = 1 To 9
        StatusString = StatusString & Right("00" & " " & Hex(Asc(Mid$(Status, i, 1))), 2)
        'StatusString = StatusString & Hex(Asc(Mid$(Status, i, 1))) & " "
    Next i
   
    Text1.Text = StatusString
    MSComm1.PortOpen = False
End Sub

Private Sub Form_Unload()Sub Form_Unload()Sub Form_Unload()Sub Form_Unload(Cancel As Integer)
    Close
End Sub

Private Sub Wait()Sub Wait()Sub Wait()Sub Wait(Interval As Long)
    Timer1.Interval = Interval
    Timer1.Enabled = True
    TimeUp = False
   
    Do
        DoEvents
    Loop While Not TimeUp
End Sub

Private Sub Timer1_Timer()Sub Timer1_Timer()Sub Timer1_Timer()Sub Timer1_Timer()
    Timer1.Interval = 0
    Timer1.Enabled = False
    TimeUp = True
End Sub


----------------------------------------------------------------------
2号代码:
Option Explicit
Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long
Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
Declare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean
Declare Function SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean
Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean
Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean
Declare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean
Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean
Public IOStat As Boolean
'************************************************************
'* 函数名称:GetPrnStat                                     *
'* 功能:根据打印机的内存地址,检测打印机的目前工作状态     *
'* 参数:lptport: 要检测的打印机的端口号,如LPT1:           *
'* 返回值:打印机的工作状态值。                             *
'*         0:正常 1:缺纸 2:无联系 3:异常(其他错误)      *
'* 调用:本模块中的API函数InitializeWinIo和GetPortVal       *
'* 备注:检测的内存地址,是在打印端口所在的基地址上加1;    *
'* 作者:谷霖                                               *
'* LPT1口的基地址为&H378;LPT2口的基地址为&H278             *
'************************************************************
Public Function GetPrnStat(ByVal LptPort As String) As Long
    Dim PrnAddr As Long
    On Error Resume Next
    If IOStat = False Then IOStat = InitializeWinIo()
    If IOStat Then
        If UCase(LptPort) = "LPT1:" Then
            PrnAddr = &H379
        ElseIf UCase(LptPort) = "LPT2:" Then
            PrnAddr = &H279
        End If
        GetPortVal PrnAddr, GetPrnStat, 1
    Else
        GetPrnStat = &HFF
    End If
    GetPrnStat = GetPrnStat And &HF8
    Select Case GetPrnStat
    Case &H68, &H58, &H70
        GetPrnStat = 1 '缺纸
    Case &H78
        GetPrnStat = 2 '无联系
    Case &HD8
        GetPrnStat = 0 '正常
    Case Else
        GetPrnStat = 3 '异常
    End Select
End Function

'*************************************************************************
'* 函数功能:检查打印机的状态主函数                                      *
'* 输入参数:PrintName 要检测的打印机名称                                *
'* 输出参数:checkprinterr                                               *
'* 检查结果(0:正常 1:打印机缺纸 2:打印机无联系 3:打印机异常          *
'*          4:没有安装打印机 5:打印机名称错误)                         *
'*************************************************************************
Public Function CheckPrintErr(ByVal PrintName As String) As Long
    'CheckPrintErr参数说明
    '0:没有错误
    '1:打印机无联系
    '2:打印机缺纸
    '3:没有安装打印机
    Dim printjieguo As Long
    Dim i As Long, k As Long
    On Error GoTo ErrCheckPrint
   
    If Printers.Count = 0 Then
        CheckPrintErr = 4      '没有安装打印机
        Exit Function
    End If
    '检测发票打印机是否可以联系
    For i = 0 To Printers.Count - 1
        If (Printers(i).DeviceName = PrintName) Then
            k = k + 1
            Exit For
        End If
    Next
    If k = 0 Then              '打印机名称错误
        CheckPrintErr = 5
        Exit Function
    End If
    Set Printer = Printers(i)
   
    CheckPrintErr = GetPrnStat(Printer.Port)
    Exit Function
ErrCheckPrint:
    CheckPrintErr = 3
    Exit Function
End Function

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

点击这里给我发消息

5#
发表于 2011-2-10 09:39:06 | 只看该作者
小票打印 一般直接使用ESC命令来控制. 一般是兼容epson 或相关的小票打印机
6#
 楼主| 发表于 2011-2-10 15:24:20 | 只看该作者
谢谢xuwenning , 我先测试一下,再告知大家测试结果.

7#
 楼主| 发表于 2011-2-10 15:26:52 | 只看该作者
本帖最后由 zyp 于 2011-2-10 15:27 编辑

谢谢tmtony 站长,
在小票机上的说明书上有很多ESC控制代码, 但本人对ESC一无所知, ACCESS的VB帮助找不到相关帮助文件,网上也搜不到有用的信息.
请问站长能不能介绍一下有关ESC命令的使用方法, 不胜感激!
8#
 楼主| 发表于 2011-2-11 14:57:22 | 只看该作者
谢谢xuwenning
(1)MSComm只能检测串口,不能检测并口LPT
(2)WinIo  这个应该可以用, 由于不是Xp自带的DLL, 帮助文件全是E文, 暂时还没有弄明白如何使用;
(3)CheckPrintErr 只能检测安装打印驱动的打印机, 不适合直接向LPT输出的打印方式

努力中,谢谢大家的关注!

点击这里给我发消息

9#
发表于 2011-2-13 13:46:59 | 只看该作者
Call StartDocPrinter(lhPrinter, 1, MyDocInfo)
Call StartPagePrinter(lhPrinter)
printData = Chr$(&H1B) & "@"
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(&H1B) & Chr$(33) & Chr$(1) '!字体大小
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(&H1B) & Chr$(51) & Chr$(35) '3行间距
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(32) & Chr$(32)
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = "单号: " & "" & strOrderNo & ""
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(10)
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(32) & Chr$(32)
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = "台号:" & "" & strTable & ""
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(10)
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(32) & Chr$(32)
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = "时间:" & "" & strOrderDate & ""
Call WritePrinter(lhPrinter, ByVal printData, LenB(StrConv(printData, vbFromUnicode)), lpcWritten)
printData = Chr$(10)

点击这里给我发消息

10#
发表于 2011-2-13 13:47:42 | 只看该作者
上面只是示例,具体你要自己修改成你想要的
前面要引用下面代码

Private Type DOCINFO
    pDocName As String
    pOutputFile As String
    pDatatype As String
End Type
  Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal _
        hPrinter As Long) As Long
  Private Declare Function EndDocPrinter Lib "winspool.drv" (ByVal _
        hPrinter As Long) As Long
  Private Declare Function EndPagePrinter Lib "winspool.drv" (ByVal _
        hPrinter As Long) As Long
  Private Declare Function OpenPrinter Lib "winspool.drv" Alias _
      "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, _
      ByVal pDefault As Long) As Long
  Private Declare Function StartDocPrinter Lib "winspool.drv" Alias _
      "StartDocPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, _
      pDocInfo As DOCINFO) As Long
  Private Declare Function StartPagePrinter Lib "winspool.drv" (ByVal _
      hPrinter As Long) As Long
  Private Declare Function WritePrinter Lib "winspool.drv" (ByVal _
      hPrinter As Long, pBuf As Any, ByVal cdBuf As Long, _
      pcWritten As Long) As Long
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-3 02:58 , Processed in 0.083036 second(s), 33 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表