一覧表のインポート・エクスポート機能が壊れてしまった

ファイル:一覧表のインポート,エクスポートが機能しなくなっている.仕掛りのバージョンでエクスポートしたCSVファイルをインポートしても新規ファイルの状態になるか,白紙のカードが横に並ぶだけで完全に壊れてしまっている.古いCSVファイルを開いても同じ状態だ.ドックに入っている間に「錆びついてしまった」という感じで,原因はまったく不明.2020/11/10の「再開発スタート版」では,2012/03/08に保存された「タモリさんちの超複雑な家系.CSV」を開くことができる.(警告パネルが出るがこれは動作とは無関係)このバージョンでは自分でエクスポートしたファイルをインポートすることもできる.

一覧表のインポート・エクスポートは主にVB側の担当なのでDLLはほとんど関係していない.VB側のコードは再開発スタート後もほとんどいじっていないはずであり,ましてインポート・エクスポート周りなどまったく触っていないはずなのだが… ⇒WinMergeでVBのソースファイルを比較してみたが,ざっと見た限りでは有意の差は見出せなかった.ともかく現行版をデバッグしてみることにしよう.現行版でエクスポートしたとき,一行目のフィールド名がすべて空になっている.この点をまず見ておこう.フィールド名は以下のコードで取り出されている.

RStr = RStr & .Columns(ColumnIndex).HeaderText()

.Columns(j).HeaderText()でフィールド名が取り出せない.⇒一覧表が表示されていないためだ.一覧表エクスポートのオプションでは「現在表示されている列だけをエクスポートする」という選択肢があるので,その場合には表示されなくてはならないかもしれないが,「すべての情報をエクスポートする」でエクスポートできないというのは不都合だ.アプリ起動時,MDIForm_Loadでは前回開いていたウィンドウを同じ位置にオープンしているが,その前に一覧画面とカード画面をロードしておくべきではないか?

いや,MDIForm_LoadでCardTable.InitTableを実行している.これで十分なはずだ.いや,InitTableは実行されているが設定が消えている.⇒設定が消えているのではない.アクセスが間違っている.コードではHeaderText()でフィールド名を取り出すようになっているが,実際に使われているのはNameというプロパティだ.古いバージョンを見てもそうなっているので,このコードは間違いではない.むしろVSで仕様変更しているのだろう.

HeaderText()をすべてNameに書き換えて,エクスポートの一行目は正しく出力されるようになったが,まだインポートはできない.しかし,古いバージョンではインポートできているので,仕掛り版のインポートが悪いということになる.ImportTableFuncでindices()の中身がすべて-1になっている.indices()には以下の式で値が与えられている.

indices(i) = CardTable.HeaderList.Items.IndexOf(value(i))

long __stdcall GetRecordでマクロIFEXPORTSACTIVEによってゼロ復帰していた.このマクロはすべての外部アクセス関数入口に設置されているもので,FAMILYTREE未構築ないしフェーズがINITIALSTATE以下のときはゼロ復帰するようになっている.このマクロを外して動作するようになった.早速藤壷の宮の重婚クラスタ図を開いてみよう.

image

 
※6

 

先帝,先帝の后宮,源氏宮

 

桐壷院,藤壷の宮

 

光源氏
 

 
冷泉院,弘徽殿女御,秋好中宮,王女御,左大臣の女御,中納言の娘,宰相の娘,冷泉院の御息所

実際には,この下に,弘徽殿女御→女一宮 (冷泉院の)と冷泉院の御息所→{女二宮 (冷泉院の),若宮 (冷泉院の)}が続いて,6世代図になるのだが,最下段のカードはいずれも独身で子どもがいないため,クラスタ図からは省かれている.薫のZ木家系図のクラスタ図を取ってみよう.原図はこんな感じだ.

image

クラスタ図を出してみよう.

image

一院の下のボックスにクラスタが2つ入っているというのはやや奇妙だが,これは摂政太政大臣の属するクラスタと桐壷院のクラスタのメンバー間には繋がりがないということを意味している.一院のクラスタからはそのどちらのクラスタにも親子関係で接続するため,一つの結婚枠の中にクラスタが2つという状態になっている.これはもちろんクラスタ循環と呼ばれるものではない.用語的に言うとこのクラスタ図は連結なので,「重婚クラスタ属」と呼ばれるものに該当する.

クラスタ図のもっとも大きな特徴は,メンバーカードがいずれか一つのクラスタにしか所属していないという点だ.これが系図木や婚姻木などとのもっとも大きな相違点であり,これによって各カードに「絶対世代番号」を与えることができる.さらに,XBTWがサポートされれば世代差のある結婚による多重を解消することができるので,多重カードゼロの系図,つまりパーフェクトな系図を実現することが可能となる.

クラスタ図をいつでも取り出せるようにしておくと便利だが,それにはメニューにコマンドを追加したりなど,いろいろと下準備が必要だ.いまのところは必要に応じてプログラムの中から直接実行するだけとしておこう.クラスタ図はZTで処理されるCSVファイルなので,多重枝の存在は邪魔になる.これを取り除いたデータを出力するようにしたい.

ゼルコバの木モジュール構成図 TEST2.ZELの標準家系図 基準ノード=#61 NLISTを軸線図法で開いて,TOPOLOGY::CallBuildShaftLineで停止した.軸線取得に失敗している.「ループフリーグラフで自己ループ枝の登録は不可」というエラーが出ているので,これが関係しているのではないか?FindJikusenAncestorでは,「基準ノードの自己ループ枝を登録する」としている.ただし,奇妙なことにこの枝は直ちに削除されている.もし,これが基準ノードをグラフの節点として登録することが目的の操作であるのなら,明示的に節点を追加した方がよい.

修正を入れてみたがエラーは解消しない.軸線グラフに自己ループを許す属性を与えてオリジナルのコードに戻しても同じ.出力を見ても確かに軸線は崩れている.

image

軸線グラフの節点はカード,枝は親子関係で,基準ノードの先祖ノードと末裔ノードを結ぶ最長経路を探索するために生成される.この検定は2つのパートに分解できる.①先祖ノード→基準ノードの最長経路を見つける,②基準ノード→末裔ノードの最長経路を見つける.おそらく先祖ノードは検定に入る前に決まっていると思われるが,どのカードが末裔ノードになるのかはこの時点では不明だ.

ここで使われている軸線グラフは比較的単純な非循環的有向グラフになると考えられるので,クラスタ検定でやったのと同じ手法でZTのCSVファイルとしてエクスポートできると思う.各段階ごとにそれをやれば,どこでしくじっているのか一目瞭然に分かるのではないだろうか?それほど難しくないのでやってみることにしよう.⇒できた!こんな単純なグラフで失敗するなど考えられないくらいシンプルなグラフだ.

image

基準ノードはcouplingで,先祖ノードもcoupling,末裔ノード候補は2つあるが,長幼の順に従えば,toplistだろう.ファイルをインポートするときエラーが3件発生している.いずれも「兄弟順位重複」でこれは「続柄」をすべて(1)としているのだから,当然だ.「名前を付けてZELファイルとして保存した後は正常に使用できます」ということでよい.FindJikusenAncestorの出口でグラフの状態を見てみよう.

image

余分なカードが2枚残っているが,これは余分な枝だけを削除してカードは放置されているためだろう.刈込めば余分なノードも一掃されると思われるが,とりあえず,これでも問題はないはずだ.それではどこで失敗しているのだろう.上掲した最終出力を見ると,軸線は4段目のNLIST→baselistで折れ曲がり,その上のtribelistから先祖ノードのcouplingまでの間には軸線ノード(イエロー)が存在しない.FindJikusenAncestorですでに末裔ノードから先祖ノードまでの直線経路が発見されているのに,なぜこんなことになってしまうのだろう?

一旦軸線上のノード(軸線ノード)が決定されれば,軸線を描画するのは難しくない.これらのすべてのノードが親子関係で繋がっているということは,先祖ノードを除けばそれらのノードを格納する結婚枠が存在するということであり,それらの結婚枠のgoodsonに軸線ノードを指定するだけで完全にストレートな軸線を描画することができる.goodsonというのは,結婚枠の吊り位置に当たるノードで,親の結婚点の直下に配置される.軸線枠はFindJikusenAncestorで決定されているのに,軸線ノードの決定を保留しているという理由が分からない.

FindJikusenAncestorは系統並び替えのステージ9の本検定(系列分解)でTribeDecompositionの中から実行されている.この段階ではノードの有効/無効はすでに決定しているから,FindJikusenAncestorでの決定は最終決定になり得ると思われるのだが… この処理をTribeDecompositionの冒頭で実行しているのは,系列分解に先立って軸線先祖を決定する必要があるためと考えられる.もし,留意点があるとすれば,軸線枠となるべき結婚枠は必ず軸線ノードの下で展開されなくてはならないということくらいだ.

この後,TribeRelocationに入り,BUILDCENTERLINEフェーズでCallBuildShaftLineが呼び出され,その中でBuildShaftLineが実行される.軸線ノードはここで最終決定される.BuildShaftLineでは軸線グラフを参照してはいるが,むしろ現物の系図木上の接続関係をトレースしている.BuildShaftLineの出口で軸線グラフがどうなっているのかを見ておこう.意図的にそうしているのかどうか?わからないが,壊滅状態だ.つまり,枝を完全に失っている.BuildShaftLineのステージ【2】の出口ではすでにtribelistから後ろの枝を失っている.ステージ【1】ではグラフを操作していないので,まだすべての枝が残っている.

image

なるほど,なんでこんなことをやっているのかという理由は分かる.つまり,軸線グラフのノードはCARDLINKであり,NAMEBOXではないからだ.CARDLINKは論理的な人名オブジェクト,NAMEBOXは画面上に描画される描画オブジェクトだ.CARDLINKとNAMEBOXは1対多の関係にあるから,具体的に展開された描画リスト上でどのNAMEBOXが軸線上に来るかは改めて決定される必要がある.

しかし,上述したように,①軸線ノードはFindJikusenAncestorの段階で決定できる,②軸線枠の軸線ノードの下で展開されなくてはならない,という2項が満たされれば,自動的に軸線が描画リスト上に構成されると考えて間違いないと思う.それを強制するのは難しくないはずだ.この2つが実現されれば,BuildShaftLineという処理はまるごと不要になると考えられる.⇒いや,そもそもCARDLINKはjikusenというプロパティを持っていない.eldestsonというフラグは持っている.「軸線図で長子相続者であるか否かを判定するためのフラグ」という説明が付いているのだが,使われているのだろうか?

長子相続図と軸線図は両立するだろうか?並立しないような気がするのだが,間違いだろうか?基準ノード→先祖ノードと基準ノード→末裔ノードというパスは親子関係で接続されているのだから,「長子」が入ってくる余地はないように思われる.「長子相続の場合はeldestsonを立てる→廃止 @20180818」というコメントが付いている箇所もあるが,実際には18箇所くらいで参照されている.多分このフラグは廃止できると思われるが,暫時放置して,別のフラグを立ててみることにしよう.

一応要件の①と②は実装したが,状況はまったく変化しない.おそらく,BuildShaftLineがすべてをぶち壊しているのではないかと思われるが,どうしたらいいだろう?現行のBuildShaftLineの論理をすべて捨てて,上記のセオリー通り「先祖ノードを除けばそれらのノードを格納する結婚枠が存在するということであり,それらの結婚枠のgoodsonに軸線ノードを指定するだけで完全にストレートな軸線を描画することができる」という指針に従って,軸線ノードを軸線枠のGoodSonに設定してみたが,事態は却って悪化してしまった.

これは思ったより手強いかもしれない.⇒ミスっていた.動きそうだ.要件がもう一つある.軸線枠はTYW婚にならないという点だ.抽出枠にするというのはどうか?それも問題だと思う.⇒対処した.

image

ここまで来ればもう一息だ.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA