Clement,
I guess I’m a little mixed up then. At the top of the thread the following line of code throws an error:
I have a macro crashing here in Rhino 8. Looking for a solution to this.
Eric
Clement,
I guess I’m a little mixed up then. At the top of the thread the following line of code throws an error:
I have a macro crashing here in Rhino 8. Looking for a solution to this.
Eric
Hi @ebunn3, i can repeat that if you read my posts at the beginning of the thread. So you’re using Office 365 and IronPython in Rhino 8 using NETCore on Windows right ? What happens if you run this:
#! python 2
import System
progType = System.Type.GetTypeFromProgID("Excel.Application")
excelApp = System.Activator.CreateInstance(progType)
excelApp.Visible = True
does it open Excel ? If not what error do you get ? Did you try out referencing by path as shown above ?
_
c.
Clement
I’ve gone back and read though the entire thread again and did see that I missed this. When I run the following code that you supplied along with GetActiveObject I so now see that Excel opens. I can potentially use this now and start to check out my other scripts that employ Excel. Thank you again for being so patient.
#! python 2
import System
progType = System.Type.GetTypeFromProgID("Excel.Application")
excelApp = System.Activator.CreateInstance(progType)
excelApp.Visible = True
import os
user = os.environ["USERPROFILE"]
#C:\Users\ebunn\SEE RhinoScript
path = user + "/SEE RhinoScript/Utils/bin/Release/net48/Utils.dll"
print (path)
#! python 2
import clr
clr.AddReferenceToFileAndPath(path)
from Utils import *
app = Marshal2.GetActiveObject("Excel.Application")
print(app)
Eric
Clement,
Just an update on the last reply. I have tested this successfully with my other scripts and can now interact with Excel. I distribute all of my scripts to a group in my organization and have put the Utils directory in the master directory that I distribute and this seems to be solving my issues with Excel. I use Excel primarily as a database and need to read and write to it. Thanks again for all of your help.
Eric
Thought I would post the whole module that I’m using to read and write to Excel with the changes for Rhino 8. Also, the Utils folder that is used by the function “getRunnngXL”. Thanks to all for all the help with this.
Eric
#! python 2
#globals
increment = 0
xlDown = -4121
xlToLeft = -4159
xlToRight = -4161
xlUp = -4162
xlWindowState = -4143
xlApp = None
Excel = None
import System
import os
import clr
import Rhino
class Excel_Transfer:
"""Transfer UF Info to Excel"""
def __init__(self,xlName,vals,wks_Name,XL_Close):
self._xlName = xlName#path to workbook
self._vals = vals#values to write to workbook
self._wks_Name = wks_Name#worksheet name
self._XL_Close = XL_Close#close Excel, True or False
def getXL(self):
"""Gets the Excel Object"""
#Set the Excel Object
excel = None
#Try to get running instance of Excel
try:
#Attempt to get running instance of Excel
excel = getRunnngXL()
if excel:
#Set the Excel Object
self.Excel = excel
return excel
excel = None
except:
excel = None
if excel == None:
try:
#Start Excel if there is no running instance
#! python 2
progType = System.Type.GetTypeFromProgID("Excel.Application")
excelApp = System.Activator.CreateInstance(progType)
excelApp.Visible = True
#Set Excel Size
excelApp.WindowState=xlWindowState # XlWindowState.xlNormal
#Set the Excel Object
self.Excel = excelApp
excel = excelApp
if excel: return excel
except:
if excel: return excel
def XL_Close(self,workbook,worksheet):
"""Saves and Closes the Excel Workbook"""
#Save Workbook
workbook.Save()
#Close Workbook
if self._XL_Close == True:
ct=0
wbkName = workbook.name
for i in self.Excel.Workbooks:
#print(i.name)
if i.name == wbkName:
workbook.Close()
ct+=1
if ct == 1:
os.system('taskkill /f /im Excel.exe')#This kills all open instances of Excel
#self.Excel.Quit()
def updateXL(self):
"""Update Excel with New Values"""
#Get the XL Object
xlApp = self.getXL()
fpeDir = self._xlName
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("en-US")
workbook = xlApp.Workbooks.Open(r"" + fpeDir + "")
#print("" + fpeDir + "")
#Get the Active Sheet
worksheet = workbook.Worksheets[self._wks_Name]
# print(worksheet.Name)
if worksheet.Name != self._wks_Name:
return
#Loop through vals
count = 1
lLastRow = worksheet.Cells(worksheet.Rows.Count, 1).End(xlUp).Row
lLastCol = worksheet.Cells(lLastRow ,worksheet.Columns.Count).End(xlToLeft).Column
self._vals[0]=lLastRow+increment
for i in self._vals:
worksheet.Cells[lLastRow+increment,count].value = i
count += 1
#Save Workbook
workbook.Save()
#Close Workbook
self.XL_Close(workbook,worksheet)
def GetValsXL(self):
"""Get values from Excel Worksheet"""
#Get the XL Object
xlApp = self.getXL()
fpeDir = self._xlName
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("en-US")
workbook = xlApp.Workbooks.Open(r"" + fpeDir + "")
# print("" + fpeDir + "")
#Get the Active Sheet
worksheet = workbook.Worksheets[self._wks_Name]
print(worksheet.Name,self._wks_Name)
if worksheet.Name != self._wks_Name:
return
#Loop through vals
count = 1
lLastRow = worksheet.Cells(worksheet.Rows.Count, 1).End(xlUp).Row
lLastCol = worksheet.Cells(lLastRow ,worksheet.Columns.Count).End(xlToLeft).Column
xlRange = worksheet.Range[worksheet.Cells[lLastRow,1],worksheet.Cells[lLastRow,lLastCol]]
self._vals = xlRange.value2
#Close Workbook
self.XL_Close(workbook,worksheet)
retVals = list(self._vals)
#print(retVals)
return retVals
def getRunnngXL():
"""Try to get a running instance of Excel."""
try:
user = os.environ["USERPROFILE"]
#C:\Users\ebunn\SEE RhinoScript
#THIS IS THE PATH TO THE XL_Utils DIRECTORY THAT CONTAINS Utils.dll
path = user + "/SEE RhinoScript/XL_Utils/bin/Release/net48/Utils.dll"
#add reference to path
clr.AddReferenceToFileAndPath(path)
#Import Marshal2
from Utils import Marshal2
#get running instance of Excel
excel = Marshal2.GetActiveObject("Excel.Application")
print(excel,"Excel Running GetUtils")
return excel
except:
print("No Running Instance of Excel Get Utils")
return None
XL_Utils.zip (5.5 KB)