Source code for dstream_excel.dstream.workbook.populate

from win32com.client import constants
from pywintypes import com_error
import time
import traceback, sys
import pythoncom


from exceldriver.tools import _restart_excel_with_addins_and_attach
from .wait import (
    _wait_for_datastream_result,
    WorkbookClosedException,
    DatastreamDataErrorException,
    _get_cell_by_index
)
from exceldriver.exceptions import NoExcelWorkbookException

[docs]def populate_datastream_for_file(filepath, excel, retries_remaining=3, close_workbook=False, index=0): """ Private function has main functionality. This is a wrapper to add retries afer com errors """ # Necessary to be called in each new thread or process which uses COM (communicate with Microsoft products) pythoncom.CoInitialize() # Even if things are going normally, restart every 500 worksheets as there is a memory leak if index % 500 == 0 and retries_remaining == 3: excel = _restart_excel_with_addins_and_attach(start_sleep=60) # Stop retries if retries_remaining <= 0: print(fr'ERROR: Could not process {filepath}. Skipping and moving to "..\failed".') return excel, False try: # If we are retrying, need to close the workbook before trying to populate if close_workbook: excel.CutCopyMode = False time.sleep(1) if excel.ActiveWorkbook: excel.ActiveWorkbook.Close(SaveChanges=False) time.sleep(5) _populate_datastream_for_file(filepath, excel) return excel, True except (com_error, WorkbookClosedException, DatastreamDataErrorException, NoExcelWorkbookException) as e: print(f'Error {e} populating {filepath}. Will wait 30 seconds, restart Excel, and try again.') traceback.print_tb(sys.exc_info()[2]) time.sleep(30) excel = _restart_excel_with_addins_and_attach(start_sleep=60) return populate_datastream_for_file(filepath, excel, retries_remaining=retries_remaining - 1, close_workbook=True)
def _populate_datastream_for_file(filepath, excel): wb = excel.Workbooks.Open(filepath) _run_datastream_func(excel) successful = _wait_for_datastream_result(excel) _copy_paste_values(excel, wb) _relabel_date(excel, wb) excel.ActiveWorkbook.Close(SaveChanges=True) return successful def _run_datastream_func(excel): dstream_func_cell = _get_cell_by_index(excel, 1, 1) dstream_func_cell.Activate() dstream_func_cell.Calculate() def _copy_paste_values(excel, wb, range='A1:J10000'): ws = wb.Sheets('Sheet') ws.Range(range).Copy() ws.Range(range.split(':')[0]).PasteSpecial(Paste=constants.xlPasteValues, Operation=constants.xlNone) excel.CutCopyMode = False def _relabel_date(excel, wb, cell_range: str ='A1'): """ Currently date is coming in with odd name, replace with Date """ ws = wb.Sheets('Sheet') ws.Range(cell_range).Value = 'Date'