Search code examples
pythonnumpypywin32win32comcomtypes

win32com MemoryError: CreatingSafeArray attempting to insert data into excel


I'm attempting to insert a list of lists into excel (such that each inner list represents a row, each is of the same length) with the following call :

#Assume ws is correctly initialized to an excel worksheet object
ws.Range(ws.Cells(1,1),ws.Cells(len(myList),len(myList[0]))).value = myList

myList lists contain strings and numpy floats and ints. I get the following error when I attempt to execute the call above:

Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "C:\Python32\lib\site-packages\win32com\client\dynamic.py", line 570, in __setattr__
    self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
MemoryError: CreatingSafeArray

what is causing this win32com.client MemoryError? Thanks!


Solution

  • I determined the problem was with the numpy values:

    >>> #Initialize test list with 2 numpy float64 values
    >>> test = [numpy.float64(456),numpy.float64(456)]
    >>> #Attempting to insert a list containing only numpy data types will error
    >>> ws.Range(ws.Cells(1,1),ws.Cells(1,2)).value = test
    Traceback (most recent call last):
      File "<interactive input>", line 1, in <module>
      File "C:\Python32\lib\site-packages\win32com\client\dynamic.py", line 570, in __setattr__
        self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
    MemoryError: CreatingSafeArray
    >>> #Changing one of the values to any other standard python data type will allow the list to be inserted
    >>> test[1] = 'test'
    >>> ws.Range(ws.Cells(1,1),ws.Cells(1,2)).value = test
    # A list with multiple numpy data types will error upon insertion
    >>> test.append(numpy.int64(456))
    >>> ws.Range(ws.Cells(1,1),ws.Cells(1,3)).value = test
    Traceback (most recent call last):
      File "<interactive input>", line 1, in <module>
      File "C:\Python32\lib\site-packages\win32com\client\dynamic.py", line 570, in __setattr__
        self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
    MemoryError: CreatingSafeArray
    >>> """ Conclusion: A list can be inserted only if all of the numpy data types are the same and there is a built-in data type in the list as well """
    >>> test[2] = numpy.float64(test[2])
    >>> ws.Range(ws.Cells(1,1),ws.Cells(1,3)).value = test
    >>>
    

    My solution was to simply convert all values in my list to string before inserting, guaranteeing no data types will give me problems.