赞
踩
背景: 深增值税开票软件在填入发票的明细时(2016年),没有从exce导入的功能,只能手工一个一个输入,对于明细清单数量多的情况,给财务人员带来过多的工作量。所以考虑做一个辅助输入工具。减轻财务的工作量,降低手工输入的出错率。
思路如下: 发票清单 Excel 格式如下, 因为开票的清单来自于销售的出货清单,都是excel格式(从sap导出的),处理起来很方便,所以也延续用Excel格式。
软件功能需要,实现将上面的清单,自动填入到,深增开软件的 清单填开 表格内。 实现原理也很简单,用程序来模拟手工输入过程,控制光标移动。 同一客户,可以连续打印发票。
选好 excel文件,然后层入。看以下效果图:
完整代码如下。用了pywin32 来操作窗口,完成光标移动,数据输入。
- #!/usr/bin/python
- # -*- coding: gbk -*-
-
- # KaiPiaoHaoPengYou.py
- #
- # Copyright (C) 2016 - xulong <fangkailove@yeah.net>
- #
-
- import sys
- from ctypes import *
- import time
- import win32con
- import win32api
- import win32ui
- import wx
- import xlrd
- import win32gui
- import sys
- wildcard = "Excel (*.xls)|*.xls"
-
- class MainFrame(wx.Frame):
- def __init__(self,*agrs,**kw):
- wx.Frame.__init__(self,size=(480,200),*agrs,**kw)
- l1=wx.StaticText(self,-1,u"提示:请先启动开票软件,并确定打开了'清单填开' 窗口!!!",(30,100))
- l1.SetForegroundColour("Red")
- self.t1=wx.TextCtrl(self,-1,"",(30,50),size=(200,-1))
-
- b1=wx.Button(self,-1,u"选择清单文件(EXCEL)",(230,50))
- self.Bind(wx.EVT_BUTTON,self.b1Click,b1)
-
- b2=wx.Button(self,-1,u"开始填写",(370,50))
- self.Bind(wx.EVT_BUTTON,self.b2Click,b2)
-
-
- def b1Click(self,evt):
- text = self.t1.GetValue()
- dlg = wx.FileDialog(self,message=u"选择清单Excel文件",
- defaultFile=text , wildcard=wildcard,style=wx.FD_OPEN |wx.FD_CHANGE_DIR)
- if dlg.ShowModal() == wx.ID_OK:
- text = dlg.GetPath()
- self.t1.SetValue(text)
-
- dlg.Destroy()
-
-
-
- def b2Click(self,evt):
- self.parsexsl(self.t1.GetValue())
-
-
- def parsexsl(self,filename):
- book = None
- try:
- book=xlrd.open_workbook(filename)
- except IOError as e:
- pass;
-
- #print ("数据提示:")
- if book == None :
- wx.MessageBox(message=u"Excel文件不能正常读,确认格式,文件名有误!!",caption=u"提示",parent=self)
- return
-
- sheet1 = book.sheet_by_index(0)
-
- #清单行数
- nrows = sheet1.nrows
- #清单列数
- ncols = sheet1.ncols
-
-
-
- for rownum in range(1,nrows):
- #print ('row',rownum )
-
-
- #print ("行:",rownum + 1," ",rowline,"\r")
- if "%s"%sheet1.cell(rownum,0).value == '---':
- message = u"遇到换票标识行(---),需要换票,请检查当前发票无误后,重新填写新发票回到'清单填开'界面,点[确定]后继续\r"
- dlg = wx.MessageDialog(self, message, u"提2示", wx.OK|wx.STAY_ON_TOP)
- dlg.ShowModal()
- continue
-
- f=None
- try:
- f=win32ui.FindWindow(None,"清单填开")
- except win32ui.error as e:
- wx.MessageBox(message=u"提示:请先启动开票软件,并确定打开了'清单填开' 窗口",caption=u"提示",parent=self)
- return
-
- #取开票软件的窗口类名,此开票软件的类名后辍部分会随机的变化。故需动态取后辍,后续用其拼接其它子窗口的类名。
- cln=win32gui.GetClassName(f.GetSafeHwnd())
- prex=cln[29:]
- #print (prex)
-
-
- #get main window handle.
- win=win32ui.FindWindow("WindowsForms10.Window.8.app.0"+prex,u"清单填开")
-
- #get second level window handle
- win2=win32ui.FindWindowEx(win,None,"WindowsForms10.Window.8.app.0"+prex,u"清单填开")
-
-
- #get grid's parent window
- win3=win32ui.FindWindowEx(win2,None,"WindowsForms10.Window.8.app.0"+prex,"")
-
- #get grid's handle
- grid=win32ui.FindWindowEx(win3,None,"WindowsForms10.Window.8.app.0"+prex,"")
-
- print 'grid:%x,win3:%x'%(grid.GetSafeHwnd(),win3.GetSafeHwnd())
-
- #fill one line of grid
- #move the cursor back to firt cell ,using allow left key
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_LEFT, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_LEFT, 0)
-
-
-
-
-
- #first column
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_F2, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_F2, 0)
- cp1=win32ui.FindWindowEx(grid,None,"WindowsForms10.Window.8.app.0"+prex,"")
- tb=win32ui.FindWindowEx(cp1,None,"WindowsForms10.EDIT.app.0"+prex,None)
- print 'tb:%x,cpl:%x'%(tb.GetSafeHwnd(),cp1.GetSafeHwnd())
- tb.SendMessage(win32con.WM_SETTEXT,sheet1.cell(rownum,0).value.encode('gbk','ignore'))
- #tb.SendMessage(win32con.WM_SETTEXT,'测试1')
- #print (sheet1.cell(rownum,0).value)
-
- #second
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_F2, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_F2, 0)
-
- print 'grid:%x,cpl:%x'%(grid.GetSafeHwnd(),cp1.GetSafeHwnd())
- cp2=win32ui.FindWindowEx(grid,cp1,"WindowsForms10.Window.8.app.0"+prex,"")
- print '2'
- tb2=win32ui.FindWindowEx(cp2,None,"WindowsForms10.EDIT.app.0"+prex,None)
- #tb2.SendMessage(win32con.WM_SETTEXT,'测试2')
- value = sheet1.cell(rownum,1).value.encode('gbk','ignore')
- if value.endswith(".0"):
- value = value[:-2]
- if value.endswith(".00"):
- value = value[:-3]
- tb2.SendMessage(win32con.WM_SETTEXT,value)
- #print (sheet1.cell(rownum,1).value)
-
- #3th
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_F2, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_F2, 0)
- cp2=win32ui.FindWindowEx(grid,cp1,"WindowsForms10.Window.8.app.0"+prex,"")
- tb2=win32ui.FindWindowEx(cp2,None,"WindowsForms10.EDIT.app.0"+prex,None)
-
- #tb2.SendMessage(win32con.WM_SETTEXT,'测试3')
- tb2.SendMessage(win32con.WM_SETTEXT,sheet1.cell(rownum,2).value.encode('gbk','ignore'))
- #print (sheet1.cell(rownum,2).value)
-
- #4th
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_F2, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_F2, 0)
- cp2=win32ui.FindWindowEx(grid,cp1,"WindowsForms10.Window.8.app.0"+prex,"")
- tb2=win32ui.FindWindowEx(cp2,None,"WindowsForms10.EDIT.app.0"+prex,None)
- #tb2.SendMessage(win32con.WM_SETTEXT,'4')
- value = str(sheet1.cell(rownum,3).value).encode('gbk','ignore')
- if value.endswith(".0"):
- value = value[:-2]
- if value.endswith(".00"):
- value = value[:-3]
- tb2.SendMessage(win32con.WM_SETTEXT,value)
- #print (sheet1.cell(rownum,3).value)
-
- #5th
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_F2, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_F2, 0)
- cp2=win32ui.FindWindowEx(grid,cp1,"WindowsForms10.Window.8.app.0"+prex,"")
- tb2=win32ui.FindWindowEx(cp2,None,"WindowsForms10.EDIT.app.0"+prex,None)
- #tb2.SendMessage(win32con.WM_SETTEXT,'5')
- tb2.SendMessage(win32con.WM_SETTEXT,str(sheet1.cell(rownum,4).value).encode('gbk','ignore'))
- #print (sheet1.cell(rownum,4).value)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
-
- grid.SendMessage(win32con.WM_KEYDOWN, win32con.VK_TAB, 0)
- grid.SendMessage(win32con.WM_KEYUP, win32con.VK_TAB, 0)
-
- #fill one line of grid
-
- #move the cursor to next line . using RETURN key
- if rownum < ( nrows -1 ):
- win32api.Sleep(3)
- grid.PostMessage(win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
- grid.PostMessage(win32con.WM_KEYUP, win32con.VK_RETURN, 0)
- win32api.Sleep(3)
-
- class MyApp(wx.App):
- pass
-
-
-
-
-
-
- if __name__ == '__main__':
- app=MyApp()
- frame=MainFrame(None,title=u"开票助手")
- frame.Show(True)
- app.MainLoop()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。