excel中想實現使用Python代替VBA,請問應該怎麼做?
前提:因使用VBA代碼可讀性和 擴展性差,想用Python實現,以提高 復用率。
目前的想法是 在Excel中寫入基礎信息,執行宏時,VBA中通過庫調用Python代碼,生成統計數據,請問可以使用什麼庫來實現?
維護一個基於Excel的項目5年的苦逼怒答。「python(或者其他什麼語言)操作excel」文件,按是否依賴Excel,可以分為兩類。
第一類,excel文件只是用來存儲數據,python對它的操作只是讀和寫。這種時候,對文件的操作不需要依賴Excel,你的機器上沒有excel也能執行。在這種場景下,csv,txt等Excel支持的文本文件格式,都是很好的選擇。這種情況,所謂的"python讀寫excel文件",實際上就是python讀寫文本文件,無非是這個文本文件是有一定格式的,找個csv的類庫處理能事半功倍。如果csv/txt太過簡單,文件內需要多個worksheet,那麼可以保存為xls/xlsx格式,對應的讀寫操作用樓上提到的xlrd和openpyxl。
第二類,對文件的操作不止讀寫數據,包含更多的其他操作,比如插入行列,設置字體顏色,等待。這時候文件格式必然是excel only的格式(xls*)。對應的操作,其實最基礎的,是通過COM調用Excel的API,實際上VBA調用的也是這個東西。python,以及其他很多語言,都是支持COM的,在腳本裡面獲取到了Excel.Application,就可以像在VBA裡面一樣寫Application.Workbooks(1).Worksheet(1)了。下面sample是ruby寫的,python應該也差不多。
#引用COM
require "win32ole"#連接一個已經打開的Excel
xlApp = WIN32OLE.connect("Excel.Application")#接下去就和VBA的寫法沒什麼兩樣了wb = xlApp.activeWorkbook #獲取當前激活的workbookws = wb.worksheets(1) #獲取第一個worksheetws.range("A1").value = "hello" #在sheet1的A1寫入「hello」搜索pyxll,你值得擁有
有了xlwings,excel就成了個gui了,結合numpy,pandas各種爽。
還有比如直接插入matplotlib圖表,比如利用python自帶的sort一行代碼完成vba寫個幾十行大一百行才能完成的複雜排序。
剛看了下新版api,又有新的黑科技了,可以excel裝個插件然後用python來寫自定義公式最近在用 Python 操作 excel ,推薦一個模塊吧,
GitHub - pyexcel/pyexcel: Python Wrapper that provides one API for reading, manipulating and writing data in csv, ods, xls, xlsx and xlsm files這個第三方的模塊在格式之間的轉換比較方便。另外推薦 awesome-Python GitHub - vinta/awesome-python: A curated list of awesome Python frameworks, libraries, software and resources 想用 Python 做點什麼,直接去找相應的模塊就好了。
因為我要讀入比較大的 excel 的文件, 最後使用了 openpyxl 的read_only 的模式,這樣讀入的速度比較快。下面是一個把比較大的 xlsx 文件轉為 csv 文件的實例。#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import openpyxl
import csv
def xlsx_to_csv(fn):
wb = openpyxl.load_workbook(filename=fn, read_only=True)
sheet_name = wb.get_sheet_names()
sheet = wb[sheet_name[0]] # 選擇操作 excel 文件的第一張表
with open("sample.csv", "w", newline="", encoding="utf-8") as fw:
ww = csv.writer(fw)
for r in sheet.rows:
row = [i.value for i in r]
ww.writerow(row)
if __name__ == "__main__":
fn = "sample.xlsx"
xlsx_to_csv(fn)
文件都讀入到 Python 中了,操作起來不就方便多了。
另外最新在我的微信公眾號,更新一篇介紹 xlwings 的文章,http://mp.weixin.qq.com/s/40VdZail2gyOhbUpocoTpQ考不考慮R語言?
在你的VBA里將所需要的數據導出到一個新文件,用VBA調用CMD,CMD運行一條執行蟒蛇的語句,可以讓VBA通過CMD往蟒蛇里傳參,蟒蛇運行,蟒蛇輸出結果到某個指定好了的空文件夾下,VBA循環監聽空文件夾下文件數目如果為1,則讀取新文件內容,這樣就極大的擴展了VBA的使用範圍了。
這只是一條簡單的思路,可任意完善,只要能達到目的。
一般來說主流程序系統由vba改成其他項目還是非常困難的。
如果採用蟒蛇控制Excel,那就平添太多學習成本。既然會了excel,會了蟒蛇數據處理,那就各取所長,就用我說的方法。
改用C#也可以,不需要一定用VBA。而且根據政策,等以後移植到UWP之後,都用C#了。
我想用js…逃跑ε=(′o`)
我曾經也有這樣的想法,因為實在很難適應vba的語法,寫一會vba,再寫別的就各種掰不回來。
樓上各位提到的工具多少也試過,都沒成功。
最後我用了一種曲線救國的方法: 1.先用vba寫導出json的函數,注意,是函數,可以把excel里的數據直接轉化為json並直接保存,每次源數據變化都會重新導出並保存。 2.用python讀取json數據,進行運算,眾所周知,python讀取json的方法是很友好的當然缺點就是,這種方式只能用於運算數據,不能更改excel的數據如果數據是 xlsx 格式的文件的話,大膽把 Excel 當成一個可視化工具,直接用 openpyxl 整個讀出來操作,再寫回去,包括樣式,公式之類的都可以修改。
對於會用python的人,Excel現在唯一重要的是最後的數據呈現。大多數你的領導或者客戶還是習慣看格式好的excel,而不是CSV。顯然沒有人喜歡寫完數據處理腳本後還要手動調整excel格式。問題應該是如何用python控制excelVBA製表!根據@woodylic的答案找到了對應的包名叫pywin32, 這個包在anaconda中自帶.
python模塊:win32com用法詳解
使用技巧
import win32com
from win32com.client import Dispatch, constantsw = win32com.client.Dispatch("Word.Application")
# 或者使用下面的方法,使用啟動獨立的進程:# w = win32com.client.DispatchEx("Word.Application")# 後台運行,不顯示,不警告
w.Visible = 0w.DisplayAlerts = 0# 打開新的文件
doc = w.Documents.Open( FileName = filenamein )# worddoc = w.Documents.Add() # 創建新的文檔# 插入文字
myRange = doc.Range(0,0)myRange.InsertBefore("Hello from Python!")# 使用樣式
wordSel = myRange.Select()
wordSel.Style = constants.wdStyleHeading1# 正文文字替換
w.Selection.Find.ClearFormatting()w.Selection.Find.Replacement.ClearFormatting()w.Selection.Find.Execute(OldStr, False, False, False, False, False, True, 1, True, NewStr, 2)# 頁眉文字替換
w.ActiveDocument.Sections[0].Headers[0].Range.Find.ClearFormatting()w.ActiveDocument.Sections[0].Headers[0].Range.Find.Replacement.ClearFormatting()w.ActiveDocument.Sections[0].Headers[0].Range.Find.Execute(OldStr, False, False, False, False, False, True, 1, False, NewStr, 2)# 表格操作
doc.Tables[0].Rows[0].Cells[0].Range.Text ="123123"worddoc.Tables[0].Rows.Add() # 增加一行# 轉換為html
wc = win32com.client.constantsw.ActiveDocument.WebOptions.RelyOnCSS = 1w.ActiveDocument.WebOptions.OptimizeForBrowser = 1w.ActiveDocument.WebOptions.BrowserLevel = 0 # constants.wdBrowserLevelV4w.ActiveDocument.WebOptions.OrganizeInFolder = 0w.ActiveDocument.WebOptions.UseLongFileNames = 1w.ActiveDocument.WebOptions.RelyOnVML = 0
w.ActiveDocument.WebOptions.AllowPNG = 1w.ActiveDocument.SaveAs( FileName = filenameout, FileFormat = wc.wdFormatHTML )# 列印
doc.PrintOut()# 關閉
# doc.Close()w.Documents.Close(wc.wdDoNotSaveChanges)w.Quit()(3)處理excel
[1]使用PyExcelerator讀寫EXCEL文件(Platform: Win,Unix-like)
優點:簡單易用 缺點:不可改變已存在的EXCEL文件。 PyExcelerator是一個開源的MS Excel文件處理python包。它主要是用來寫 Excel 文件.URL: pyExcelerator download我沒有找到關於PyExcelerator的文檔。只是看到了limodou的一篇介紹。 http://blog.donews.com/limodou/archive/2005/07/09/460033.aspx這個包使用起來還是比較簡單的:)。帶了很多小例子,可以參照。 例mini.py. ================================= #!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman __rev_id__ = """$Id: mini.py,v 1.3 2005/03/27 12:47:06 rvk Exp $""" "導入模塊 from pyExcelerator import * "生成一個工作薄 w = Workbook() "加入一個Sheet ws = w.add_sheet("Hey, Dude") "保存 w.save("mini.xls") ================================= [2]使用COM介面,直接操作EXCEL(只能在Win上) 優點:可以滿足絕大數要求。缺點:有些麻煩。:-) 這方面的例子很多,GOOGLE 看吧:-). 文檔也可以參看OFFICE自帶的VBA EXCEL 幫助文件(VBAXL.CHM)。這裡面講述了EXCEL VBA的編程概念, 不錯的教程!另外,《Python Programming on Win32》書中也有很詳細的介紹。這本書中給出了一個類來操作EXCEL 文件,可以很容易的加以擴展。 #!/usr/bin/env python # -*- coding: utf-8 -*- from win32com.client import Dispatch import win32com.client class easyExcel: """A utility to make it easier to get at Excel. Remembering to save the data is your problem, as is error handling. Operates on one workbook at a time.""" def __init__(self, filename=None): self.xlApp = win32com.client.Dispatch("Excel.Application") if filename: self.filename = filename self.xlBook = self.xlApp.Workbooks.Open(filename) else: self.xlBook = self.xlApp.Workbooks.Add() self.filename = "" def save(self, newfilename=None): if newfilename: self.filename = newfilename self.xlBook.SaveAs(newfilename) else: self.xlBook.Save() def close(self): self.xlBook.Close(SaveChanges=0) del self.xlApp def getCell(self, sheet, row, col): "Get value of one cell" sht = self.xlBook.Worksheets(sheet) return sht.Cells(row, col).Value def setCell(self, sheet, row, col, value): "set value of one cell" sht = self.xlBook.Worksheets(sheet) sht.Cells(row, col).Value = value def getRange(self, sheet, row1, col1, row2, col2): "return a 2d array (i.e. tuple of tuples)" sht = self.xlBook.Worksheets(sheet) return sht.Range(sht.Cells(row1, col1), sht.Cells(row2, col2)).Value def addPicture(self, sheet, pictureName, Left, Top, Width, Height): "Insert a picture in sheet" sht = self.xlBook.Worksheets(sheet) sht.Shapes.AddPicture(pictureName, 1, 1, Left, Top, Width, Height) def cpSheet(self, before): "copy sheet" shts = self.xlBook.Worksheets shts(1).Copy(None,shts(1)) "下面是一些測試代碼。 if __name__ == "__main__": PNFILE = r"c:screenshot.bmp" xls = easyExcel(r"D: est.xls") xls.addPicture("Sheet1", PNFILE, 20,20,1000,1000) xls.cpSheet("Sheet1") xls.save() xls.close()(4)python調用簡訊貓控制項,發簡訊
#! /usr/bin/env python
#coding=gbkimport sysimport win32com.clientocxname="ShouYan_SmsGate61.Smsgate"axocx=win32com.client.Dispatch(ocxname)axocx.CommPort=8#設置COM埠號axocx.SmsService="+8613800100500"#設置簡訊服務號碼axocx.Settings="9600,n,8,1"#設置com埠速度axocx.sn="loyin"c=axocx.Connect(1)#連接簡訊貓或手機print "連接情況",axocx.Link()axocx.SendSms("python確實是很好的","15101021000",0)#發送簡訊
沒太明白題主的具體需求是什麼,我現在工作中也用python處理excel,主要是做一些對excel文件的行列轉化、按條件抽取數據、計算。主要用下面的一些方式:
- 把excel文件處理稱文本格式。主要方式是用vba來保存成CSV、TXT的格式。
- 用python的pandas庫對csv、txt、進行各種變化、處理,pandas非常強大。
轉化成csv、txt格式,然後用python處理,這種處理方式,程序的擴展性應該會比較好一些。
如果直接讀excel,改變excel表格的基本信息(獲取合併的單元格、改變單元格樣式等),我了解的有兩個:- openpyxl(openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files),不過這個只支持2010以上的xlsx文件。
- xlrd https://pypi.python.org/pypi/xlrd 支持xls和xlsx文件。
xlrd基本上沒怎麼用過,openpyxl用過幾次,感覺功能還不錯。
這個問題我覺得我還是有點專業的,雖不是財務,但是大量處理財務數據。
背景:公司程序員是絕對不可能給我一個資料庫賬號的,就算只有讀許可權也不行。公司內網web系統auth不完善,我可以輕鬆繞過許可權爬數據。
起初,用xlrd和xlwt。後來發現這兩個工具寫起來有點麻煩,而且性能不是很優秀。於是改用內置的csv模塊。在這個階段,自動化程度不高,需要大量人工干預和預先處理
現在因為數據量大了,我就在本地弄了個lnmp環境和navicat,將paypal原始數據導入,操作資料庫。現在正在寫這方面的腳本,結合email模塊和windows計劃任務完成全部自動化。SolverStudio for Excel 支持C# Python等,有沒有人試過?
"An integrated environment for optimisation using modelling languages within Excel"
Developing for ExcelIf you are interested in developing for Excel, you might like the following resources.Excel XLL add-in libary for writing C++ add-ins using Visual Studio 2010 (incl Express): Excel xll add-in libraryExcel-DNA provides .net integration with Excel: Excel-DNA - HomePyXLL, a 「free for non-commercial and evaluation purposes」 Excel extension, allows Python code to be used to add menus and user functions within Excel.Pycel will compile a spreadsheet into Python. It was developed to allow non-linear optimisation of aircraft design.PyWorkbooks is an open source Python interface for Excel and GNumeric; it looks very nice, with careful thought given to speed issues (e.g. implenting Generators).Python for Excel (PFE) is a commercial (?) Python scripting system for Excel that 「provides a complete set of tools for building of fully featured applications with Excel front end. It is in-process control of Excel with an out-of-process developement and debugging environment.」有openpyxl讀寫包 ,讀寫分離的包xlrd,xlwt包。
datanitro
等,馬上就要官方實現了。
xlwings,一個包解決所有問題
我覺得題主想問的主要是提高靈活性和利用率。用python完全可以實現。
題主打算用excel去展現,用宏去調用python腳本這可能是因為vba是這樣的模式,但python完全不用這樣做。題主可以把excel為主換成以python為主,用python實現需要實現的功能,然後將處理好的數據存到excel中。或者先讀入excel處理好後再去修改原excel。
用到的庫有xlrd用於讀 xlwt用於寫。這兩個庫就夠一般操作了。cython也不能脫離python runtime。那個python.dll還是要的。excel調用python沒問題。可以用pywin32,支持com。
我原來也用過,用python寫了一個函數,在excel調用。
你這個需求感覺用cx freeze包裝一下,在客戶端安裝就行了,不需要動用cython。推薦閱讀:
※如何優雅的安裝Python的pandas?
※怎樣使 Python 輸出時不換行?
※Python 的縮進有多重要?
※Python沒有常量是不是不夠安全的設計?
※Python的Dictionary的花括弧,應該換行嗎?
TAG:Python | MicrosoftExcel | Cython |