如何解决多线程Excel应用程序的com_error:(-2147221008,'CoInitialize尚未被调用。',None,None)?

问题描述 投票:0回答:1

我有一个 PYQT5 应用程序的工作线程,当调用该函数时,该线程会输入进度条。问题是,每当我调用 excel 函数时,我都会收到 com_error: (-2147221008, 'CoInitialize 尚未被调用。', None, None) 。我该如何修复这个错误?

我创建了以下 Worker 类和调用 Worker 类的进度条类。这是 UI 的图像在此处输入图像描述

import sys
import time

from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QDialog, QApplication,QMainWindow, QWidget, QProgressBar,QVBoxLayout
from PyQt5.QtCore import QThread, pyqtSignal, QObject, pyqtSlot
import win32com.client as win32


month="April"    
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = True
excel.DisplayAlerts = False
destination=rf"C:\Users\RC\Desktop\Important Emails\WIP Special Workings\FY2024\{month}"


class Worker(QObject):
    finished = pyqtSignal()
    intReady = pyqtSignal(int)
    @pyqtSlot()
    def proc_counter(self):
     count=0
     data_file = rf"C:\Users\RC\Desktop\Important Emails\WIP Special Workings\FY2024\{month}\gl transaction download-cc1.xlsx"
     template_file=rf"C:\Users\RC\Desktop\Important Emails\WIP Special Workings\FY2024\{month}\GL Dump - {month}.xlsx"
     wb_template = excel.Workbooks.Open(template_file)
     wb_data = excel.Workbooks.Open(data_file)
     count+=20
     self.intReady.emit(count)
     wb_template.Sheets("GL Data Jan").Range("A2:W5000").Clear()
     wb_data.Sheets("Sheet1").Range("A2:W5000").Copy()
     wb_template.Sheets("GL Data Jan").Paste(wb_template.Sheets("GL Data Jan").Range('A2'))
     count+=20
     self.intReady.emit(count)
     wb_template.RefreshAll()
     time.sleep(3)
     count+=40
     self.intReady.emit(count)
     wb_template.Save()
     count+=19
     self.intReady.emit(count)
     wb_template.Close(True)
     wb_data.Close(True)
     excel.Application.Quit()
     count+=1
     self.intReady.emit(count)
     self.finished.emit()
     return None
            

            
    
class PopUpProgressB(QWidget):

    def __init__(self):
        super().__init__()
        self.pbar = QProgressBar(self)
        #self.pbar.setRange(0,0)
        self.pbar.setGeometry(30, 40, 500, 75)
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.pbar)
        self.setLayout(self.layout)
        self.setGeometry(300, 300, 550, 100)
        self.setWindowTitle('Progress Bar')

        self.obj = Worker()
        self.thread = QThread()
        self.obj.intReady.connect(self.on_count_changed)
        
        self.obj.moveToThread(self.thread)
     
        self.obj.finished.connect(self.thread.quit)
        self.obj.finished.connect(self.hide)  # To hide the progress bar after the progress is completed
        self.thread.started.connect(self.obj.proc_counter)
       

    def start_progress(self):
        # To restart the progress every time
        self.show()
        self.thread.start()

    def on_count_changed(self, value):
        self.pbar.setValue(value)

class Screen2(QDialog):
    def __init__(self):
        super(Screen2,self).__init__()
        loadUi("GL_Dump_Curr.ui",self)
        self.pushButton_2.clicked.connect(self.gotoScreen1)
        self.popup=PopUpProgressB()
        self.pushButton.clicked.connect(self.popup.start_progress)
python excel multithreading pyqt5 pywin32
1个回答
0
投票

也许另一个问题的答案有帮助:

import pythoncom


def onThreadStart(threadIndex):
  pythoncom.CoInitialize()

cherrypy.engine.subscribe('start_thread', onThreadStart)
© www.soinside.com 2019 - 2024. All rights reserved.