微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当 Access 具有使用 python 的“Nz”表达式时,从 MS Access 导出到 Excel

如何解决当 Access 具有使用 python 的“Nz”表达式时,从 MS Access 导出到 Excel

我有一个访问表,我试图将其导出到 excel,但访问表(以及它调用的一些表)使用“Nz”表达式。我试过用 IIf(IsNull( 甚至合并) 替换 Nz,但我似乎无法得到任何工作。我知道 pyodbc 访问驱动程序不支持他的 Nz 表达式,所以我试图找出解决方法。此外,我无权对 Access 数据库进行任何更改(这可能是最简单的解决方案。

一个问题是连接中的一些列也有 NZ 表达式。也许某些东西会给脚本遇到的任何 Nz 表达式提供 0 的总值?我不太会使用 sql,所以这可能很容易,但我一直无法弄清楚如何。

我已经在没有 Nz 表达式的表上运行了代码并且它可以工作,所以我知道驱动程序/cnxn 是正确的。

import pyodbc
import pandas as pd

ly_rep_temp_path = r"C:\examplePath\msAccessFile.accdb"
temp_path = r"C:\example\temoraryStorage"


driver = '{Microsoft Access Driver (*.mdb,*.accdb)}'


cnxn = pyodbc.connect(Driver=driver,DBQ=ly_rep_temp_path)


sql = """
SELECT rep.old,rep.new,Left(Nz([oldI].[mName],""),10) AS oldM,Left(Nz([newI].[mName],10) AS newM,oldI.primary AS oldS,newI.primary AS newS,oldI.primaryMR AS oldR,newI.primaryM AS newR,FROM export_byI INNER JOIN ((rep INNER JOIN availableI AS oldI ON rep.olIs = oldI.isI) INNER JOIN availableI AS newI ON rep.nIsI = newI.isI) ON export_byI.IstI = rep.nwIsI
ORDER BY rep.nwIsI;
"""

crsr = cnxn.execute(sql)
for row in crsr.fetchall():
    lpd_df = pd.read_sql(sql,cnxn)
    print(lpd_df.columns)
    lpd_df.to_excel(temp_path + '/zFinal.xlsx')
    full_export_path = (temp_path + '/zFinal.xlsx')
    # return full_export_path
crsr.close()
cnxn.close()

运行代码时出现以下错误: "pyodbc.ProgrammingError: ('42000',"[42000] [Microsoft][ODBC Microsoft Access Driver] 表达式中未定义函数 'Nz'。(-3102) (sqlExecDirectW)")"

解决方法

所以如果我们有一个名为 [Donor] 的表

DonorID  DonorName  Comments     
-------  ---------  -------------
      1  Gord       cheapskate   
      2  Bill                    
      3  Marsha     Jan's nemesis

以及使用 Nz()

的名为 [query1] 的已保存查询
SELECT Donor.DonorID,Donor.DonorName,Nz([Comments],"(no comment)") AS txt
FROM Donor;

在 Microsoft Access 应用程序本身中产生以下内容

DonorID  DonorName  txt          
-------  ---------  -------------
      1  Gord       cheapskate   
      2  Bill       (no comment) 
      3  Marsha     Jan's nemesis

如果我们尝试在 pyodbc 中执行 crsr.execute("SELECT * FROM query1"),我们会得到

"pyodbc.ProgrammingError: ('42000',"[42000] [Microsoft][ODBC Microsoft Access Driver] 表达式中未定义函数 'Nz'。(-3102)

因为 Nz() 不是 Access 数据库引擎 (ACE) 的内置函数;它是 VBA 表达式引擎的一部分。因此,为了从 Python 执行该查询,我们需要使用 pywin32 和 COM 自动化来运行 MSACCESS.EXE 的实例并以这种方式执行查询:

"""
requires: pip install pywin32
"""
import win32com.client

# ACE.DAO constants
dbOpenDynaset = 2

msa = win32com.client.Dispatch("Access.Application")
msa.OpenCurrentDatabase(r"C:\Users\Public\Database1.accdb")
db = msa.CurrentDb()
rst = db.OpenRecordset("SELECT * FROM query1",dbOpenDynaset)
while not rst.EOF:
    print(rst.Fields("txt").Value)
    rst.MoveNext()
"""console output:
cheapskate
(no comment)
Jan's nemesis
"""
msa.Quit()

编辑:如果您想将查询导出到 Excel,您可以直接从 Access.Application 实例执行此操作:

acExport = 1
acSpreadsheetTypeExcel12Xml = 10
msa.DoCmd.TransferSpreadsheet(
    acExport,acSpreadsheetTypeExcel12Xml,"query1",r"C:\__tmp\test.xlsx"
)
msa.Quit()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。