エラー ポスト機能を使用して問題をレポートするには、次の手順が必要です。
強度、重大度、基本説明、解決策、既定の解像度などのエラーに関するいくつかの永続的情報を含む FailureDefinition オブジェクトを作成して、Revit の考えられる各エラーを Revit アプリケーションの起動中に定義、登録する必要があります。
次の例では、高すぎる壁に使用することができる 2 つの新しいエラー、警告、エラーを作成します。この例では、これらは(この章の次のコードで)エラーのポストを行うアップデータと合わせて使用されます。FailureDefini tionIds はエラーのポストに必要なため、Updater クラスに保存されます。次のセクションでは、FailureDefinition.CreateFailureDefinition()メソッドのパラメータについて詳しく説明します。
コード領域 26-1: エラーを登録、定義 |
WallWarnUpdater wallUpdater = new WallWarnUpdater(); UpdaterRegistry.RegisterUpdater(wallUpdater); ElementClassFilter filter = new ElementClassFilter(typeof(Wall)); UpdaterRegistry.AddTrigger(wallUpdater.GetUpdaterId(), filter, Element.GetChangeTypeGeometry()); // define a new failure id for a warning about walls FailureDefinitionId warnId = new FailureDefinitionId(new Guid("FB4F5AF3-42BB-4371-B559-FB1648D5B4D1")); // register the new warning using FailureDefinition FailureDefinition failDef = FailureDefinition.CreateFailureDefinition(warnId, FailureSeverity.Warning, "Wall is too big (>100'). Performance problems may result."); FailureDefinitionId failId = new FailureDefinitionId(new Guid("691E5825-93DC-4f5c-9290-8072A4B631BC")); FailureDefinition failDefError = FailureDefinition.CreateFailureDefinition(failId, FailureSeverity.Error, "Wall is WAY too big (>200'). Performance problems may result."); // save ids for later reference wallUpdater.WarnId = warnId; wallUpdater.FailureId = failId; |
一意の FailureDefinitionId は、FailureDefinition を登録するためのキーとして使用する必要があります。 一意である各 FailureDefinitionId は、GUID 生成ツールを使用して作成する必要があります。後で、FailureDefinitionId を使用して、FailureDefinitionRegistry の FailureDefinition をルックアップし、FailureMessages を作成、ポストすることができます。
新しいエラーを登録する場合、FailureDefinitionId およびユーザに表示できるエラーの説明文とともに、重大度が指定されます。 重大度は、ドキュメントでどのアクションが許可されているか、トランザクションがすべてコミットされるかどうかを判断します。重大度のオプションは次のとおりです。
4 番目の重大度の None は、新しい FailureDefinition を定義するときに指定することはできません。
エラーを解決する場合、使用可能なすべての解決策は、FailureDefinition クラスで定義済みである必要があります。これは、Revit に指定のエラーに使用できると考えられるエラーの解決策を通知します。FailureDefinition には、解決策のユーザ表示キャプションなど、エラーに適用できる解決策の完全なリストが含まれています。
解決策の数は制限されていませんが、2011 年現在、Revit API では、公開されているエラーの解決策は DeleteElements のみです。 複数の解決策を指定する場合は、SetDefaultResolutionType()メソッドを使用して明示的に変更しない限り、最初に追加した解決策が既定の解決策になります。 Revit のエラー処理機能によって既定の解決策が使用され、適用可能な場合はエラーを自動的に解決します。Revit UI は既定の解決策のみを使用しますが、Revit アドインは、Revit API を介して、適用可能な任意の解決策を使用したり、(この章の処理エラーのセクションで記載のとおり)それを実行するもう 1 つの UI を提供することができます。
DocumentCorruption の重大度でエラーが発生した場合は、エラーが解決されるまでにトランザクションは既に中止されているため、解決することはありません。したがって、FailureResolutions を 重大度が DocumentCorruption の API で定義されたエラーに追加することはできません。
Document.PostFailure()メソッドを使用して、問題のドキュメントを通知します。エラーは検証され、トランザクションの終了時に解決される場合もあります。ポストこのメソッドから投稿された警告は、解決された後にドキュメントに保存されません。エラーのポストを使用して、トランザクションが終了する前に変更する可能性のあるドキュメントの状態に対処するため、またはトランザクションの終了まで解決策を保留するのが妥当な場合に使用されます。外部コマンドによって発生したすべてのエラーがエラーをポストするわけではありません。エラーがドキュメントに無関係の場合は、タスク ダイアログを使用する必要があります。Revit UI が外部コマンドを実行しない無効な状態である場合などです。
エラーをポストするには、カスタム エラーが定義された場合に FailureDefinitionId を使用して新しい FailureMessage を作成する、または Revit API によって提供される BuiltInFailure を使用します。失敗した要素などの FailureMessage オブジェクトの追加情報を設定し、新しい FailureMessage を通過する Document.PostFailure()を呼び出します。ドキュメントはエラーをポストするために変更可能である必要があります。
PostFailure()によって返される一意の FailureMessageKey()はトランザクションの寿命の間格納でき、エラーメッセージに関連性がなくなった場合にこれを削除するために使用できます。同じ FailureMessage が 2 回以上表示される場合は、同じ FailureMessageKey が返されます。ポスト済みのエラーに DocumentCorruption の重大度がある場合、無効な FailureMessageKey が返されます。これは DocumentCorruption エラーのポスト取り消しができないためです。
次の例では、Execute()メソッドで受信された情報に基づいた新しいエラーをポストする(上記の「エラーを定義、登録する」コード領域で参照される) IUpdate クラスを示します。
コード領域 26-2: エラーをポスト |
public class WallWarnUpdater : IUpdater { static AddInId m_appId; UpdaterId m_updaterId; FailureDefinitionId m_failureId = null; FailureDefinitionId m_warnId = null; // constructor takes the AddInId for the add-in associated with this updater public WallWarnUpdater(AddInId id) { m_appId = id; m_updaterId = new UpdaterId(m_appId, new Guid("69797663-7BCB-44f9-B756-E4189FE0DED8")); } public void Execute(UpdaterData data) { Document doc = data.GetDocument(); Autodesk.Revit.ApplicationServices.Application app = doc.Application; foreach (ElementId id in data.GetModifiedElementIds()) { Wall wall = doc.GetElement(id) as Wall; Autodesk.Revit.DB.Parameter p = wall.LookupParameter("Unconnected Height"); if (p != null) { if (p.AsDouble() > 200) { FailureMessage failMessage = new FailureMessage(FailureId); failMessage.SetFailingElement(id); doc.PostFailure(failMessage); } else if (p.AsDouble() > 100) { FailureMessage failMessage = new FailureMessage(WarnId); failMessage.SetFailingElement(id); doc.PostFailure(failMessage); } } } } public FailureDefinitionId FailureId { get { return m_failureId; } set { m_failureId = value; } } public FailureDefinitionId WarnId { get { return m_warnId; } set { m_warnId = value; } } public string GetAdditionalInformation() { return "Give warning and error if wall is too tall"; } public ChangePriority GetChangePriority() { return ChangePriority.FloorsRoofsStructuralWalls; } public UpdaterId GetUpdaterId() { return m_updaterId; } public string GetUpdaterName() { return "Wall Height Check"; } } |
ドキュメントに対して複数の変更が行われ、同じトランザクション内で複数の再生成が行われた可能性があるため、いくつかのエラーで関連性がなくなる場合や、「誤った警告」を防ぐために削除する必要がある場合があります。特定のメッセージは Document.UnpostFailure()メソッドを呼び出してポストを取り消すことができ、PostFailure() が呼び出されたときに取得した FailureMessageKey を通過できます。UnpostFailure() は、エラーの重大度が DocumentCorruption の場合に例外をスローします。
Transaction.SetFailureHandlingOptions()メソッドを使用することで、トランザクションがロールバックされているときに、すべてのポスト済みエラーを自動的に削除することもできます(これによりユーザは[キャンセル]を押さなくて済むようになります)。