Hi Everyone,
Thanks in advance for the help. I have no idea what I'm doing wrong and it's becoming very frustrating. First, a little background...
Program: Revit MEP 2015
IDE: VS 2013 Ultimate
I have created a Shared Parameter file and added the parameters in that file to the Project Parameters. These parameters have been applied to Conduit Runs, Conduit Fittings, and Conduits.
I'm using VB.NET to populate the parameters with no issue. After the code runs, I can see the expected text applied in the elements property window. Here is the code used to populate the values:
Populate:
Dim p as Parameter = Nothing
Dim VarName as String = "Parameter Name"
Dim VarVal as String = "Parameter Value"
p = elem.LookupParameter(VarName) <-- elem is passed in to the function as an Element
If p IsNot Nothing Then
p.Set(VarVal)
End if
Here's where I run into the error. When I attempt to retrieve the value, I am able to get the parameter by the parameter's definition name, but the value is always blank. Here is the code used to retrieve
Try
T = Split(sCommaDelimListOfCompTypes, ",")
For Each e As Element In ElemCollector.OfCategory(BuiltInCategory.OST_ConduitRun)
p = e.LookupParameter("Parameter Name")
If p IsNot Nothing Then
sVar1 = p.AsString()
MessageBox.Show(sVar1,"Title")
End If
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
The message box is always blank. Is there another way that I'm supposed to be going about this? Is there some sort of binding that I should be looking at when the value is set to begin with? Thanks in advance for everyone's help.
Regards,
Glen
Solved! Go to Solution.
Solved by RunninThruLife. Go to Solution.
A few things to check / try out:
1.
Is it possible that there is another parameter with the same name that exists in your project? Element.LookupParameter() only returns the first parameter it finds, it might be returning a comlpetely different parameter. Try Element.get_Parameter(Guid guid) using the Guid shown in the shared parameters file and see if that works.
2.
Check whether ElemCollector.OfCategory(BuiltInCategory.OST_ConduitRun) is actually finding the elements that you expect it too. I suggest adding the Element's Id value to the text shown in your message box to verify that the elements you see on your screen are the ones your code is working with.
3.
Is the code that reads the parameter values running immediately after the code that sets the parameter, or is it in a seperate command executed later? If it is running directly after, you may need to call Document.Regenerate() or even commit the transaction before you will be able to read the values back.
4.
Does changing sVar1 = p.AsString() to sVar1 = p.AsValueString() make a difference?
Scott,
Thanks for your thoughts on the issue.
1) The shared parameters that I have set up are very unique, there are no other parameters like it in the model.
2) The ElemCollector is finding the elements that I'm working with correctly. I've verified that it's iterating through the current drawing by changing the amount of elements in the drawing and then verifying with a counter placed in the loop. For instance, when I have 8 elements in the drawing, the counter shows eight, when there are 40, the counter displays 40. I am also able to see the unique ID of the elements.
3) The values are set and read in two different routines, at two different times. After they are set, the transaction is committed. They are read later on...
4) AsValueString doesn't change anything, I gave that a shot too.
... The plot thickens...
So, this gets a bit weirder. Instead of looping through every element in the drawing with the collector, I tried using a selection to choose only one and read the values back that way and it worked, I could see the value I expected! So what is missing between the collector and the reference. I'm at a total loss now. Here is the code that works with the Reference...
Dim uiDoc As UIDocument = app.ActiveUIDocument
Dim doc As Document = uiDoc.Document
Dim ElemCollector As New FilteredElementCollector(doc)
Dim pickedref As Reference = Nothing
Dim sel As Selection = app.ActiveUIDocument.Selection
pickedref = sel.PickObject(ObjectType.Element, "Choose Something")
Dim el As Element = doc.GetElement(pickedref)
For Each pp As Parameter In el.Parameters
sTemp = sTemp & "Name: " & pp.Definition.Name & vbCrLf & "Value: " & pp.AsString & vbCrLf & "Value As: " & pp.AsValueString & vbCrLf & vbCrLf
sTemp2 = sTemp2 & "Name: " & GetParamInfo(pp, doc)
Next
MessageBox.Show(sTemp)
What am I missing?!?!
Maybe the FilteredElementCollector isn't expanding the elements? Try converting the collector to a List<Element> and loop through that.
I'm using an ElementCategoryFilter(OfCategory(BuiltInCategory.OST_ConduitRun)) and applying it to the FilteredElementCollector (fec) like... fec.WherePasses(Filter). I have filtered down further using .WhereElementIsNotElementType, and its opposite for that matter. I've tried looping through and reading the parameters of the fec and through the fec.ToElements collection.
I've tried using Class Filter TypeOf(FamilyInstance) and TypeOf(ConduitRun), still to no avail.
Very strange.
It's difficult to see what might be the problem from your original code snippets as it looks like there's a bit of setup that hasn't been shown. Could you post the complete code of the Execute() method that isn't working? It will be easier for me (and others) to see what's happening if all the declarations and previous steps are shown. If the parameter reading section is just a small part of a larger command, go ahead and remove anything that you believe isn't related to the issue, but be sure to re-test the redacted code to ensure that it still behaves in the same way.
Before we get to that though, you haven't mentioned whether you have tested your code with other parameters or not. Have you tried using your original code to set / read one of the built in parameters? Try something like the "Mark" parameter and see what happens.
Sure thing, thanks for taking a look; here's the Execute Sub
Public Sub Execute(app As UIApplication) Implements IExternalEventHandler.Execute
Dim oGO As New clsGeneralOperations
Dim uiDoc As UIDocument = app.ActiveUIDocument
Dim doc As Document = uiDoc.Document
Dim condCategoryFilter As New ElementCategoryFilter(BuiltInCategory.OST_ConduitRun)
Dim fec As New FilteredElementCollector(doc)
fec.WhereElementIsNotElementType()
fec.WherePasses(condCategoryFilter)
Dim conds As ICollection(Of Element) = fec.ToElements
Dim myCond As ConduitRun = Nothing
Dim prompt As String = "A list of names and values for the element's parameters" & vbCrLf
Using trans2 As New Transaction(doc, "Test22")
trans2.Start()
Try
For Each e As Element In conds
myCond = TryCast(e, ConduitRun)
For Each p As Parameter In myCond.Parameters
If p.StorageType = StorageType.String then
prompt = prompt & "Name: " & p.Definition.Name & vbTab & "Value: " & p.AsString
End If
Next
MessageBox.Show(prompt)
Next
Catch ex As Exception
TaskDialog.Show("ERROR", ex.Message.ToString)
End Try
trans2.Commit()
End Using
End Sub
I have attached a picture of a conduit run segment selected with the value of one of the parameters sought after set. The Parameter name can be seen as '_TYPE' in the picture but the full name is 'COMP_TYPE'
Another picture has been attached showing the successful retrieval of the Revit COMMENT parameter.
Holy Bejeesus... I figured it out, but I'm not sure why the methods are that different from each other... if anyone had any insight, that'd be great.
I wanted to post the answer here, just in case anyone else is fighting with the same thing, so... you can see the method I was using to try to read the parameters above. In the method being used now there are only a couple of things that are different... 1) An element set... 2) An active view Id was added as a parameter to the FilteredElementCollector... 3) A FilteredElementIterator was implemented.
As far as I can tell it's the iterator that's making it different... can anyone explain what it's doing differently?
Below is the method that actually works...
Public Sub Execute(app As UIApplication) Implements IExternalEventHandler.Execute
Dim prompt As String = ""
Dim uiDoc As UIDocument = app.ActiveUIDocument
Dim doc As Document = uiDoc.Document
Dim ElemSet As ElementSet = app.Application.Create.NewElementSet
Dim fec As New FilteredElementCollector(doc, doc.ActiveView.Id)
Dim fec_filter As New ElementCategoryFilter(BuiltInCategory.OST_Conduit)
fec.WhereElementIsNotElementType()
fec.WherePasses(fec_filter1)
Dim fec_i As FilteredElementIterator = fec.GetElementIterator
Dim e As Element = Nothing
fec_i.Reset()
Using trans As New Transaction(doc, "Reading Conduit")
trans.Start()
While (fec_i.MoveNext)
e = TryCast(fec_i.Current, Element)
ElemSet.Insert(e)
End While
Try
For Each ee As Element In ElemSet
GetElementParameterInformation(doc, ee)
Next
Catch ex As Exception
TaskDialog.Show("ERROR", ex.Message.ToString)
End Try
trans.Commit()
End Using
End Sub
At any rate, thanks for any help that was offered. I'm sure it won't be the last time that I post here.
Regards,
Runnin