Schedule data from a list not working

python
dynamo

#1

Hi all,

I gratefully use the Python scripts from Thomas Mahon to read the data of my schedules.
But I can not read the list of schedules. It must be one by one.

I received an advice to us node List.Map, but I don’t no how.
Can someone help me please.

Link to python script:
python script Thomas Mahon

Regards,

Kangal


#2

Hi,

The two easiest way would be :

  • If you know how to code in Python, add a loop to the Python script in order to iterate through your list of schedules
  • If you don’t know how to code in Python, create a Dynamo custom node, containing only the Python Script (select your script, then right-click, create custom node). Then double-click on the new custom node, and replace what will be written in the input block of the custom node by “ScheduleView”.

One of the two solutions should do the trick :slight_smile:


#4

Hi Mellouze,

Thanks for your reply.
unfortunately I can not code in Python.
making a custom node is also not an option, because my company does not want to use a custom node.

Have you also a third option :sweat_smile:

Regards,

Kangal


#5

Well, if you cannot apply either options, you’ll pass a pretty rough time while using Dynamo.

Not even sure this works or is optimal, but it is the best I can do. You can also try contacting @Thomas_Mahon.

#Copyright 2016. All rights reserved. Bimorph Consultancy LTD, 5 St Johns Lane, London EC1M 4BH www.bimorph.co.uk
#Written by Thomas Mahon @Thomas__Mahon info@bimorph.co.uk

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
#
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

schedules = IN[0]
result = []

for i in range(len(schedules)):
	schedule = UnwrapElement(schedules[i])
	
	# "Start" the transaction
	TransactionManager.Instance.EnsureInTransaction(doc)
		
	#count the number of rows and columns in the schedule
	table = schedule.GetTableData().GetSectionData(SectionType.Body)
	nRows = table.NumberOfRows
	nColumns = table.NumberOfColumns
	
	#Collect all of data from the schedule
	dataListRow = []
	for row in range(nRows): #Iterate through the rows. The second row is always a blank space
		dataListColumn = []
		for column in range(nColumns): #Iterate through the columns
			dataListColumn.Add( TableView.GetCellText(schedule, SectionType.Body, row, column) )
		dataListRow.Add( dataListColumn );

	# "End" the transaction
	TransactionManager.Instance.TransactionTaskDone()
	result.append(dataListRow)

OUT = result

#6

You are the best Mellouze.
it works :muscle:

thank you very much!!!


#7

Glad I helped :slight_smile:


#8

Hi Mellouze,

I hate to ask but is it possible to use the script without flatten?
so I do not lose my list.

Regards,

Kangal


#9

This is the exact reason why you HAVE to use custom nodes at some point … This solution only work for THIS particular problem…

#Copyright 2016. All rights reserved. Bimorph Consultancy LTD, 5 St Johns Lane, London EC1M 4BH www.bimorph.co.uk
#Written by Thomas Mahon @Thomas__Mahon info@bimorph.co.uk

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
#
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

list_schedules = IN[0]
result = []

for schedules in list_schedules :
	mini_result = []
	for schedule in schedules :
		schedule = UnwrapElement(schedule)
	
		# "Start" the transaction
		TransactionManager.Instance.EnsureInTransaction(doc)
		
		#count the number of rows and columns in the schedule
		table = schedule.GetTableData().GetSectionData(SectionType.Body)
		nRows = table.NumberOfRows
		nColumns = table.NumberOfColumns
	
		#Collect all of data from the schedule
		dataListRow = []
		for row in range(nRows): #Iterate through the rows. The second row is always a blank space
			dataListColumn = []
			for column in range(nColumns): #Iterate through the columns
				dataListColumn.Add( TableView.GetCellText(schedule, SectionType.Body, row, column) )
			dataListRow.Add( dataListColumn );

		# "End" the transaction
		TransactionManager.Instance.TransactionTaskDone()
		mini_result.append(dataListRow)
	result.append(mini_result)

OUT = result

#10

Guess the original code with the list.map (or list.combine) using list levels would works as well :slight_smile: but agree, if you’re not allowed to use custom nodes or is able to modify the simplest parts of a python script you’re gonna have a hard time in the land of Dynamo…


#11

I don’t think that List.Map and List.Combine actually work with Python Script, as Python scripts cannot be passed as functions :slight_smile: I tried before with no success.


#12

I’m not at a computer but will give it a go tomorrow :slight_smile: might be a fun challenge :slight_smile:


#13

Thank you Mellouze,

I will also hammer in our office to use Custom Nodes :crossed_fingers:


#14

Good luck haha :stuck_out_tongue: Had a hard time ! (As you can see, the Python Scripts are compiled and not undestood by Dynamo as functions)

a = IN[0]

OUT = a+1


#15

hi Jonathan,

I also tried it, but unfortunately I did not succeed with List.Map.:sweat_smile:
Good luck tomorrow :muscle:


#16

Good luck was not enough :frowning: Couldn’t wait till tomorrow to try my ideas…
Custom nodes will be the way to go, and if it has to do with sharing the nodes internally you could create a “company-package” containing the custom nodes used in the company :slight_smile:

A side-note is that is was possible to pass functions, and I’m guessing using python nodes as functions back in Dynamo 0.6.3 but the functionality disappeared in the migration to 0.7.x…

There is a promise in there that it, as Arnold would say, be back… But so far no cigar.


#17

Hi Jonathan,

thanks for trying, too bad that it did not work out :disappointed_relieved:
I also think that we must go to a company-package. Thanks for your input.

Regards,

Kangal


#18

Just wanted to add a solution that does not care about how you list is structured, but will work on any depth like follows:

Credit to @kennyb6 as I’ve borrowed a little of his code from this post: Change list structure to match another list structure :wink:

Implementing that in @mellouze adaption of @Thomas_Mahon script it would look something like this, but it could probably be modified so that you keep your list structure in the output :wink:

#Copyright 2016. All rights reserved. Bimorph Consultancy LTD, 5 St Johns Lane, London EC1M 4BH www.bimorph.co.uk
#Written by Thomas Mahon @Thomas__Mahon info@bimorph.co.uk

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
#
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

result = []

x = []
def rec(_lists):
    for _list in _lists:
        if isinstance(_list,list):
            c = rec(_list)
        else:
            x.append(_list)
    return x
schedules = rec(IN[0])

for i in range(len(schedules)):
    schedule = UnwrapElement(schedules[i])

    # "Start" the transaction
    TransactionManager.Instance.EnsureInTransaction(doc)

    #count the number of rows and columns in the schedule
    table = schedule.GetTableData().GetSectionData(SectionType.Body)
    nRows = table.NumberOfRows
    nColumns = table.NumberOfColumns

    #Collect all of data from the schedule
    dataListRow = []
    for row in range(nRows): #Iterate through the rows. The second row is always a blank space
        dataListColumn = []
        for column in range(nColumns): #Iterate through the columns
            dataListColumn.Add( TableView.GetCellText(schedule, SectionType.Body, row, column) )
        dataListRow.Add( dataListColumn );

    # "End" the transaction
    TransactionManager.Instance.TransactionTaskDone()
    result.append(dataListRow)

OUT = result;

#19

Nice Jonathan!!
This will help me in the future.

Thank you!