Проверка существования схемы расширяемого хранилища перед извлечением ее полей
Я использовал оператор if, чтобы проверить, является ли метод, извлекающий схему, нулевым, это в отдельной форме, которая содержит checkListBox для заполнения. Код ниже, и я отметил условное, что проверяет это. Мой вопрос Каков наиболее эффективный способ обеспечения того, чтобы каждый раз, когда надстройка revit запускалась в новом файле.rvt, запись схемы уже существовала до попытки получения схемы? Когда дела идут плохо, возникает ошибка нулевой ссылки при попытке доступа к пустой схеме.
//CheckedListBox for filter01 this exists in the form and calls the main
class function to retrieve the record.
checkedListBox1.DataSource = WS.categoryList(rvtDoc, intSwitch = 1);
Filter01_CategoryList = new List<BuiltInCategory>();
**if (WS.retSchemaBICMethod(rvtDoc) != null)**
{
TaskDialog.Show("Schema 1 ", " exists");
Filter01_CategoryList = WS.retSchemaBICMethod(rvtDoc);
}
else
{
TaskDialog.Show("Schema 1 "," has not been created");
//Update stored schema field values
inputBIC = checkedListBox1.CheckedItems.Cast<BuiltInCategory>
().ToList<BuiltInCategory>();
WS.getSetBIC(rvtDoc, inputBIC);
WS.storeSchema(rvtDoc, WS.projectInfoElement, inputBIC,
out WS.retrieveBIC);
//set checkedlistbox 1
Filter01_CategoryList = WS.retSchemaBICMethod(rvtDoc);
}
//this code returns the retrieved schema from the main class
public List<BuiltInCategory>retSchemaBICMethod(Document doc)
{
Element piElement = projectInfoFilter(doc);
// Read back the data from ProjInfo
Entity retrievedEntity = piElement.GetEntity(Schema.Lookup(schemaGuid));
IList<int> retrievedData = retrievedEntity.Get<IList<int>>
(Schema.Lookup(schemaGuid).GetField("BuiltInCatIds"));
//cast int list back to built-in category list
retSchemaBIC = retrievedData.Cast<BuiltInCategory>
().ToList<BuiltInCategory>();
return retSchemaBIC;
}
2 ответа
Чтобы проверить, существует схема или нет, я использую следующие где name
это имя вашей схемы. Если вы используете != null
это выдаст ошибку во время выполнения.
Schema s = Schema.ListSchemas().FirstOrDefault(q => q.SchemaName == name);
if (s == null)
{
// no schema found, create one
}
else
{
// schema found, use it
}
GUID, скорее всего, будет отличаться для каждого проекта Revit.
Неясно, как вы предоставляете guid для вашего retSchemaBICMethod, поэтому может показаться, что это, скорее всего, причина вашей проблемы.
Я бы взял Schema.Lookup из вызова GetEntity и сначала проверил, что у вас есть допустимое значение, потому что я подозреваю, что именно там происходит ваша нулевая ссылка.
Я также считаю, что есть проблемы с тем, как Revit обрабатывает несколько документов и расширяемое хранилище. У меня был ряд проблем, когда открывался второй документ, и я представил отчет об ошибке в Revit по этой проблеме.
Чтобы получить данные поля, вы должны проверить, существует ли расширяемая схема хранения. Для этого вы должны сначала понять всю структуру.
Хранилище данных -> GUID схемы -> Схема -> Сущность -> Поле
Сначала вы должны проверить, существует ли хранилище данных. Вы можете проверить через FilteredElementCollector.
FilteredElementCollector collector = new FilteredElementCollector(doc);
var dataStorage = collector.OfClass(typeof(DataStorage)).FirstElement();
if (dataStorage == null)
{
TaskDialog.Show("No data storage found");
return null;
}
Каждая схема имеет уникальный GUID. Получить GUID для каждой схемы, хранящейся в проекте.
IList<Guid> SchemaGuids = dataStorage.GetEntitySchemaGuids();
Теперь вы можете получить схему методом Schema.Lookup(guid). После получения схемы вы можете легко получить сущности, хранящиеся в схеме, и их значения.
foreach (Guid guid in SchemaGuids)
{
Schema schema = Schema.Lookup(guid);
Entity entity = dataStorage.GetEntity(schema);
tokenValue = entity.Get<string>("Token");
}