写此文的初衷
本人从事VBA宏编程十多年,最近在转型用Python写Excel操作程序。编码过程中遇到很多问题,某度N久,论坛也查了很多资料。然而发现一个问题,发布的很多关于xlwings的文章,只是基于Python方面对于xlwings的初步介绍,或者就是作者对VBA根本就没有很深的认识或者是藏拙,无法应用到实际使用中。
写此文的原因在于,我想指定某一区域去查找我要的单元格,网上的资料都是全局查找,很难应用到实际中,会查找到其他的单元格。该函数便于后人使用。
举例:
姓名 | 班主任 |
---|---|
李四 | 张三 |
张三 | 张三 |
一个简单的表,表中发现,学生姓名和班主任姓名重复,这在现实中是不可避免会出现的。
如果出现学生转学,就要从表中移出学生:张三
先上一个网上找到的全局查找例子:
def FindRowCol(SheetName, RowOrCol, KeyWord):
try:
if RowOrCol == 'Row':
Cell_Address = SheetName.api.Cells.Find(What=KeyWord, After=SheetName.api.Cells(SheetName.api.Rows.Count, SheetName.api.Columns.Count), LookAt=xws.constants.LookAt.xlWhole,
LookIn=xws.constants.FindLookIn.xlFormulas, SearchDirection=xws.constants.SearchDirection.xlNext, MatchCase=False).Row
elif RowOrCol == 'Col':
Cell_Address = SheetName.api.Cells.Find(What=KeyWord, After=SheetName.api.Cells(SheetName.api.Rows.Count, SheetName.api.Columns.Count), LookAt=xws.constants.LookAt.xlWhole,
LookIn=xws.constants.FindLookIn.xlFormulas, SearchDirection=xws.constants.SearchDirection.xlNext, MatchCase=False).Column
except:
Cell_Address = 0
return Cell_Address
这个查找最后返回的是 B2 单元格 ,即李四的班主任张三那个格子。如果继续执行删除程序,李四就会被删掉了。
以下是指定区域查找
def FindRowColRange(SheetName, RowOrCol, KeyWord,StCol,StRow,EdCol,EdRow):
# StCol = getColumnName(StCol)
# EdCol = getColumnName(EdCol)
# RangeStr = StCol + str(StRow) + ":" + EdCol + str(EdRow)
try:
if RowOrCol == 'Row':
Cell_Address = SheetName.range((StRow,StCol),(EdRow,EdCol)).api.Find(What=KeyWord, After=SheetName.api.Cells(wb.app.selection.row,wb.app.selection.column), LookAt=xws.constants.LookAt.xlWhole,
LookIn=xws.constants.FindLookIn.xlFormulas, SearchDirection=xws.constants.SearchDirection.xlNext, MatchCase=False).Row
elif RowOrCol == 'Col':
Cell_Address = SheetName.range((StRow,StCol),(EdRow,EdCol)).api.Find(What=KeyWord, After=SheetName.api.Cells(wb.app.selection.row,wb.app.selection.column),LookAt=xws.constants.LookAt.xlWhole,
LookIn=xws.constants.FindLookIn.xlFormulas, SearchDirection=xws.constants.SearchDirection.xlNext, MatchCase=False).Column
except:
Cell_Address = 0
return Cell_Address
当调用的时候,输入参数,这样的话,就只在第一列中进行查找。结果为 A3 ,然后删除即可。
Keyword_Row = getRowColRange(wb.Sheets(1),"Row","张三",1,1,655436,1)
隐藏起来的几句话是用来拼接区域地址的,如:”A1:B3“。可以结合以下 列数 转 列名 函数使用,这个是网上找来的,谢谢大神。
def getColumnName(columnIndex):
ret = ''
ci = columnIndex - 1
index = ci // 26
if index > 0:
ret += getColumnName(index)
ret += string.ascii_uppercase[ci % 26]
return ret
为啥我会隐藏起来那几句话呢,因为直接使用单元格行列数代替区域地址可以少几步运行时间。xlwings中的range支持这种方法。
以下是xlwings关于range的使用方法:
import xlwings as xw
xw.Range('A1')
xw.Range('A1:C3')
xw.Range((1,1))
xw.Range((1,1), (3,3))
xw.Range('NamedRange')
xw.Range(xw.Range('A1'), xw.Range('B2'))
另外附上一个读取文件、创建文件夹的函数。
def LoadFile(dir,period):
ResultPath = dir + '\\output\\' + period
if os.path.exists(ResultPath) == True:
print("There has the same period folder in output! Deleting...")
shutil.rmtree(ResultPath)
print("Creating " + period + " folder...")
os.mkdir(ResultPath)
os.mkdir(ResultPath + '\\文件夹1\\')
os.mkdir(ResultPath + '\\文件夹2\\')
DataPath = dir + '\\input\\'
FileLists = []
for Files in os.listdir(DataPath):
if Files[-4:] == "xlsx":
FileLists.append(DataPath + Files)
return FileLists
最近一直在写此类程序,如果有好的会继续分享出来。