選択範囲の表示バイト数をステータスバーNo.38616
まっきょす さん 20/12/24 23:28
 
選択範囲の表示バイト数をステータスバーに表示できるようにしてほしいです。

ヘルプのステータスバーに次の様に記載されていることは承知しています。
>UTF-8,UTF-16,EUC,JISなどは、文字によってエンコードされるバイト数が変化する
>可能性があるため、ファイルに保存される正確なバイト数を計算することはできま
>せん。

しかし、UTF-8環境でプログラムしており、おおよそで構わないのでバイト数が分か
ると助かります。

『範囲選択の文字数』の計算方法で文字を2文字にするか1文字にするか指定できます
が、これは文字幅ではなくバイト数を意識させているのでしょうか?
(半角文字を0.5文字に設定できるのが、どういったニーズからなのか分かりません
が・・)

バイト数を意識しているのであれば、3文字も設定できる様にして頂ければ解決する
かとも思いましたが、
半角カナは3バイト、半角英字は1バイトなので、半角文字という項目をさらに細分
化してもらわないといけないな、と気づきました。

いっそのこと文字幅とバイト数で分けてみてはとも思います。

どのような形でも構いませんので、範囲選択に対してUTF-8のおおよそのバイト数が
ステータスバーに表示されること、が要望になります。

にわか知識で申し訳ありませんが、現在のUTF-8の仕様では最小のバイト数による表
現以外は不正らしいので(wikipediaで読みました)
バイト数を計算してみてもよいのではないでしょうか

少し前まで私はEUC環境でしたので、半角カナさえ使わなければ文字幅=バイト数で
したので特に問題ありませんでした。

勝手な要望かもしれませんが、ご検討頂けるとうれしいです

[ ]
RE:38616 選択範囲の表示バイト数をステーNo.38617
秀丸担当 さん 20/12/25 09:49
 

文字数計算で全角と半角を分けて計算できるのは、原稿用紙に収まるような想定だっ
たり、Shift-JISのバイト数だったりしますが、UTF-8の場合はバイト数にはならない
です。
UTF-8の場合は、文字コードの範囲によって、一文字が1バイトから4バイトくらいに
変化します。
半角カナだけでなく、正確に判断するためにはU+0080〜U+07FFが2バイト、U+0800〜U
+FFFFが3バイト、U+10000〜U+1FFFFFが4バイトになります。
さらに結合文字があると、いくらでも増えることになってしまいます。
正確にやるとしたら、実際に保存したほうが早いかもしれません。

全角を一律に3バイトとする概算でよければ、マクロで計算する方法も考えられます。
例えば[マクロ]→[マクロ登録]→[自動起動]のところでに、「カーソル移動後タイ
マー」で遅延時間300msくらいで以下のようなマクロを登録します。
ステータスバーはファンクションキー表示とは分離している状態で、左側の普段空欄
の場所に表示されます。

//カーソル移動後タイマーで300msとか
if(selecting){
  #cZenkaku=charcount(0x80202020);
  #cHankaku=charcount(0x80020202);
  $a=str(#cZenkaku*3+#cHankaku);
  title $a,1;
  title -1,1;
} else {
  title "",1;
  title -1,1;
}

マクロで正確にやるとしたら、一文字ずつ文字コードを拾って足し算するとできると
思いますが、たぶん遅くなると思います。
または、saveasでselection指定で実際に一時的に保存して、そのファイルサイズを
見ると比較的高速で正確にできると思いますが、ファイルを頻繁に書き換えるのであ
まり良くないかもしれません。

[ ]
RE:38617 選択範囲の表示バイト数をステーNo.38620
まっきょす さん 20/12/27 01:10
 
ご回答ありがとうございます
結合文字というのは初めて知りました、勉強になります

ASCII:1、全角:3、半角カナ:3くらいの簡単な文字だけをカウントしたいという要望
でした
utf-8のニーズは増えてくると思うのですが・・承知しました

マクロでのやり方説明ありがとうございます
マクロはやったことがないのですが、できそうなので今度やってみます

[ ]
RE:38620 選択範囲の表示バイト数をステーNo.38621
秀まるお2 さん 20/12/27 12:09
 
 マクロ作ってみました。

 範囲選択した文字列をUTF-8でファイルに保存して、そのファイルサイズを表示す
るだけですが。

    if( !selecting ) {
        message "範囲選択して実行してください。";
        endmacro;
    }
    $text = gettext(seltopx, seltopy, selendx, selendy, 1);
    if( $text == "" ) {
        endmacro;
    }
    $path = getenv("temp") + "\\utf8temp.$$$";
    #wnd = hidemaruhandle(0);
    openfile "/h";
    insert $text;
    saveas $path, utf8;
    #wnd2 = hidemaruhandle(0);
    setactivehidemaru #wnd;
    closehidemaruforced #wnd2;
    //ファイルサイズ取得
    #fso = createobject("Scripting.FileSystemObject");
    #file = callmethod_returnobj( #fso, "GetFile", $path );
    #size = getpropnum( #file, "Size");
    deletefile $path;
    releaseobject #file;
    releaseobject #fso;
    message "範囲選択部分のUTF-8でのサイズは、" + str(#size) + "バイトです。";

[ ]
RE:38621 選択範囲の表示バイト数をステーNo.38622
h-tom さん 20/12/27 16:41
 
h-tom です。

ADODB.Stream を使えば一時ファイルを作らなくてもすみますが、
改行コードの扱いが元のファイルと一致しないかもしれない。
Ver.8.94以降だと補正もできそうです。

//-------------------------- ここから
if( !selecting ) {
//      message "範囲選択して実行してください。";
        endmacro;
}
$select = gettext2(seltopcolumn, seltoplineno, selendcolumn, selendlineno, 1);
call ADOST_GetByteSize "UTF-8", $select;
#ret = ##return;
if(#ret > -1){
//    message "バイト数(UTF-8):"  + str(#ret);
    title str(#ret),1;
    title -1,1;
}else {
    title "",1;
    title -1,1;
}
endmacro;

/*

' 関数名    : ADOST_GetByteSize
' 返り値    : バイト数
' 引き数    : cset  : 入力文字データのキャラクタセット名
                      指定可能なのは、HKEY_CLASSES_ROOT\MIME\Database\Charse
t を参照
'           : InStr : 入力データ
' 機能説明  : 入力文字データを変換し、バイト数を取得する
' 備考      : https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/stream-object-ado?view=sql-server-ver15
*/
ADOST_GetByteSize:
    //ADODB.Streamで使う定数の代わりの変数
    ##TextStream            = 2;
    ##BinStream             = 1;
    ##adReadAll             = -1;
    ##SaveCreateNotExist    = 1;
    ##adSaveCreateOverWrite = 2;
   
    $$encodeStr  = $$1;
    $$SourceText = $$2;
   
    //テキストがない場合は0を返す。
    if(strlen($$SourceText) == 0) return 0;
    //エンコード指定がない場合はエラー
    if(strlen($$encodeStr) == 0) return -1;
   
    //各種変換入力用オブジェクト生成
    ##Stm_in  = createobject("ADODB.Stream");
    //失敗した場合はエラー
    if(##Stm_in == 0) return -1;
    //オープン
    callmethod ##Stm_in, "Open";
    //データタイプを設定
    setpropnum ##Stm_in, "Type", ##TextStream;
    //文字セットを指定
    setpropstr ##Stm_in, "Charset", $$encodeStr;
    //テキストを書き込み
    callmethod ##Stm_in, "WriteText", $$SourceText;
    //バイト数取得
    ##size = getpropnum(##Stm_in, "Size");
    //Charsetが"UTF-8"の場合、BOMが必ず追加される為、BOM分だけ補正する
    if(toupper($$encodeStr) == "UTF-8") ##size = ##size - 3;
    //オブジェクト解放
    releaseobject ##Stm_in;
    //テキストがあって、##sizeが0の場合は、COM関連でエラーが出ているのでエ
ラーを返す。
    if(##size == 0) return -1;
return ##size;
//-------------------------- ここまで

[ ]