Revit api import size lookup table to "Pipe Accessory" or "Plumbing Fixture" - revit-api

I am trying to import loookuptabledata.csv to different families using :
Document DstnctFamEdt = actvDoc.EditFamily(DstnctFam);
FamilySizeTableManager fstm = FamilySizeTableManager.GetFamilySizeTableManager(DstnctFamEdt,DstnctFamEdt.OwnerFamily.Id);
I am able to successfully do that to "Pipe Fitting" families. However when i apply the same code to a "Pipe Accessory" family or a "Plumbing Fixture" Family, i get this error:
lookupTableResult Exception: System.NullReferenceException: Object reference is not set to an instance object.
I have tried to import a lookuptable csv file "manually" into these types of families, and Revit (2022) does not complain about it.
Any pointers on how to import loookuptable csv file into "Pipe Accessory" Families and "Plumbing Fixture" Families?

Ok, So i Figured it out....
It seems that it has nothing to do with Family Type as in if it is a Fitting, Accessory or a fixture.
What it has to do with, is whether the family have a lookuptable manager to begin with. if you happened to have csv files in your family already, the above code will work fine.
However, if you do not have any csv in your family, then you have to CREATE and new lookuptable manager, then get it.
So i modified my code the following, and it now works for all families:
Document DstnctFamEdt = actvDoc.EditFamily(DstnctFam);
// Get FamilySizeTableManager (FSTM)
FamilySizeTableManager fstm = FamilySizeTableManager.GetFamilySizeTableManager(DstnctFamEdt,
DstnctFamEdt.OwnerFamily.Id);
// if FSTM is NUll then it does not exist=> Create one
if (fstm == null) {
bool fstmResult = FamilySizeTableManager.CreateFamilySizeTableManager(DstnctFamEdt, DstnctFamEdt.OwnerFamily.Id);
// Check that you actually created and FSTM, and Retrieve it.
if (fstmResult) {
fstm = FamilySizeTableManager.GetFamilySizeTableManager(DstnctFamEdt, DstnctFamEdt.OwnerFamily.Id);
}
}
// If FSTM Does Exit then Load csv File and Save Family and load into original DOC that family exists in.
if (fstm != null) {
// Import the csv file into Family... transaction needed
Transaction importTrans = new Transaction(DstnctFam.Document, "Importing csv File into Family ");
importTrans.Start("Start");
FamilySizeTableErrorInfo errorInfo = new FamilySizeTableErrorInfo();
FamilySizeTableErrorInfo ImportErrorInfo = new FamilySizeTableErrorInfo();
fstm.ImportSizeTable(DstnctFamEdt, csvFilePath, ImportErrorInfo);
// End transaction
importTrans.Commit();
// Load Family into Doc where it exists after adding csv file.
DstnctFamEdt.LoadFamily(actvDoc, new familyLoadOptions()); //update begins here
SaveAsOptions saveoptions = new SaveAsOptions();
saveoptions.OverwriteExistingFile = true;
// Save the Family if you want to, otherwise, make sure you save the Host doc.
DstnctFamEdt.SaveAs(DstnctFamPath, saveoptions);
// Cloes Family.
DstnctFamEdt.Close(false);
Ok, let me know if anyone can add to this.
thanks

Related

Why does DOORS show an error when creating a new Object in a Module via DXL?

I need to add occasionally Objects to a Module, depending on the needs via DXL for IBM DOORS. Only sometimes when trying to do this:
Object newObj
if (last(m) == null){
newObj = create(m)
} else {
newObj = create(last(m))
}
An error in line newObj = create(last(m)) appears saying that the "Creation of objects is not the current Module**. It is once again strange, as sometimes appears, and sometimes not...I guess depending on the Module "status", maybe previously has not been correctly closed and editing now is impossible...I do not know what to do...Some hints?
depends on what "sometimes" means. If m is not the current module, you can make it so with the statement
current = m

Revit Family Rename in a project

Is it possible to rename families in a project through the API. We are recently updating and standardizing our family naming convention. I'd like to build an add-in that would rename the families in existing project to the new standard names. I haven't had any success finding an example of this online.
I’ve successfully been able to find all the family names, however, I can’t rename the family.
I’m using the C#.
I tried the direct way with .Name property and seems to work.
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
foreach(ElementId id in uidoc.Selection.GetElementIds())
{
FamilyInstance famInstance = doc.GetElement(id) as FamilyInstance;
if (famInstance == null) continue; //skip element
famInstance.Symbol.Name = famInstance.Symbol.Name + " - Changed";
}
This is what I used
Element ff = doc2.GetElement({insert family id here});
var bar = (from x in familycollection where x.Name == ff.LookupParameter("Family Name").AsString() select x).FirstOrDefault();
exEvent.Raise()

Retrieving Properties from DbSqlQuery

Background: Project is a Data Import utility for importing data from tsv files into a EF5 DB through DbContext.
Problem: I need to do a lookup for ForeignKeys while doing the import. I have a way to do that but the retrieval if the ID is not functioning.
So I have a TSV file example will be
Code Name MyFKTableId
codevalue namevalue select * from MyFKTable where Code = 'SE'
So when I process the file and Find a '...Id' column I know I need to do a lookup to find the FK The '...' is always the entity type so this is super simple. The problem I have is that I don't have access to the properties of the results of foundEntity
string childEntity = column.Substring(0, column.Length - 2);
DbEntityEntry recordType = myContext.Entry(childEntity.GetEntityOfReflectedType());
DbSqlQuery foundEntity = myContext.Set(recordType.Entity.GetType()).SqlQuery(dr[column])
Any suggestion would be appreciated. I need to keep this generic so we can't use known type casting. The Id Property accessible from IBaseEntity so I can cast that, but all other entity types must be not be fixed
Note: The SQL in the MyFKTableId value is not a requirement. If there is a better option allowing to get away from SqlQuery() I would be open to suggestions.
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();

Entity Framework 4.1 & existing database

Hi I have an existing database with a table with 30 fields, I want to split the table into many models so I could retrieve/save fields that I need and not every time retrieve/save the whole object from the db. using c#.
I think I should be using Code-First. Could someone provide an example or a tutorial link?
thanks,
You don't need to split table to be able to load a subset of field or persist subset of fields. Both operations are available with the whole table mapped to single entity as well.
For selection you simply have to use projection:
var data = from x in context.HugeEntities
select new { x.Id, x.Name };
You can use either anonymous type in projection or any non-mapped class.
For updates you can simply use:
var data = new HugeEntity { Id = existingId, Name = newName };
context.HugeEntities.Attach(data);
var dataEntry = context.Entry(data);
dataEntry.Property(d => d.Name).IsModified = true; // Only this property will be updated
context.SaveChanges();
Or:
var data = new HugeEntity { Id = existingId };
context.HugeEntities.Attach(data);
data.Name = newName;
context.SaveChanges(); // Now EF detected change of Name property and updated it
Mapping multiple entities to single table must follows very strict rules and it is possible only with table splitting were all entities must be related with one-to-one relation (and there are some problems with more than two entities per split table in code first) or with table-per-hierarchy inheritance. I don't think that you want to use any of them for this case.

Dynamic data structures in C#

I have data in a database, and my code is accessing it using LINQ to Entities.
I am writing some software where I need to be able to create a dynamic script. Clients may write the scripts, but it is more likely that they will just modify them. The script will specify stuff like this,
Dataset data = GetDataset("table_name", "field = '1'");
if (data.Read())
{
string field = data["field"];
while (cway.Read())
{
// do some other stuff
}
}
So that script above is going to read data from the database table called 'table_name' in the database into a list of some kind based on the filter I have specified 'field='1''. It is going to be reading particular fields and performing normal comparisons and calculations.
The most important thing is that this has to be dynamic. I can specify any table in our database, any filter and I then must be able to access any field.
I am using a script engine that means the script I am writing has to be written in C#. Datasets are outdated and I would rather keep away from them.
Just to re-iterate I am not really wanting to keep with the above format, and I can define any method I want to behind the scenes for my C# script to call. The above could end up like this for instance,
var data = GetData("table_name", "field = '1'");
while (data.ReadNext())
{
var value = data.DynamicField;
}
Can I use reflection for instance, but perhaps that would be too slow? Any ideas?
If you want to read dynamically a DataReader context, it's a pretty easy step:
ArrayList al = new ArrayList();
SqlDataReader dataReader = myCommand.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
string[] fields = new string[datareader.FieldCount];
for (int i =0; i < datareader.FieldCount; ++i)
{
fields[i] = dataReader[i].ToString() ;
}
al.Add(fields);
}
}
This will return an array list composed by a dynamic object based on the number of field the reader has.

Resources