「検索ヒット数表示(選択文字列)」の版間の差分

Sukemaru (トーク | 投稿記録)
「何件目」の表示を追加。関数バージョンを追加
Sukemaru (トーク | 投稿記録)
機能強化バージョン「文字数・行数・ヒット件数(選択文字列)」を追加
10行目: 10行目:


<span style="color:#c00;">※ このマクロと Mery 標準の検索メソッドとでは、ヒット数のカウントの仕方が異なります。 </span>
<span style="color:#c00;">※ このマクロと Mery 標準の検索メソッドとでは、ヒット数のカウントの仕方が異なります。 </span>
:''e.g.''「あ<span style="background:#bfdfff;">ああ</span>ああ」5文字だけの文書で「<span style="background:#bfdfff;">ああ</span>」を検索した場合、このマクロでは "2件" とカウントしますが、Mery の検索メソッド(次/前を検索)では "4回" ヒットします。
:''e.g.''「あ<span style="background:#bfdfff;">ああ</span>ああ」5文字だけの文書で「<span style="background:#bfdfff;">ああ</span>」を検索した場合、このマクロでは "2件" とカウントしますが、Mery の検索メソッド(次/前を検索)では "4回" ヒットします。<br> また、「あい<span style="background:#bfdfff;">あいあ</span>」5文字だけの文書で「<span style="background:#bfdfff;">あいあ</span>」を検索した場合は、このマクロでは "1件" とカウントします(Mery の検索メソッドでは "2回" ヒット)。
:→ 「何件目」かの表示は、うえの例のような範囲選択をしている場合には不正確な値を返します。
:→ 「何件目」かの表示は、上の例のような範囲選択をしている場合には不正確な値を返します。




※ このマクロの実行にあたって include ライブラリは不要です。
※ このマクロの実行にあたって include ライブラリは不要です。


※ このマクロでは、イベントマクロで利用する場合の処理速度を優先させるために「[[検索ヒット数表示]](JScript)」 マクロのような正規表現検索には対応させていません。また、文字列のヒット判定では「大文字と小文字を区別する」が適用され、「単語のみを検索する」は適用されません。
※ このマクロでは、イベントマクロで利用する場合の処理速度を優先させるために「[[検索ヒット数表示]] (JScript)」 マクロのような正規表現検索には対応させていません。また、文字列のヒット判定では「大文字と小文字を区別する」が適用され、「単語のみを検索する」は適用されません。


※ イベントマクロで利用する場合は「遅延時間」を適宜調整しないと、大きな文書の編集のさいに動作がもたつくことがあります。
※ イベントマクロで利用する場合は「'''遅延時間'''」を適宜調整しないと、大きな文書の編集のさいに動作がもたつくことがあります。


オプション指定をつけてヒット数を調べたい場合は、「[[ポップアップメニューで検索先にジャンプ|ポップアップメニューで検索先にジャンプ]] 」マクロの '''include''' 版をご利用ください(イベントマクロにはできませんが)。
オプション指定をつけてヒット数を調べたい場合は、「[[ポップアップメニューで検索先にジャンプ|ポップアップメニューで検索先にジャンプ]] 」マクロの '''include''' 版をご利用ください(イベントマクロにはできませんが)。
99行目: 99行目:
=== 使用例 ===
=== 使用例 ===
<source lang="javascript">
<source lang="javascript">
// 例1. ステータスバーの表示内容に追加
// 例. ステータスバーの表示内容に追加
if ( document.selection.Text ) {
if ( document.selection.Text ) {
   Status += "  " + HitStatus( document.selection.Text );
   Status += "  " + HitStatus( document.selection.Text );
}
// 例2. 入力ダイアログで指定した文字列のヒット数
var word = Prompt( "検索文字列:", "" );
if ( word ) {
  Alert( "「 " + word + " 」 \n" + HitStatus( word ) );
}
}
</source>
</source>
141行目: 135行目:
           + " ( " + SeparateNum( hit ) + " 件目 ) ";
           + " ( " + SeparateNum( hit ) + " 件目 ) ";
   }
   }
}
</source>
== 機能強化バージョン ==
2019/08/26 追加
[[#単独マクロバージョン|単独マクロバージョン]] に以下の機能を追加しています。
* 選択範囲の文字数と行数を表示
* 保存済みの文書で「すべて選択」しているときにファイルサイズを表示
* 設定項目から表示方法や検索方法などを変更可
<br>
※ ロースペックの PC でイベントマクロ(選択範囲が変更されたとき/遅延 0秒)として使用しても、1万行・30万文字程度の文書では編集作業のジャマにはならないようでした。<br>
6万行・800万文字の文書では "もたつき" が生じましたが…。
=== ソースコード ===
<source lang="javascript">
#title = "文字数・行数・ヒット件数(選択文字列)"
#tooltip = "文字数・行数・検索ヒット数表示(選択範囲の文字列)"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",19
/**
* --------------------------------------------------------------------
* 文字数・行数・ヒット数
* sukemaru ( 2019/08/26 )
* --------------------------------------------------------------------
* 編集中の文書または選択範囲の文字数と行数をステータスバーに表示します。
* 選択範囲があるときは、選択範囲の文字列の出現回数を表示します。
*
* 選択範囲のある状態でマクロを手動で実行するか、
* イベント「選択範囲が変更されたとき」に設定して自動で実行させる想定。
*
* ▼ 制限事項 ▼
*
* ※ 矩形選択範囲では正しく機能しません。
*
* ※ 「行数のカウント方法」の設定項目 Logical と ignoreEnter で
*    無効(false)を「Mery 方式」としているのは、
*    ステータスバーの中央右寄りに表示される "選択範囲の行数" の数え方に
*    合せるための表現です。
*    ignoreEnter を有効(true)にしても、
*    文字数のカウントには選択範囲末尾の改行記号を含めます。
*
* ※ 文字数のカウントでは、改行コードの
*    CR+LF と CR と LF の区別なしに1文字として扱います。
*
* ※ 「あああああ」5文字だけの文書で「ああ」を検索した場合、
*    このマクロでは "2件" とカウントします。
*    また、「あ あ あ」5文字だけの文書で「あ あ」を検索した場合は、
*    このマクロでは "1件" とカウントします。
*
* ※ 設定項目の bytesEnable が有効(true)で「すべて選択」状態のときのみ、
*    実体ファイルのファイルサイズを表示できます。
*    ただし、「無題」や「未保存状態*」のタブでは表示しません。
*/
// ---------- ▼ 設定項目 ▼ ----------
// ■ 行数のカウント方法
// true:論理行(改行) / false:物理行(折り返し ← Mery 方式)
var logical = false;
// ■ 選択範囲の末尾が改行記号のときの行数のカウント方法
// true:次の行頭を含めない / false:含める( ← Mery 方式)
var ignoreEnter = false;
// ■ ヒット数のカウント方法
// true:大文字と小文字を区別しない / false:区別する
var ignoreCaseEnable = true;
// ■ ファイルサイズの表示
// true:表示する / false:表示しない
var bytesEnable = true;
// ■ マクロの処理の所要時間の表示
// true:表示する / false:表示しない
var timerEnable = false;
// ---------- ▲ 設定項目 ▲ ----------
var timerStart = new Date();
var d = editor.ActiveDocument;
var s = d.selection;
var isEmpty = s.IsEmpty; // 「範囲選択なし」のフラグ
var selAll = false; // 「すべて選択」のフラグ
var posMode = logical ? mePosLogical : mePosView;
var lineMode = logical ? 0 : meGetLineView;
var dLines = d.GetLines( lineMode );
var sLines;
var dt = d.Text;
var st;
var statusStr;
// 範囲選択なしなら文書全体の文字列と行数
if ( isEmpty ) {
  st = dt;
}
// 範囲選択ありなら選択範囲の文字列と行数
else {
  st = s.Text;
  selAll = ( st == dt );
  sLines = s.GetBottomPointY( posMode )
        - s.GetTopPointY( posMode )
        + ( ( ignoreEnter && /[\r\n]$/.test( st ) ) ? 0 : 1 );
}
var sLen = st.length;
// 範囲選択なしのときは、文書全体の文字数・行数を、
// 範囲選択ありのときは、選択範囲の文字数・行数をステータスバーに表示
var charStr = " " + sLen + " 文字";
var lineStr = " ( " + ( isEmpty ? dLines : sLines ) + " 行 )";
statusStr = charStr + lineStr;
// すべて選択のときはファイルサイズを取得する
var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
var fileSize = ( bytesEnable && selAll && d.FullName && d.Saved )
                ? Fso.GetFile( d.FullName ).Size
                : "";
var fileSizeStr = " ( ファイルサイズ: " + fileSize + " バイト )";
// ファイルサイズ、または選択範囲の文字列のヒット数をステータスバーに追加
statusStr += ( isEmpty || selAll )
              ? ( fileSize ? fileSizeStr : "" )
              : HitStatus( st, dt, ignoreCaseEnable );
statusStr += timerEnable ? TimerElapsed( new Date(), timerStart ) : "";
Status = SeparateNum( statusStr );
// --------------------------------------------------------------------
/**
* 関数 SeparateNum( str )
* 文字列中の数字を3ケタ区切りに
*/
function SeparateNum( str ) {
  return str.replace( /(\d)(?=(?:\d{3})+[^\d])/g, "$1," );
}
/**
* 関数 TimerElapsed( end, start )
* マクロの処理の所要時間を計測
*/
function TimerElapsed( end, start ) {
  var elapsedSec = ( ( end - start ) / 1000 ).toFixed( 3 );
  return " [ " + elapsedSec.replace( /\./, ". " ) + " 秒 ]";
}
/**
* 関数 HitStatus( strSelection, strDocuText, ignoreCase )
* 選択文字列の出現回数を返す
*/
function HitStatus( word, docu, i ) {
  word = i ? word.toLowerCase() : word;
  var len = word.length;
  var docu = i ? docu.toLowerCase() : docu;
  var tPos = Math.min( s.GetActivePos(), s.GetAnchorPos() );
  var pos = 0,  count = 0,  hit = 0;
  while ( pos >= 0 ) {
    pos = docu.indexOf( word, pos );
    if ( pos >= 0 ) {
      count ++;
      if ( pos <= tPos  ) {
        hit = count;
      }
      pos += len;
    }
  }
  return "  /  ヒット数:" + count + " 件"
        + " ( " + hit + " 件目 ) ";
}
}
</source>
</source>
スポンサーリンク