【问题标题】:Export from MS Access to Excel when Access has an "Nz" expression using python当 Access 使用 python 具有“Nz”表达式时,从 MS Access 导出到 Excel
【发布时间】:2020-12-29 23:46:17
【问题描述】:

我有一个要导出到 excel 的访问表,但访问表(以及它调用的一些表)使用“Nz”表达式。我曾尝试用 IIf(IsNull( 甚至合并,但我似乎无法得到任何工作。我知道 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)")"

【问题讨论】:

  • 作为Nz(thing, "") 的替代品,您尝试过IIf(IsNull(thing), '', thing) 吗?我刚试过,它似乎对我有用…… (注意替换中的单引号。)
  • 我确实尝试过,它确实适用于在 sql 中导出可见的 Nz 表达式。我应该澄清一下,主要问题是在连接表中调用的某些表中的 Nz 表达式在 sql 中不可见以替换为 'code' IIf(IsNull(thing), '', thing) 'code' .我想我需要一些可以在基本 sql 上工作的东西,比如“SELECT * FROM tableWithMultNZExpressions”。
  • 我确实尝试过,它确实适用于在 sql 中导出可见的 Nz 表达式。我应该澄清一下,主要问题是连接表中调用的某些表中的 Nz 表达式在 sql 中不可见以替换为IIf(IsNull(thing), '', thing)。我想我需要一些可以在 SELECT * FROM tableWithMultNZExpressionscode 之类的基本 sql 上工作的东西。 - 编辑以制作降价代码

标签: python ms-access pyodbc


【解决方案1】:

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

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

还有一个名为 [query1] 的已保存查询,该查询使用 Nz()

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()

【讨论】:

  • 这可以让我使用打印命令查看数据,但我一直坚持让它导出到 excel。现在通过 pywin32 文档试图弄清楚。
  • 完整代码用于将带有Nz 表达式的访问表导出到.csv。 """ 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() # Line below is probably superfluous rst = db.OpenRecordset("SELECT * FROM tableNamet", dbOpenDynaset) acExportDelim = 2 msa.DoCmd.TransferText(acExportDelim, None, "tableName", "export_path.csv"), True
  • 注意:通过修改解决方案可能可以导出到excel...否则可以使用pandas将.csv转换为.xlsx。
猜你喜欢
  • 2017-08-28
  • 1970-01-01
  • 2017-07-12
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多