FAQ
編集セッションと編集オペレーションの管理

ナレッジ番号:5324 | 登録日:2023/07/26 | 更新日:2024/11/21

概要

Editor はジオデータベースのシンクライアントです。Editor クラスに公開されている多くのメソッドは、ワークスペースで利用できるメソッドと密接に関わってマッピングされています。以下はメソッドの対応表です。

操作 IEditor IEngineEditor IWorkspaceEdit
編集セッションの開始 StartEditing StartEditing StartEditing
編集セッションの終了 StopEditing StopEditing StopEditing
編集オペレーションの開始 StartOperation StartOperation StartEditOperation
編集オペレーションの終了 StopOperation StopOperation StopEditOperation
編集オペレーションのキャンセル AbortOperation AbortOperation AbortEditOperation
編集オペレーションを元に戻す UndoOperation IOperationStack::Undo UndoEditOperation
編集オペレーションをやり直し RedoOperation IOperationStack::Redo RedoEditOperation
編集のコミット StopEditing(True) StopEditing(True) StopEditing(True)

ArcMap のエクステンションを書く場合、多くのケースで Editor のメソッドが内部的にジオデータベースのメソッドを呼ぶため、これらは Editor メソッドの代わりに利用されるべきではなく、交互に用いられるべきでもありません。Editor メソッドはしばしば追加のロジックも実行しますが、その中には適切なイベントの発行、選択状態の管理、属性ダイアログボックス等の Editor 関連のユーザー インターフェイス コンポーネントの管理等が含まれます。

編集セッションの開始

ArcMap の上では、常に Editor は編集可能なワークスペースを一つのみ許可します。これは編集ワークスペースあるいはカレント ワークスペースとして参照されます。この条件は現在のマップ ドキュメントのすべてのデータフレームにまたがって統制されています。編集セッションを開始する前に、マップ内の他のワークスペースがすでに編集可能な状態になっていないことを確認するようにします。以下のコード例を見てください。
public bool StartEditing(ESRI.ArcGIS.Geodatabase.IWorkspace workspaceToEdit)
{
    //editor への参照を取得する。
    UID uid = new UIDClass();
    uid.Value = "esriEditor.Editor";
    IEditor editor = m_application.FindExtensionByCLSID(uid)as IEditor;

    //ワークスペースがすでに編集中でないか調べる。
    if (editor.EditState == esriEditState.esriStateNotEditing)
    {
        editor.StartEditing(workspaceToEdit);
        return true;
    }
    else
    {
        return false;
    }
}
Public Function StartEditing(ByVal workspaceToEdit As ESRI.ArcGIS.Geodatabase.IWorkspace) As Boolean
    
    'editor への参照を取得する。
    Dim uid As UID
    uid = New UIDClass()
    uid.Value = "esriEditor.Editor"
    Dim editor As IEditor
    editor = CType(m_application.FindExtensionByCLSID(uid), IEditor)
    
    'ワークスペースがすでに編集中でないか調べる。
    If editor.EditState = esriEditState.esriStateNotEditing Then
        editor.StartEditing(workspaceToEdit)
        Return True
    Else
        Return False
    End If

End Function
 

編集の保存

編集セッションを管理する多くの Editor メソッドはジオデータベース メソッドと直接の相互関係があります。 これは編集の保存コマンドの例外を除き、Editor の UI からの操作にもあてはまります。 このケースでは Editor の編集の保存コマンドは IWorkspaceEdit.StopEditing(true) と IWorkspaceEdit.StartEditing (true) を内部的に呼びます。 ジオデータベースは Row オブジェクトへの参照が編集セッションのライフタイムの間で保ち続けられることを 保証します。ジオデータベースは Row  への参照が編集セッションの境界を越えて保ち続けられることは保証しません。 編集の保存コマンドが実行された時、厳密には Editor はひとつの編集セッションを停止して別の編集セッション を開始しているので、保持しているジオデータベース オブジェクトへのあらゆる参照は、新しい編集セッションの中で 再度取得する必要があります。詳しい情報は IWorkspaceEdit を参照してください。

編集オペレーションの操作

編集オペレーションの中で Row への編集を囲みます。そうすることで操作がオペレーション スタックに追加されるようになります。それは編集に対する Undo と Redo 機能を提供します。ある型のフィーチャは、更新が編集セッションの中でなされなくてはなりません。その中にはジオメトリック ネットワークやトポロジに参加しているフィーチャも含まれます。編集オペレーションのライフスパンの管理、Undo、Redo 機能を提供することに加えて、Editor はさらに編集関連のイベントに呼応する機会も提供します。コミットされる前に変更を見たり処理したりひとつの便利なイベントは IEditEvents2.BeforeStopOperation です。開発者にとっては、これはジオデータベースへの操作をコミットする前に編集オペレーションの内側で起こった変更の事前分析を行う機会を与えてくれます。IEditEvents2.OnStopOperation は、StopOperation が実行され、オペレーションがジオデータベースにコミットされたという通知を受けた時ですので、IEditEvents2.BeforeStopOperation はこれとは異なります。現在、編集オペレーションを破棄する機会はありません。 AbortOperation は、BeforeStopOperation も含めて、いかなる Editor イベントの内側でも呼ばないでください。 入れ子になった編集オペレーション ArcGIS は入れ子になった編集オペレーションをサポートしません。ArcGIS 9.1 やそれ以前では最初の操作の IEditor.StopOperation を呼ぶ前に 2 回目に IEditor.StartOperation を呼ぶと、システムは 2 回目の StartOperation の呼び出しを実行する前に、最初のオペレーションを閉じてしまいます。ArcGIS 9.2 からこの振る舞いは変更され、ユーザは新しい編集オペレーションを始まる前に現在の編集オペレーションを閉じることが求められます。そうしないと、例外がスローされます。以下のコード例をみてください。
 
private void EditOperationTest(IEditor m_editor)
{

    //編集オペレーションを開始する
    m_editor.StartOperation();

    //処理を行う部分
    // ...
    //End work.

    //1回目をクロースする前に2回目の編集オペレーションを開始する。例外がスローされる
    m_editor.StartOperation();
}
 Private Sub EditOperationTest(ByVal m_editor As IEditor)
    
    '編集オペレーションを開始する
    m_editor.StartOperation()
    
    '処理を行う部分
    ' ...
    'End work.
    
    '1回目をクロースする前に2回目の編集オペレーションを開始する。
    m_editor.StartOperation()
    
End Sub

この理由から、StartOperation と StopOperation の呼び出しの間に実行されるコードは最小限にし、コードの可読性を高め、入れ子になった 編集オペレーションを開始するようなことは極力減らします。 すでに編集オペレーション内にいるかどうかも調べることができます。以下のコード例は、編集オペレーションの状態であるかどうかを調べる方法です。

private void EditOperation(IEditor m_editor)
{
  //操作中であるかどうか調べる
  IWorkspaceEdit2 workspaceEdit = (IWorkspaceEdit2)m_editor.EditWorkspace;

  if (!workspaceEdit.IsInEditOperation)
  {
    // 最初のオペレーションを閉じる
    m_editor.StopOperation("edit");
  }
}
Private Sub EditOperation(ByVal m_editor As IEditor)
    
    '操作中であるかどうか調べる
    Dim workspaceEdit As IWorkspaceEdit2 = CType(m_editor.EditWorkspace, IWorkspaceEdit2)
    
    If (Not workspaceEdit.IsInEditOperation) Then
        ' 最初のオペレーションを閉じる
        m_editor.StopOperation("edit")
    End If
End Sub

ノンバージョンの編集セッション

ジオデータベースはバージョンとノンバージョンの編集セッションをサポートしています。Editor も両方の編集セッションタイプをサポ-ト しています。すべてのフィーチャクラスがノンバージョンの編集セッション内で編集できるわけではありません。ノンバージョン編集の制限についての詳しい情報は、「Geodatabase API を利用した編集」についてのジオデータベースのドキュメントを参照してください。ノンバージョンの編集セッションについては、ひとつの留意事項は、非 NULL 値やユニーク値の制限のある属性の扱いです。Editor はフィーチャを保存する前の属性の更新をサポートしていますので、そのフィーチャのフィールドに対して非 NULL またはユニーク値の制限に違反する属性の更新もできてしまいます。 この振る舞いは、IEditAttributeProperties インターフェイスを通じてすべての編集可能なフィーチャクラスあるいはまた特定のフィーチャクラスに適用されます。 以下のコード例はフィーチャを保存する前に入力フィーチャクラスの属性を更新すべきであることを明示しています。
private void AddClass(IEditor m_editor, IFeatureClass featureClass)
{
    IEditAttributeProperties editAttributeProps = (IEditAttributeProperties)m_editor;

    // コミット前に新しいフィーチャの属性クエリを可とする.
    editAttributeProps.NonversionedAttributionEnabled = true;

    // 特定のフィーチャクラスに限定する
    editAttributeProps.AttributeEditAll = false;

    // フィーチャクラスが指定されていなければ新しく追加する
    if (editAttributeProps.AttributeEditClasses == null)
    {
        editAttributeProps.AttributeEditClasses = new SetClass();
        editAttributeProps.AttributeEditClasses.Add(featureClass);
        return ;
    }

    // null でない場合、フィーチャクラスが存在するかの確認と追加
    if (editAttributeProps.AttributeEditClasses.Count == 0 ||
        !editAttributeProps.AttributeEditClasses.Find(featureClass))
    {
        editAttributeProps.AttributeEditClasses.Add(featureClass);
    }
}
Private Sub AddClass(ByVal m_editor As IEditor, ByVal featureClass As IFeatureClass)
    
    Dim editAttributeProps As IEditAttributeProperties = CType(m_editor, IEditAttributeProperties)
    
    ' コミット前に新しいフィーチャの属性クエリを可とする.
    editAttributeProps.NonversionedAttributionEnabled = True
    
    ' 特定のフィーチャクラスに限定する
    editAttributeProps.AttributeEditAll = False
    
    ' フィーチャクラスが指定されていなければ新しく追加する
    If editAttributeProps.AttributeEditClasses Is Nothing Then
        editAttributeProps.AttributeEditClasses = New SetClass()
        editAttributeProps.AttributeEditClasses.Add(featureClass)
        Return
    End If
    
    ' null でない場合、フィーチャクラスが存在するかの確認と追加
    If editAttributeProps.AttributeEditClasses.Count = 0 OrElse (Not editAttributeProps.AttributeEditClasses.Find(featureClass)) Then
        editAttributeProps.AttributeEditClasses.Add(featureClass)
    End If
    
End Sub

メタデータ

機能

種類

製品