重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

事で急に初めて秀丸を使用することになりました。
EXCEL VBAは多少使ったことがあるのですが、
秀丸マクロは置換=replaceallくらいしかまだ調べられていません。
下記のことをマクロで行いたいのですがコードを教えていただけますでしょうか。


やりたいこと:

①100列超×10000行超のCSVファイルのデータに対して、
 指定した列のみ全角スペース1個を半角スペース4個に変換したい
②指定列以外に全角スペースがあっても変換したくない
③指定列は必ずしも連続していない
④全角スペースの数は1項目に1個
 (全角スペース1個の項目と、↓の「家族人数」列のように
  スペースの前に数値がある項目も存在します)
⑤1行目は見出し行、2行目からが明細行
 (変換対象は2行目から最終行の特定の列です)
⑥変換対象のCSVファイルは複数存在しますがどれもレイアウトは同じですので
 変換したい列番号も同じです


例:

No.,名前,住所,子供有無,住居,家族人数,車有無,備考
001,はなこ,東京都 ,有,マンション,3人, ,
002,たろう,神奈川県,無,アパート ,0 ,有,
003,よしこ,埼玉県 ,有,戸建   ,4人,無,ペットは犬

変換したい列=「子供有無」「家族人数」「車有無」の3列のみ
(家族人数が「0 」と登録されることはあまりないと思いますが
あくまで例と思っていただければと思います。)

秀丸のバージョンは8.52です。

変換対象のCSVファイルは複数存在し、少しおいてまた作業があるので簡易化・ミス減のためマクロを作成したいです。個人的にはエクセルで実施したかったのですが秀丸で変換するよう指定され、対応することとなった次第です。

他力本願となってしまい本当に申し訳ございませんがお力をお貸しください。
長文すみませんでした。よろしくお願いいたします。

質問者からの補足コメント

  • 自分で以下のように記述して実行してみたのですがうまくいきませんでした。

    selectcolomn ○; ←全角1文字を半角2文字として数えたときのスペースの位置
    replacedown " "," ",regular,nocasesense,nohilight;

    すると、明細行一行目の子供有無と住居(に、実際のデータには全角スペースがあったのです。でも住居は置換したくない項目です。)のみ置換され、2行目以降・指定したつもりの2列目以降は置換できていませんでした。
    selectcolomnで全角スペースがある列にカーソルを合わせるイメージなのかなと思ってこのようにしたのですが、どういけなかったのでしょうか?

    図々しくて申し訳ありませんが、こちらもアドバイスいただけると幸いです。。

      補足日時:2015/07/01 03:48

A 回答 (4件)

こんなかんじで如何でしょうか?


4列目、6列目、7列目に対して置換を行っています。

setcompatiblemode 0x0F;
gofiletop;
replaceall "(?<=^([^,]+,){3}[^,]*)(?= +[^,]*,([^,]+,){3}) " , " " , regular, nocasesense, nohilight;
gofiletop;
replaceall "(?<=^([^,]+,){5}[^,]*)(?= +[^,]*,[^,]+,) " , " " , regular, nocasesense, nohilight;
gofiletop;
replaceall "(?<=^([^,]+,){6}[^,]*)(?= +[^,]*,) " , " " , regular, nocasesense, nohilight;
if( ! result ) beep;
    • good
    • 0
この回答へのお礼

siffon9様
コメントありがとうございます。いま実行環境がないので会社に行ってやってみます!実は投稿後に考えていたものと少し似ていて、でも私のは失敗だったのでこうするのかと思いました。補足に失敗した文を書かせていただいたので、もしお時間がありましたらご一読ください。
教えていただいたコードを実行して、またコメントさせていただきます。ありがとうございました。

お礼日時:2015/07/01 03:56

置換コマンドを使用せずに、2行目以降の行頭から1文字ずつ見ていくマクロを勉強がてら作成してみました。


ご参考にどうぞ。

setcompatiblemode 0x0F;
#target_col = 4; //対象カラム、最左カラムを0とする。
$target_char = " "; //置換対象文字(全角スペース)
$replace_char = " ";//置換後文字(半角スペース4個)

gofiletop;
down;
while(code != eof){
golinetop2;

// 対象カラムまでカーソル移動
if(#target_col != 0){
#i = 0;
while(#i != #target_col){
if(char(code) == ","){
#i = #i + 1;
}
right;
}
}


//対象カラムで文字置換
while(true){
if(code == 0x0D) break;
if(char(code) == ",") break;
if(char(code) == $target_char){
delete;
insert($replace_char);
left;
}
right;
}

//次行へ移動
golineend2;
right;
}
    • good
    • 0
この回答へのお礼

こちらのコードはこれから勉強します。。理解を待っているとなかなか締め切れなそうなので、一旦締め切らせていただき、じっくり読ませていただこうと思います!お忙しいなかここまでしていただき、ありがとうございました。

お礼日時:2015/07/03 13:55

> "(?<=~~~"の部分はどういうことを行っているのか、詳しく伺ってもよろしいでしょうか。




目的のカラムの全角スペースにマッチ(適合)するような正規表現を記述しています。
正規表現の詳細については、ここでは説明しきれませんのでお手数ですが入門サイト等をご参照ください。


前出のマクロの正規表現を簡単に解説します。
(以下、全角スペースを□で表します)

"(?<=正規表現1)(?=正規表現2)□" は、
置換対象の□の前に、正規表現1にマッチする文字列があり、
かつ、置換対象の□以降(対象の□も含む)が、正規表現2にマッチする。
という意味になります。



"(?<=^([^,]+,){3}[^,]*)(?= +[^,]*,([^,]+,){3}) "を例にとると

正規表現1は、"^([^,]+,){3}[^,]*"
正規表現2は、" +[^,]*,([^,]+,){3}" となります。

正規表現1は
行頭から"○○,"が3個あり、その後に","以外の文字が0個以上続くという意味です。
目的の□の前に"○○,"(すなわち","で終わる文字のかたまり)が3個ということで、4カラム目を指定しています。

正規表現2は
対象の□、","以外の文字が0個以上、","(4カラムの終了)、"○○,"が3個、の順で文字が並んでいるという意味になります。

この例では","が1行に7個、すなわち1行が8カラムで構成されていることが前提になっています。
実際に使用されるCSVのカラム数が異なる場合は、適宜修正する必要があります。

ちょっと難しいかもしれませんが、頑張って解読してみて下さい。
    • good
    • 0
この回答へのお礼

コメントが遅くなってしまい大変失礼いたしました。指定したい列の後ろも記述すると知って実行してみたのですが失敗して考えていました。いまはなんとか実行し、期待の結果が得られました!丁寧にご指導くださり本当にありがとうございました。

今回はカンマや空白で余計にわかりづらかったのかなと思いました。正規表現が特に理解の課題ですが、今後勉強していきたいと思います。この度は本当にありがとうございました。

お礼日時:2015/07/03 13:53

No.1です。


申し訳ありません、No.1のマクロだとヘッダ行の全角スペースも置換してしまいますね。
以下の様に修正をお願いします。
・各gofiletop; の下に down; を追加
・replaceall を replacedown に変更


補足いただいた件について
私も詳しいわけではないのですが、selectcolomnは文字の位置を指定するのではなくて、TSVまたはCSVモード表示時においてカラム番号を指定するような使用方法になります。ですから、選択できるのはカラム単位になると思います。
また、ちょっと試してみたのですがreplaceXXのコマンドで、選択範囲内のみでの置換操作ができないようですね。
    • good
    • 0
この回答へのお礼

明細行ばかり気にしていて見出し行の詳細を忘れていました。見出し行には基本的に全角も半角もスペースは入らない想定なので、検索開始は一行目からでも実質もんだいありません。でも、二行目からの検索開始方法がわかって勉強になりました。

教えていただいたコードを実行してみたのですが・・実際のデータに合わせた書き換えがうまくできていないようで、対象列全て変換とはいきませんでした。。すみません。。ご提示した例ではバッチリ成功だったのですが。。
"(?<=~~~"の部分はどういうことを行っているのか、詳しく伺ってもよろしいでしょうか。調べたところ検索条件が前方一致で・・まではわかりましたが「^」「,」「{}」で詰まってしまいました。
何から何までお世話になってしまい申し訳ありません。。

また、補足へのコメントありがとうございます。使い方が違ったのですね。。勉強不足でした。。

お礼日時:2015/07/01 16:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!