You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本报WinError32:文件被其他进程占用问题求助

问题描述

我在Spyder中编写了一个供同事和自己使用的小型脚本,用于更新简单的Excel文件。自己运行代码时无报错,但同事运行相同代码时,出现错误提示:进程无法访问文件,因为该文件正被其他进程占用。已尝试在同事运行时关闭自己的程序、将文档重命名后重新运行,但错误仍未解决。

文件路径(已移除公司信息前缀)

#Files 
swx_f = 'Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\SWX' + dayval + '.xlsx'

caris_f = 'Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\CARIS' + dayval + '.xlsx'

cspcaris_f = 'Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\CSPvsCARIS' + dayval + '.xlsx'

错误代码

PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\saed\\OneDrive\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\SWX202408.xlsx' -> 'C:\\Users\\saed\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\File Archive\\SWX202408.xlsx'


During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File ~\AppData\Local\anaconda3\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec

    exec(code, globals, locals)

  File c:\users\saed\.spyder-py3\monthly closure.py:107

    shutil.move(swx_f, dest_new)

  File ~\AppData\Local\anaconda3\Lib\site-packages\shutil.py:868 in move

    os.unlink(src)

PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\saed\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\SWX202408.xlsx'

完整代码

###Headers
length = 0
header1 = ['AWB Number']
header2 = ['Departure Date', 'Match Status', 'Flight Number', 'Net Revenue Prorated', 'Source']
swxhead = ['AWB Number', 'Origin', 'Destination', 'SWX Net Amount']

###Lists/Dicts
swx_list = []

caris_dict = {}
cspcaris_dict = {}
final_dict = {}

###Record Counts
swxcount = 0
cariscount = 0
cspcariscount = 0
#combinedcount = 0

###Build SWX List

workbook1 = xl.load_workbook(filename=swx_f)
wb1 = workbook1.active

for line in wb1.iter_rows(values_only=True):
    if line[2] is not None:
        if '724-' in line[2]:
            swxamt = float(line[10])
            amtround = np.around(swxamt, decimals=2)
            swx_list.append([line[2].strip(), line[4].strip(), line[5].strip(), amtround])
            swxcount +=1
        else:
            pass
    else:
        pass
workbook1.close()
shutil.move(swx_f, dest_new)        

###Build CARIS List      

workbook2 = xl.load_workbook(filename=caris_f)
wb2 = workbook2.active

for row in wb2.iter_rows(values_only=True):
    if row[3] is not None:
        if '724-' in row[3].strip():
            awb = row[3].strip()
            depdate = row[4]
            flt = row[5]
            netrev = row[6]
            
            if awb in caris_dict.keys():
                caris_dict[awb] += [depdate, flt, netrev, 'CARIS']
                cariscount +=1
            else:
               caris_dict[awb] = [depdate, flt, netrev, 'CARIS'] 
               cariscount +=1
        else:
            pass
    else:
        pass
     
workbook2.close()
shutil.move(caris_f, dest_new)        
            

###Build CSP vs CARIS List

workbook3 = xl.load_workbook(filename=cspcaris_f)
wb3 = workbook3.active

for r in wb3.iter_rows(values_only=True):
    if r[1] is not None:
        if '724' in str(r[1]):
            awb2 = str(r[1])
            depdate2 = r[4].strftime('%d/%m/%Y')
            flt2 = r[3]
            netrev2 = r[6]
            
            if awb2 in cspcaris_dict.keys():
                cspcaris_dict[awb2] += [depdate2, flt2, netrev2, 'CSPCARIS']
                cspcariscount +=1
            else:
                cspcaris_dict[awb2] = [depdate2, flt2, netrev2, 'CSPCARIS']
                cspcariscount +=1

        else:
            pass
    else:
        pass
workbook3.close()
shutil.move(cspcaris_f, dest_new)        


###Build Combined CARIS and CSP vs CARIS Dict

for k in caris_dict.keys():
    if k in cspcaris_dict.keys():
        final_dict[k] = ['Matched'] + caris_dict[k] + cspcaris_dict[k]
        cspcaris_dict[k] += ['Matched']
    else:
        final_dict[k] = ['No Match'] + caris_dict[k]
for j in cspcaris_dict.keys():
    if cspcaris_dict[j][-1] == 'Matched':
        pass
    elif j in caris_dict.keys():
        final_dict[j] = ['Matched'] + caris_dict[j] + cspcaris_dict[j]
    else:
        final_dict[j] = ['No Match'] + cspcaris_dict[j]
        
for l in final_dict.keys():
    if len(final_dict[l]) > length:
        length = len(final_dict[l])
    else:
        pass
            
###Write Final File###

###Create report counts for error checking 
indtotal = swxcount + cariscount + cspcariscount

####Headers

multiplier = int(length / 5)
variablehead = header2 * multiplier
final_head = header1 + variablehead

###Create workbook and name sheets 
wb = xl.Workbook()
ws1 = wb.create_sheet('CARIS CSP', 0)
ws2 = wb.create_sheet('SWX', 1)
ws3 = wb.create_sheet('Record Counts', 2)

ws3.append(['Record Counts - Individual Reports', 'SWX Records:', swxcount, 'CARIS Records:', cariscount, 'CSP vs CARIS Records:', cspcariscount, 'Total:', indtotal])
#ws2.append(['Record Counts - This Report', '', '', 'Combined Records:', combinedcount, 'Unique Records:', uniquecount, 'Total:', reporttotal])

ws2.append(swxhead)
for t in swx_list:
    ws2.append(t)
    
ws1.append(final_head)
for w in final_dict.keys():
    newlist = [w] + final_dict[w]
    ws1.append(newlist)

    
outputfile = r'C:\\Users\\' + user_code + '\\Internal Team Library\\Team\\CS\\Darian\\CARISCSPSWX_Report\\Completed Reports\\SWXCARISCSP Records Report ' + dayval + 'TESTTEST.xlsx'
wb.save(outputfile)        
wb.close()

messagebox.showinfo("Success!", "Report Completed")

master_with_quotes = '"' + outputfile + '"'
os.system('start "EXCEL.exe" {}'.format(master_with_quotes))
问题根源与解决办法

1. OneDrive同步锁定

同事的文件路径包含OneDrive,OneDrive的实时同步机制会在文件被读取/修改时自动锁定文件,导致shutil.move无法操作。

  • 临时解决:让同事暂停OneDrive同步,运行完脚本后再恢复;
  • 永久优化:修改脚本逻辑,先将文件从OneDrive复制到本地非同步目录,处理完成后再归档到目标位置。

2. Excel进程残留或隐性占用

即使手动关闭了Excel,系统后台可能仍有EXCEL.EXE进程残留,或者文件被杀毒软件、预览工具等后台程序锁定。

  • 让同事打开任务管理器,结束所有EXCEL.EXE进程;
  • 关闭文件资源管理器的预览功能,避免系统自动锁定文件;
  • 在脚本中添加延迟,确保workbook.close()完全释放文件后再执行shutil.move,例如在close()后添加time.sleep(2)。

3. 代码优化:确保文件句柄完全释放

虽然代码中调用了workbook.close(),但openpyxl偶尔会因缓存或上下文问题未彻底释放文件,改用with上下文管理器可以更稳妥地管理文件资源:

###Build SWX List
with xl.load_workbook(filename=swx_f) as workbook1:
    wb1 = workbook1.active
    for line in wb1.iter_rows(values_only=True):
        if line[2] is not None:
            if '724-' in line[2]:
                swxamt = float(line[10])
                amtround = np.around(swxamt, decimals=2)
                swx_list.append([line[2].strip(), line[4].strip(), line[5].strip(), amtround])
                swxcount +=1
# with块结束后自动关闭workbook,无需手动调用close()
shutil.move(swx_f, dest_new)

按此方式修改CARIS和CSPvsCARIS的读取代码,确保文件句柄被正确释放。

4. 路径格式规范

Windows系统下建议使用原始字符串(rf"")定义路径,避免转义字符导致的路径识别错误:

swx_f = rf'Internal Team Library\Team\CS\Darian\CARISCSPSWX_Report\SWX{dayval}.xlsx'
caris_f = rf'Internal Team Library\Team\CS\Darian\CARISCSPSWX_Report\CARIS{dayval}.xlsx'
cspcaris_f = rf'Internal Team Library\Team\CS\Darian\CARISCSPSWX_Report\CSPvsCARIS{dayval}.xlsx'

内容的提问来源于stack exchange,提问作者dare1331

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:37:03