Проверка существования схемы расширяемого хранилища перед извлечением ее полей

Я использовал оператор 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");
        }
Другие вопросы по тегам