python을 사용하여 excel로 작업하는 중 오류 발생
내 스크립트가 한 엑셀을 동시에 업데이트 하는 동안 다른 엑셀 오류가 발생하여 수동으로 다른 작업을 수행하려면 디스패치를 사용하고 있습니다.
from win32com.client import Dispatch
excel = Dispatch('Excel.Application')
excel.Visible = True
file_name="file_name.xls"
workbook = excel.Workbooks.Open(file_name)
workBook = excel.ActiveWorkbook
sheet=workbook.Sheets(sheetno)
이와 같은 오류가 발생합니다. ( com_error(-2147418111, 'calllee가 호출을 거부했습니다.', 없음, 없음)
어떻게든 극복할수있는 방법이 없을까요..오류없이 다른 엑셀을 업데이트 할수있을까요..
저는 최근에 이와 같은 문제를 겪었습니다.여러 가지 근본 원인이 있을 수 있는 것처럼 들리지만, Python이 후속 호출을 너무 빨리 수행하여 Excel이 따라가지 못했기 때문에, 특히 외부 쿼리를 새로 고치고 있습니다.이 간헐적인 "콜이 호출에 의해 거부되었습니다" 오류를 다음과 같이 삽입하여 해결했습니다.time.sleep()대부분의 통화 사이에 특히 긴 통화(보통 7-15초 사이)에 대한 수면 인수를 늘립니다.이를 통해 Excel은 Python이 추가 명령을 내리기 전에 각 명령을 완료할 수 있습니다.
이 오류는 사용자가 호출하는 COM 개체가 이미 다른 작업을 처리하고 있는 경우 외부 호출을 거부하기 때문에 발생합니다.호출을 비동기적으로 처리할 수 없으며 동작이 무작위로 보일 수 있습니다.
작업에 따라 pythoncom.com _error 또는 pywintypes.com _error가 표시됩니다.이 문제를 해결하기 위한 간단한 방법은 통화를 try-except로 COM 개체에 래핑하고 액세스 오류 중 하나가 발생하면 통화를 재시도하는 것입니다.
자세한 내용은 Mark Hammond & Andy Robinson(O'Reilly 2000)의 Win32 파이썬 프로그래밍에서 발췌한 12장의 "오류 처리" 섹션을 참조하십시오.
Siew Kam Onn의 블로그 게시물 "Excel로 파이썬 프로그래밍, makepy 생성 파이썬 파일에서 COM_error를 극복하는 방법"에 엑셀에 대한 유용한 정보도 있습니다.
저는 같은 문제로 어려움을 겪어왔지만, 지금까지 저에게 맞는 해결책을 만들었습니다.
Excel COM 객체를 랩핑하는 ComWrapper라는 클래스를 만들었습니다.중첩된 모든 개체를 자동으로 래핑하고 ComWrapper에서 호출하고 래핑된 개체에 대한 호출 또는 할당을 함수하는 인수로 사용할 때 래핑을 해제합니다.래퍼는 "Call is rejected by calllee" 예외를 잡고 상단에 정의된 시간 초과에 도달할 때까지 호출을 재시도함으로써 작동합니다.시간 초과에 도달하면 최종적으로 예외가 래퍼 개체 외부에 던져집니다.
랩핑된 객체에 대한 함수 호출은 마법이 발생하는 함수 _com_call_wrapper에 의해 자동으로 랩핑됩니다.
작동을 위해서는 ComWrapper를 사용하여 Dispatch의 컴 오브젝트를 포장한 후 코드 하단처럼 평소대로 사용하면 됩니다.문제가 있으면 댓글 달아주세요.
import win32com.client
from pywintypes import com_error
import time
import logging
_DELAY = 0.05 # seconds
_TIMEOUT = 60.0 # seconds
def _com_call_wrapper(f, *args, **kwargs):
"""
COMWrapper support function.
Repeats calls when 'Call was rejected by callee.' exception occurs.
"""
# Unwrap inputs
args = [arg._wrapped_object if isinstance(arg, ComWrapper) else arg for arg in args]
kwargs = dict([(key, value._wrapped_object)
if isinstance(value, ComWrapper)
else (key, value)
for key, value in dict(kwargs).items()])
start_time = None
while True:
try:
result = f(*args, **kwargs)
except com_error as e:
if e.strerror == 'Call was rejected by callee.':
if start_time is None:
start_time = time.time()
logging.warning('Call was rejected by callee.')
elif time.time() - start_time >= _TIMEOUT:
raise
time.sleep(_DELAY)
continue
raise
break
if isinstance(result, win32com.client.CDispatch) or callable(result):
return ComWrapper(result)
return result
class ComWrapper(object):
"""
Class to wrap COM objects to repeat calls when 'Call was rejected by callee.' exception occurs.
"""
def __init__(self, wrapped_object):
assert isinstance(wrapped_object, win32com.client.CDispatch) or callable(wrapped_object)
self.__dict__['_wrapped_object'] = wrapped_object
def __getattr__(self, item):
return _com_call_wrapper(self._wrapped_object.__getattr__, item)
def __getitem__(self, item):
return _com_call_wrapper(self._wrapped_object.__getitem__, item)
def __setattr__(self, key, value):
_com_call_wrapper(self._wrapped_object.__setattr__, key, value)
def __setitem__(self, key, value):
_com_call_wrapper(self._wrapped_object.__setitem__, key, value)
def __call__(self, *args, **kwargs):
return _com_call_wrapper(self._wrapped_object.__call__, *args, **kwargs)
def __repr__(self):
return 'ComWrapper<{}>'.format(repr(self._wrapped_object))
_xl = win32com.client.dynamic.Dispatch('Excel.Application')
xl = ComWrapper(_xl)
# Do stuff with xl instead of _xl, and calls will be attempted until the timeout is
# reached if "Call was rejected by callee."-exceptions are thrown.
저는 여기서 새로운 질문에 같은 대답을 했습니다: https://stackoverflow.com/a/55892457/2828033
계산 사이클이 실행되는 동안 이(차단) 오류가 지속적으로 나타나는 집중 엑셀 시트를 실행합니다.
해결책은 for loop을 사용하는 것입니다.
저는 제 코드 솔루션의 다음과 같은 섹션을 제공합니다.
# it failed, keep trying
attempt_number = 0
reading_complete = False
while reading_complete==False:
try:
workbook = xw.Book(file_to_read)
reading_complete = True
print('file read...')
except:
reading_complete = False
attempt_number += 1
print('attempt:', attempt_number)
if attempt_number > 5:
print('no good: exiting the process')
exit()
위치:
file_to_readExcel 워크북의 전체 경로 및 이름입니다.attempt_number시도 .도를록다은다록를es도은ote
언급URL : https://stackoverflow.com/questions/3718037/error-while-working-with-excel-using-python
'programing' 카테고리의 다른 글
| null 가능한 int 직렬화 (0) | 2023.09.14 |
|---|---|
| Ubuntu의 Oracle XE에서 새 데이터베이스 생성 (0) | 2023.09.14 |
| jQuery 또는 페이지의 메모리 사용량을 찾기 위한 javascript (0) | 2023.09.09 |
| 함수와 닫힘의 균등성을 검사하려면 어떻게 해야 합니까? (0) | 2023.09.09 |
| ASP에 의해 트리거된 비동기 작업 실행.NET 웹페이지 요청 (0) | 2023.09.09 |