home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2002 April
/
VPR0204A.ISO
/
OLS
/
LF-CSVPAD102
/
lf-csvpad102.lzh
/
LF-CSVPad.mac
next >
Wrap
Text File
|
2002-01-01
|
20KB
|
726 lines
// LF-CSVPad.mac,tab = 4
//=============================================================================
// Name : LF-CSVPad CSVファイル編集マクロ
// Version : 1.02
// Author : Yusuke Komori
// Date : 2001.10.27(Sat) Start
// : 2001.11.03(Sat) Version 1.00
// : 2001.12.24(Mon) Version 1.01
// ・先頭レコードへジャンプした際に、先頭レコードの次の行へジャン
// プしてしまう不具合を修正。
// ・CSVでないファイルで実行した際にエラーが発生してしまう不具合
// を修正。
// ・田楽DLLのロード方法を改良した。
// ・途中でフィールド数が増えた場合にダイアログを表示し直すように
// した。
// ・フィールドを追加した場合は空行ではなくCSVを出力するようにし
// た。
// : 2002.01.02(Wed) Version 1.02
// ・フィールド数が多い場合、横に並べて表示できるようにした。
//-----------------------------------------------------------------------------
// Copyright: Original code by Yusuke Komori.
// Copyright (c) 2001-2002. Yusuke Komori, All rights reserved.
//=============================================================================
$VERSION = "LF-CSVPad ver1.02";
$COPY_RIGHT = "Copyright (c) 2001-2002. Yusuke Komori, All rights reserved.";
//= カスタマイズ用の変数 =====================================================
#HEAD_FIELD_WIDTH = 20; // ヘッダフィールド幅(デフォルト値)
#INPUT_FIELD_WIDTH = 30; // 入力フィールド幅
#INPUT_FIELD_ROW = 20; // 入力フィールド1列あたりの数
#IGNORE_VOIDLINE = true; // trueの場合、空行を無視する
#IGNORE_COMMENT = true; // trueの場合、コメント行を無視する
// 各行のタブ、スペースを除いた先頭の1文字が$COMMENT_HEADERのどれか
// 一文字に一致した場合、コメント行と見なす
$COMMENT_HEADER = "#"; // コメントと見なす先頭文字列(複数指定化)
$SEPARATOR = ","; // セパレータ
//=============================================================================
#max_field = 0; // 最大フィールド数
#field_column = 1; // フィールドの横カラム数
#isOpen = false; // ダイアログを表示しているか?
call InitDengakuDLL; // 田楽DLLのロード
disablebreak;
// ヘッダの取得
#prev_x = x; // 現在のカーソル位置を保存
#prev_y = y;
gofiletop;
#orgCommentFlg = #IGNORE_COMMENT; // オリジナル設定を保存
#orgVoidFlg = #IGNORE_VOIDLINE;
#IGNORE_COMMENT = false; // ヘッダはコメントでも取得する
#IGNORE_VOIDLINE = true; // 先頭行が空行の場合は次の行をヘッダとする
call GetCSVDownward 0;
#IGNORE_COMMENT = #orgCommentFlg; // オリジナル設定を復帰
#IGNORE_VOIDLINE = #orgVoidFlg;
#max_field = #fieldcount;
#HEAD_FIELD_WIDTH = #maxfieldlen;
// 現在行の取得
moveto #prev_x,#prev_y; // カーソル位置を元に戻す
call GetCSVDownward 1; // 現在位置が空/コメント行の場合は次へ移動
//メイン処理
call MainProcess;
goto EndProcess;
//-----------------------------------------------------------------------------
// ■ メイン処理
//-----------------------------------------------------------------------------
MainProcess:
call ResizeDialog; // ダイアログの再表示
call DispData lineno, 1; // ダイアログへ現在行のデータを表示する
while (true)
{
$$name = "";
while ($$name == "")
{
$$name = dllfuncstr("WAITCTRLNOTIFY", 100);
}
// キャンセルされたときの処理
if ($$name == "0")
{
if (!dllfunc("ENDDIALOG")) goto EndProcess;
break;
}
// OKボタンを押されたときの処理
else if ($$name == "1")
{
call WriteData ##isChanged; // フィールドが変更されていたら書き出す
##isChanged = false;
// ダイアログを閉じる
if (!dllfunc("ENDDIALOG")) goto EndProcess;
break;
}
// 「前のレコード」ボタンが押されたときの処理
else if ($$name == "1000")
{
call WriteData ##isChanged; // フィールドが変更されていたら書き出す
##isChanged = false;
golinetop2; // 1行上へ移動
left;
call GetCSVUpward 1; // CSV取得
call ResizeDialog; // 必要ならばダイアログを再表示
call DispData lineno, 1; // ダイアログへ現在行のデータを表示する
}
// 「次のレコード」ボタンが押されたときの処理
else if ($$name == "1001")
{
call WriteData ##isChanged; // フィールドが変更されていたら書き出す
##isChanged = false;
golineend2; // 1行下へ移動
right;
call GetCSVDownward 1; // CSV取得
call ResizeDialog; // 必要ならばダイアログを再表示
call DispData lineno, 1; // ダイアログへ現在行のデータを表示する
}
// 「先頭のレコード」ボタンが押されたときの処理
else if ($$name == "1002")
{
call WriteData ##isChanged; // フィールドが変更されていたら書き出す
##isChanged = false;
// ヘッダの次の行を取得する。
gofiletop; // ファイルの先頭へ移動
// 空行以外のレコードを検索し、ヘッダと見なして読み捨てる
#orgCommentFlg = #IGNORE_COMMENT; // オリジナル設定を保存
#orgVoidFlg = #IGNORE_VOIDLINE;
#IGNORE_COMMENT = false; // ヘッダはコメントでも取得する
#IGNORE_VOIDLINE = true; // 空行は無視
call GetCSVDownward 1;
#IGNORE_COMMENT = #orgCommentFlg; // オリジナル設定を復帰
#IGNORE_VOIDLINE = #orgVoidFlg;
golineend2;
right;
call GetCSVDownward 1; // CSV取得
call DispData lineno, 1; // ダイアログへ現在行のデータを表示する
}
// 「最後のレコード」ボタンが押されたときの処理
else if ($$name == "1003")
{
call WriteData ##isChanged; // フィールドが変更されていたら書き出す
##isChanged = false;
gofileend; // ファイルの最後へ移動
call GetCSVUpward 1; // CSV取得
call ResizeDialog; // 必要ならばダイアログを再表示
call DispData lineno, 1; // ダイアログへ現在行のデータを表示する
}
// 「追加」ボタンが押された時の処理
else if ($$name == "1004")
{
// ファイルが書き込み禁止かチェック
call WarnReadOnly;
if (##return == false)
{
// フィールドが変更されていたら書き出す
call WriteData ##isChanged;
##isChanged = false;
if (##return == false)
{
golineend2;
insertreturn;
call ClearCSV 1,0; // 配列を消去
##isChanged = true;
call DispData lineno, 1; // 現在行のデータを表示する
}
}
}
// 「削除」ボタンが押された時の処理
else if ($$name == "1005")
{
// ファイルが書き込み禁止かチェック
call WarnReadOnly;
if (##return == false)
{
golinetop2; // 行を削除
deleteafter;
delete;
call GetCSVDownward 1; // CSV取得
call DispData lineno, 1; // 現在行のデータを表示する
}
}
// 「元に戻す」ボタンが押されたときの処理
else if ($$name == "1006")
{
if (##isChanged == true)
{
// フィールドが変更されている場合
call DispData lineno, 1; // フィールドを元に戻す
##isChanged = false;
}
}
// 「検索」ボタンが押された時の処理
else if ($$name == "1007")
{
find;
if (result)
{
// 検索結果が存在した場合
// フィールドが変更されていたら書き出す
call WriteData ##isChanged;
##isChanged = false;
call GetCSV 1; // CSV取得
call DispData lineno, 1; // 現在行のデータを表示する
}
else
{
if(!dllfunc("SHOWMESSAGE", "9999", "文字列が見つかりません")) goto ErrorProcess;
}
}
// フィールドが変更されたときの処理
else if ( ($$name == "10000") && (##isChanged == false) )
{
if(!dllfunc("SETCTRLSTRING", "changed", "変更")) goto ErrorProcess;
##isChanged = true;
}
}
return;
//-----------------------------------------------------------------------------
// ■ フィールド数が増加していればダイアログを再表示する
//-----------------------------------------------------------------------------
ResizeDialog:
// フィールド数が増えたか、ダイアログを開いていない場合に処理する
if ((#fieldcount > #max_field) || (#isOpen == false))
{
if (#fieldcount > #max_field)
{
#max_field = #fieldcount; // 最大フィールド数を更新する
}
// ダイアログを開いていれば一度閉じる
if (#isOpen)
{
if (!dllfunc("ENDDIALOG")) goto EndProcess;
}
// ダイアログの作成と表示
call CreateDialog;
if (!dllfunc("SHOWDIALOG", hidemaruhandle(0), 0)) goto ErrorProcess;
#isOpen = true;
}
return;
//-----------------------------------------------------------------------------
// ■ ダイアログの作成を行う
//-----------------------------------------------------------------------------
CreateDialog:
// ダイアログの横幅を計算する
#field_column = (#max_field / #INPUT_FIELD_ROW) + 1; // 列の数
##last_column = #max_field % #INPUT_FIELD_ROW; // 最終列の行数
if (##last_column == 0)
{
#field_column = #field_column - 1;
##last_column = #INPUT_FIELD_ROW;
}
##column_width = #HEAD_FIELD_WIDTH + #INPUT_FIELD_WIDTH; // フィールド幅
##dialog_width = (##column_width + 2) * #field_column - 1; // ダイアログ幅
// 通常列の行数
if (#field_column > 1)
{
##real_row = #INPUT_FIELD_ROW;
}
else
{
##real_row = #max_field;
}
// ダイアログの準備
if (!dllfunc("NEWDIALOG", $VERSION, ##dialog_width, "")) goto ErrorProcess;
// 行番号表示
if (dllfunc("NEWCONTROL", "text", "", "行番号") == 0 ||
dllfunc("SETCTRLWIDTH", "", #HEAD_FIELD_WIDTH) == 0 ||
dllfunc("NEWCONTROL", "text", "lineno", "") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##dialog_width - #HEAD_FIELD_WIDTH - 4) == 0 ||
dllfunc("NEWCONTROL", "text", "changed", "") == 0 ||
dllfunc("NEWCONTROL", "hline") == 0 )
{
goto ErrorProcess;
}
// フィールド表示
if(!dllfunc("NEWPAGE", ##column_width)) goto ErrorProcess;
##index = 0;
##j = 1;
while (##j <= #field_column)
{
// 現在の列の行数を計算
if (##j == #field_column)
{
// 最終列の場合
##column_num = ##last_column;
}
else
{
// それ以外の場合
##column_num = ##real_row;
}
// 1列分を表示
##i = 0;
while(##i < ##column_num)
{
if (dllfunc("NEWCONTROL", "text", "", $csv[0][##index]) == 0 ||
dllfunc("SETCTRLWIDTH", "", #HEAD_FIELD_WIDTH) == 0 ||
dllfunc("NEWCONTROL", "edit", str(##index), "") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "10000") == 0 )
{
goto ErrorProcess;
}
##index = ##index + 1;
##i = ##i + 1;
}
// 区切り線と新しい列を作成
if ((#field_column > 1) && (##j < #field_column))
{
if (dllfunc("NEWCOLUMN", 1) == 0 ||
dllfunc("NEWCONTROL", "vline") == 0 ||
dllfunc("SETCTRLHEIGHT", "", (#INPUT_FIELD_ROW * 27/20)) == 0 ||
dllfunc("NEWCOLUMN", ##column_width) == 0
)
{
goto ErrorProcess;
}
}
##j = ##j + 1;
}
##quotWidth = ##dialog_width / 4;
if (// 仕切線
dllfunc("NEWPAGE", ##dialog_width) == 0 ||
dllfunc("NEWCONTROL", "hline") == 0 ||
// 先頭/前/次/最後ボタン
dllfunc("NEWCONTROL", "button", "", "(&T) <<- 先頭") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1002") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##quotWidth) == 0 ||
dllfunc("NEWCONTROL", "button", "", "(&P) <- 前") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1000") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##quotWidth) == 0 ||
dllfunc("NEWCONTROL", "button", "", "(&N) 次 ->") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1001") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##quotWidth) == 0 ||
dllfunc("NEWCONTROL", "button", "", "(&B) 最後 ->>") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1003") == 0 ||
// 追加/削除/元に戻す/検索ボタン
dllfunc("NEWCONTROL", "button", "", "(&A) 追加") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1004") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##quotWidth) == 0 ||
dllfunc("NEWCONTROL", "button", "", "(&D) 削除") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1005") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##quotWidth) == 0 ||
dllfunc("NEWCONTROL", "button", "", "(&U) 元に戻す") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1006") == 0 ||
dllfunc("SETCTRLWIDTH", "", ##quotWidth) == 0 ||
dllfunc("NEWCONTROL", "button", "", "(&F) 検索") == 0 ||
dllfunc("SETCTRLNOTIFY", "", "1007") == 0 ||
// OK・キャンセルボタン
dllfunc("NEWPAGE", ##dialog_width) == 0 ||
dllfunc("NEWCONTROL", "okcancel") == 0 )
{
goto ErrorProcess;
}
return;
//-----------------------------------------------------------------------------
// ■ ダイアログへデータを表示する
//
// ●引数
// ##1 現在行
// ##2 表示したい$csvの要素番号
// $csv 表示したい要素を格納した配列
// #max_field 最大フィールド数
//-----------------------------------------------------------------------------
DispData:
// 行番号の表示
if (!dllfunc("SETCTRLSTRING", "lineno", str(##1))) goto ErrorProcess;
if (!dllfunc("SETCTRLSTRING", "changed", "")) goto ErrorProcess;
// 各フィールドの表示
##i = 0;
while(##i < #max_field)
{
$$idx = str(##i);
if (dllfunc("SETCTRLSTRING", $$idx, $csv[##2][##i]) == 0 )
{
goto ErrorProcess;
}
##i = ##i + 1;
}
// フィールド変更に伴う通知を読み捨てる
while (1)
{
$$name = dllfuncstr("WAITCTRLNOTIFY", 5);
if ($$name == "")
{
break;
}
}
return;
//-----------------------------------------------------------------------------
// ■ ダイアログからデータを取り込んでテキストへ書き出す
//
// ●引数
// ##1 true ならばテキストが変更されている。
// $$SEPARATOR セパレータ
// #max_field 最大フィールド数
//
// ●戻り値
// ##return 書き込み禁止で書き込めなかった場合、true
//-----------------------------------------------------------------------------
WriteData:
// テキストが変更されていなければ何も行わない
if (##1 == false)
{
return false;
}
// 書き込み禁止でないかチェックする
call WarnReadOnly;
if (##return == true)
{
return true;
}
// 各フィールドからテキストを読み込む
##i = 0;
while(##i < #max_field)
{
$$writeStr =
$$writeStr + dllfuncstr("GETCTRLSTRING", str(##i)) + $SEPARATOR;
##i = ##i + 1;
}
// 最後のセパレータを取り除く
$$writeStr = leftstr($$writeStr, strlen($$writeStr) - 1);
golinetop2; // 論理行頭へ移動
deleteafter; // カーソルより後ろを削除
insert $$writeStr; // 新しいデータを挿入
return;
//-----------------------------------------------------------------------------
// ■ 現在のファイルが書き込み禁止の場合、警告メッセージを表示
//
// ●戻り値
// ##return 書き込み禁止の場合、true
//-----------------------------------------------------------------------------
WarnReadOnly:
if (readonly == true)
{
if(!dllfunc("SHOWMESSAGE", "9999", "現在のファイルは書き込み禁止です.")) goto ErrorProcess;
return true;
}
return false;
//-----------------------------------------------------------------------------
// ■ カーソルのある行をセパレータで分割して配列に格納する
// 空行やコメント行の場合は1行上を格納する。
//
// ●引数
// ##1 結果を格納する要素番号
// ##2 1を指定した場合、先頭行に達したときに逆にたどらない。
//-----------------------------------------------------------------------------
GetCSVUpward:
while (1)
{
// 現在行のCSVを取得
call GetCSV ##1;
if ( ##return > 0 )
{
break;
}
else
{
// 空行やコメント行だった場合
golinetop2;
##prevline = lineno; // 現在の行番号を保存
left;
if (##prevline == lineno) // 先頭行に達した場合
{
if (##2 == 1)
{
// 下へたどらないで終了
break;
}
else
{
// 有効なレコードを下にたどって取得
call GetCSVDownward ##1, 1;
break;
}
}
}
}
return;
//-----------------------------------------------------------------------------
// ■ カーソルのある行をセパレータで分割して配列に格納する
// 空行やコメント行の場合は1行下を格納する。
//
// ●引数
// ##1 結果を格納する要素番号
// ##2 1を指定した場合、最終行に達したときに逆にたどらない。
//-----------------------------------------------------------------------------
GetCSVDownward:
while (1)
{
// 現在行のCSVを取得
call GetCSV ##1;
if (##return > 0)
{
break;
}
else
{
// 空行やコメント行だった場合
golineend2;
##prevline = lineno; // 現在の行番号を保存
right;
if (##prevline == lineno ) // 最終行に達した場合
{
if (##2 == 1)
{
// 上へたどらないで終了。
break;
}
else
{
// 有効なレコードを上にたどって取得
call GetCSVUpward ##1, 1;
break;
}
}
}
}
return;
//-----------------------------------------------------------------------------
// ■ カーソルのある行をセパレータで分割して配列に格納する
//
// ●引数
// ##1 結果を格納する要素番号
// $csv[##1] セパレータで分割した文字列
//
// ●戻り値
// コメント行だった場合は 0。空行の場合は-1。それ以外はフィールド数
// #fieldcount フィールド数
// #maxfieldlen 最も長いフィールドの文字数
//-----------------------------------------------------------------------------
GetCSV:
golineend2; // 論理行末へ移動して座標を取得
##x_end = x;
##y_end = y;
golinetop2; // 論理行頭へ移動して座標を取得
##x_start = x;
##y_start = y;
if (code == eof)
{
// 配列を消去しておく
call ClearCSV ##1, 0;
return 0;
}
$$line = gettext(##x_start, ##y_start, ##x_end, ##y_end);
$$trimline = dllfuncstr("LTRIM", $$line);
// コメント行であるか判断する
if (#IGNORE_COMMENT == true)
{
$$top = leftstr($$trimline, 1);
if (strstr($COMMENT_HEADER, $$top) > -1)
{
// 配列を消去しておく
call ClearCSV ##1, 0;
return 0;
}
}
// 空行であるか判断する
if ( (#IGNORE_VOIDLINE == true) && (strlen($$trimline) < 1) )
{
// 配列を消去しておく
call ClearCSV ##1, 0;
return -1;
}
// 文字列をセパレータで分割
#fieldcount = 0;
#maxfieldlen = 0;
$$token = dllfuncstr("GETTOKEN",$$line, $SEPARATOR);
while (1)
{
// フィールドのトリムを行う
$$token = dllfuncstr("LTRIM", $$token);
$$token = dllfuncstr("RTRIM", $$token);
$csv[##1][#fieldcount] = $$token;
// フィールド文字列の最大長を更新
##fieldlen = strlen($csv[##1][#fieldcount]);
if (##fieldlen > #maxfieldlen)
{
#maxfieldlen = ##fieldlen;
}
#fieldcount = #fieldcount + 1;
if (dllfunc("HASMORETOKENS") == 0)
{
// トークンがもう存在しなければ終了
break;
}
// 次のトークンを取り出す
$$token = dllfuncstr("GETTOKEN", "", $SEPARATOR);
}
// フィールド数が満たない場合は、前のゴミを消しておく
call ClearCSV ##1, #fieldcount;
return #fieldcount;
//-----------------------------------------------------------------------------
// ■ $CSV配列の消去を行う
//
// ●引数
// ##1 要素番号
// ##2 消去を始めるフィールド番号
//-----------------------------------------------------------------------------
ClearCSV:
// 配列を消去しておく
##i = ##2;
while (##i < #max_field)
{
$csv[##1][##i] = "";
##i = ##i + 1;
}
return;
//-----------------------------------------------------------------------------
// ■ 田楽DLLの利用準備
//-----------------------------------------------------------------------------
InitDengakuDLL:
if (1/2 == 0 && version < 309) {
message "このマクロには秀丸の Ver.3.09 以降が必要です。";
endmacro;
}
// 田楽DLLのパス
$$dllFileName = hidemarudir + "\\dengakudll.dll";
// 田楽DLLのロード(すでにロードされている場合はロードしない)
if (loaddllfile != $$dllFileName)
{
title "田楽DLL をロード中・・・";
loaddll($$dllFileName);
if (!result)
{
message "田楽DLL をロードできませんでした。";
endmacro;
}
title 0;
}
return;
//---------------------------------------------
// ■ マクロ終了処理ルーチン
//---------------------------------------------
ErrorProcess:
message "処理中にエラーが発生しました.";
freedll; // 念のため、DLLを破棄
EndProcess:
endmacro;
//======================================================== End of LF-CSVPad.mac