Hi @a81383. I had not really looked into using the ModelStates.ExcelWorkSheet property that much, due to using either more traditional means, or the ModelStatesTable object directly, but you (and another recent poster) got me interested in it. So, I decided to create an iLogic rule to explore it. With the right references, as mentioned above, and some familiarity with how to navigate 2-dimensional data grid, as well as how to copy, edit, write back, whole blocks of data at a time, I wrote the following code, sort of as a guide, to help others out in this area. It is working OK for me so far. My testing was done on a PartDocument with multiple ModelStates, so if you are working with an assembly, or do not know which document type it may be, then you will obviously have to alter the first couple of lines to suit your needs.
Here is the code I created:
AddReference "Microsoft.Office.Interop.Excel.dll"
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Interop.Excel
Dim oPDoc As PartDocument = ThisDoc.FactoryDocument
Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
Dim oMSs As ModelStates = oPDef.ModelStates
Dim oWS As Excel.Worksheet = oMSs.ExcelWorkSheet
Dim oWB As Excel.Workbook = oWS.Parent
'Dim oWBType As String = TypeName(oWB)
'MsgBox("oWBType = " & oWBType,,"")
Dim oCells As Excel.Range = oWS.Cells
'a couple good hints here, in case you want to stay within bounds of Excel
'Dim oRowsCount As Integer = oWS.UsedRange.Rows.Count
'Dim oColsCount As Integer = oWS.UsedRange.Columns.Count
'copy the whole block of data to 'memory' (a 2-dimensional Array variable)
'As Object, because some data may be String, some Double, some Integer, etc.
Dim oAllRetrievedData(, ) As Object = oWS.UsedRange.Value
'now we can work with the data without working directly with Excel for a while (faster)
Dim oRows As Integer = oAllRetrievedData.GetUpperBound(0)
Logger.Info("oRows = " & oRows)
Dim oCols As Integer = oAllRetrievedData.GetUpperBound(1)
Logger.Info("oCols = " & oCols)
For oRow As Integer = 1 To oRows
For oCol As Integer = 1 To oCols
'again, As Object, because data may be String, or Double, or Integer, etc.
Dim oCellData As Object = oAllRetrievedData(oRow, oCol)
'Logger.Info("Cell at Row" & oRow & " & Col" & oCol & " = " & oCellData.ToString)
'<<<< edit data here, if needed, then when done, write this block of data back to the source >>>>
'notice how I am 'setting' the value...not to oCellData, but to the Array directly
'If oCellData.ToString = "2 in" Then oAllRetrievedData(oRow, oCol) = "3 in"
Next 'oCol
Next 'oRow
'here is where you write all the edited data back to the Excel Worksheet
oWS.UsedRange.Value = oAllRetrievedData
oWB.Save
oWB.Close
If oPDoc.RequiresUpdate Then oPDoc.Update2(True)
'If oPDoc.Dirty Then oPDoc.Save
If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.
Wesley Crihfield

(Not an Autodesk Employee)