初めてのミニバン、スライドドア。

背が高い。
1.5L Dieselエンジン、WLTCモード18.1km/lでタンク容量60Lなので、満タンで900km走れる、計算になる。ゲットしたのはMAXIというモデル。ロングの7人乗りで、4770x1850x1825、ホイールベースは2975。長い、けど駐車場には無事入れました。
サーフボードが何枚でも積めて、2−3人乗って長距離いける、ようなスペックだ。
プログラムを記述して、コンパイルエラーがなければ実行する。しかし思ったような結果にならないことはよくある。そんなときに有効なデバッグテクニックを紹介する。
実行中のコードにログファイルに文字列を出力するコマンドを挿入しておいて、実行時に注目している変数がどのような値になっているかを調べる。アラートダイアログの方法と違ってプログラムが止まらないという長所がある。
次のコードをスクリプトパレットに登録し、図形を選択してから実行する。
procedure debug_test;
var
h: handle;
myType: integer;
gAryLog: DYNARRAY [] OF STRING; { Jiro_LogAdd }
gCntOfAryLog: LONGINT; { Jiro_LogAdd }
(* -------------------------------
関数:Jiro_LogAdd
機能:ログ出力バッファに1行メッセージを追加する
------------------------------ *)
PROCEDURE Jiro_LogAdd( msg: STRING );
BEGIN
gCntOfAryLog:= gCntOfAryLog +1;
ALLOCATE gAryLog[ 1.. gCntOfAryLog];
gAryLog[gCntOfAryLog]:=msg;
END;
(* -------------------------------
関数: Jiro_Logout
機能: ログ出力: メッセージをテキストファイルに書き出す
------------------------------ *)
procedure Jiro_Logout;
CONST
kFileName='/Users/wat/Desktop/my_log.txt'; { デスクトップのファイル名 }
var
i: LONGINT;
begin
ReWrite( kFileName ); {保存ダイアログなし}
FOR i:=1 TO gCntOfAryLog DO BEGIN
WriteLn( gAryLog[i] );
END;
Close(kFileName);
end;
begin
h:=FSActLayer;
while h<>NIL do begin
myType:=GetTypeN( h );
Jiro_LogAdd( concat( 'debug_test: type=', Num2StrF(myType)));
h:=NextSObj(h);
end; {while}
{ ログ出力 }
Jiro_LogAdd( concat( Date(2,1), 'END of PGM' ) );
Jiro_Logout;
end;
RUN ( debug_test );
グローバルな配列変数gAryLogに出力するログをためていって、プログラムの最後でファイルに出力する、というコードだ。
2つの図形を選択して実行する。

実行すると、デスクトップに「my_log.txt」というテキストファイルが作成される。ファイルの中身は次のとおり。

コーディングは少し面倒ではあるが、うまく使えばプログラムの動きがよくわかる。
プログラムを記述して、コンパイルエラーがなければ実行する。しかし思ったような結果にならないことはよくある。そんなときに有効なデバッグテクニックを紹介する。
実行中のコードにアラートダイアログを表示するコマンドを挿入しておいて、実行時に注目している変数がどのような値になっているかを調べる。
次のコードをスクリプトパレットに登録し、図形を選択してから実行する。
procedure debug_test;
var
h: handle;
myType: integer;
begin
h:=FSActLayer;
myType:=GetTypeN( h );
alrtDialog( concat( 'debug_test: type=', Num2StrF(myType)));
end;
RUN ( debug_test );
文字列図形を選択して実行してみた結果は次の図

アラートダイアログによって変数の中身をみるためには、次のようなコマンドを知っていると便利。
アラートダイアログによるデバッグはコード挿入が簡単だが、プログラムがいちいち止まってしまうという欠点がある。ループの中で使うと[OK]ボタンをクリックして繰り返しダイアログを閉じていかなくてはならない。抜けるにはoption+command+escキーでVectorWroksを強制終了する。
続いて、デバッグ2(debug2)ログファイルへの出力を紹介する。
Vectorworksではシンボルは図面ファイルに登録する。シンボルを使えば作図作業が楽になり、図面の標準化も進む。シンボルはシンボルフォルダを使って分類することができる。フォルダの階層が深くなると全体でどのくらいのシンボルが登録されているか把握しにくくなる。
次のコマンドを実行して、現在の図面ファイルにどれだけのシンボルが登録されているか調べてみよう。実行手順は次の通り。
1.リソースマネージャを開く
2.新規リソースをクリック
3.スクリプト(P)を選んで[作成]をクリック
4.パレット名入力ダイアログでパレット名を入力
「パレット-1」でかまいません。
5.スクリプト名入力ダイアログでスクリプト名を入力
「スクリプト-1」でかまいません。
6.開いたエディタに上記のプログラムをペースト
7.歯車アイコンをクリックしてコンパイル
8.リソースマネージャで「スクリプト-1」をダブルクリック
ソースコードは次。
(* -------------------------------
関数: SP_NumOfSym
Version: 1.0.0
機能: 図面ファイルに登録されているすべての定義シンボルを数える
20241129 wat
------------------------------- *)
PROCEDURE SP_NumOfSym;
var
gLoopy: longint;
gMsg: string;
(* -------------------------------
関数: SP_SearchInSymFolder
機能: シンボルフォルダ内のシンボルを取得(再帰コール)
------------------------------ *)
procedure SP_SearchInSymFolder( symFolderH: handle; folderName: string );
var
symDefH: handle; {SymDef handle}
objType: longint;
currentFolderName: string;
begin
symDefH := FInFolder( symFolderH );
WHILE ( symDefH <> NIL ) DO BEGIN
objType := GetTypeN( symDefH );
if ( objType = 16 ) then begin
gLoopy := gLoopy + 1;
end else begin
if ( objType = 92 ) then begin
{ フォルダの場合はフォルダ内をサーチ(再帰) }
currentFolderName := GetName( symDefH );
currentFolderName := concat( folderName, '/', currentFolderName );
SP_SearchInSymFolder( symDefH, currentFolderName );
end;
end;
symDefH:= NextSymDef( symDefH );
END; {WHILE (objH<>NIL)}
end; { SP_SearchInSymFolder }
(* -------------------------------
関数: SP_arySymInfo_make
機能: シンボルを取得
------------------------------ *)
procedure SP_arySymInfo_make;
var
symDefH: HANDLE; {SymDef }
objType: longint;
currentFolderName: string;
begin
gLoopy := 0;
{ シンボル定義をハンドル移動して、シンボル定義情報を得る }
symDefH:= FSymDef;
WHILE ( symDefH <> NIL ) DO BEGIN
objType := GetTypeN( symDefH );
if ( objType = 16 ) then begin
gLoopy := gLoopy + 1;
end else begin
if ( objType = 92 ) then begin
{ フォルダの場合はフォルダ内をサーチ }
currentFolderName := GetName( symDefH );
SP_SearchInSymFolder( symDefH, currentFolderName );
end;
end;
symDefH:= NextSymDef( symDefH );
END; {WHILE (symDefH<>NIL)}
end; { SP_arySymInfo_make }
BEGIN {===== MAIN =====}
{ シンボル定義を取得 }
SP_arySymInfo_make;
if ( gLoopy >= 1 ) then begin { シンボル定義が一つ以上ある }
gMsg:= 'シンボルの数:';
gMsg:= concat( gMsg, Num2StrF( gLoopy ) );
gMsg:= concat( gMsg, chr(13) );
AlrtDialog( gMsg );
end else begin
gMsg:= 'この図面にはシンボルが登録されていません';
AlrtDialog( gMsg );
end; { if ( gLoopy >= 1 ) }
END;
RUN( SP_NumOfSym );
コンパイルエラーが表示されたり、実行時にエラーが出るような場合は、うまくコピペできていない可能性がある。そのような場合は次からソースコードをテキストファイルでダウンロードしてみてほしい。
シンボル図形を表示するツールは別売り。
Vectorworks 2024に限ったことではなく、VW2023でもそれ以前でも発生していたと思う。たまにハマるのでメモしておく。
文法エラーがあると、エラーの行の下の行番号と内容が表示される、という事例。
たとえば次のコード。

スクリプトをコンパイルすると、エラーになって次のようなメッセージが表示される。文字列を期待している、という指摘だ。で、何処の?となる。

349行目がエラー、と表示されているように見えるけど、varの宣言文を見ると、GFはrealで、GRがstringとなっていた。348行目を次のように修正。
GR:=gEDIT_11;

これでコンパイルは成功。

コンパイルエラーになったら、1行前のコードも疑おう。もちろん正しい宣言文があるか、セミコロンが記述されていないかとか、関数の始まりも要チェック。