最近处理账套时候发现VBA的效率在某些情况下会比Python高,因此写了个小玩意来注入VBA到Excel中进而执行。
Ist_vba
代码
import xlwings as xw
class Ist_vba:
def __init__(self,path,code):
self.code = code
self.path = path
def creat_obj(self):
'''利用xlwings库创建app对象和win32对象'''
app = xw.App(add_book=False, visible=True)
#app.screen_updating = False
#app.display_alerts = False
#app.api.AutomationSecurity = 1
com_target = app.books.api.Open(path, UpdateLinks=False) # win32com object 这里创建了win32的对象,用于宏的创建、导入和执行
wb_target = app.books[com_target.Name] # xlwings object xlwings模块是为了后续对Excel的处理执行
return com_target,wb_target
def create_module(self, name,wb ):#创建一个空宏模块
'''Add normal module.'''
module = wb.VBProject.VBComponents.Add(1)
module.Name = name
def set_module(self, name,wb, code=code ):#将宏代码写入到模块中
''' update code of specified module '''
comp = wb.VBProject.VBComponents(name)
assert comp, f'Module {name} does not exist in the workbook.'
cm = comp.CodeModule
num = cm.CountOfLines
if num > 0:
cm.DeleteLines(1, num)
cm.AddFromString(code)
# save
wb.Save()
def run_macro(self, macro_name,wb ):#执行宏模块
'''run macro embedded in current toll
:param macro_name: macro name, e.g. workbook_name!mudule_name.sub_name
if errors exist in the macro, this function will be blocked. so ensure the macro works
well and insert the following macro at the beginning for safe:
On Error Resume Next
'''
try:
wb.Application.Run(macro_name)
except Exception as e:
print(e, flush=True)
return False
else:
return True
手册
类—属性
code:这里需要传入VBA代码,以文本方式导入,直接用三引号包裹即可
path:这里需要传入Excel文件路径,建议使用原始字符串即:path = r“”
类—方法
creat_obj()
这里会返回两个对象,以元组形式返回
obj = Ist_vba.creat_obj()
wb32 = obj[0] 是Excel的win32对象,用于执行宏模块的创建,导入,执行操作
wb = obj[1] 是Xlwings 的对象,用于借助Xlwings库执行后续操作
create_module(name,wb32 )
用于创建VBA模块
name:这里是模块名
set_module( name, wb32, code=code )
将VBA代码写入到模块“name”中
name:需要写入到哪个模块
run_macro(macro_name,wb32 )
macro_name 需要执行的VBA代码名字
示例
Ivba =Ist_vba(path,code)
excel_obj = Ivba.creat_obj()
wb32= excel_obj[0]#这里是win32对象
wb= excel_obj[1]#这里是xlwings对象
Ivba.create_module("新插入的模块",wb32)
Ivba.set_module("新插入的模块",wb32)
Ivba.run_macro("执行的代码",wb32)
牛
niu