EXCELのデータをテキストに貼り付ける際に余計なダブルクォートを削除

休みの日に限って勤勉なbonlifeです。人力検索はてなの質問(http://www.hatena.ne.jp/1137168136)に適当な回答をしていたのですが、ちょっと見直してみました。セル内にAlt+Enterで入力できる改行がある場合、そのセルをコピーすると先頭行の最初と最終行の最後にダブルクォートが挿入されます。この改行を削除するための秀丸マクロを書いてみました。どういったケースで活用できるのかは、イマイチ不明ですが、EXCELで表示されている内容をそのまま秀丸に貼り付けることが出来ます。処理速度は…遅いです。表示の制御を行っていないせいもあるとは思いますが、なんとも遅いです。
http://d.hatena.ne.jp/junsub777/20060118
こちらでいくつかアイディアを出されている方がいらっしゃいますが、私のやり方は

  • 貼り付けた内容から、"を抜く
  • コピーした内容から、"を抜く

の間ぐらいでしょうか。全て貼り付けた後、処理を行う方が速いのかな、とも思ったのですが、その場合、どうやって貼り付けた範囲を覚えておいて、先頭行と最終行で処理を分けるのかが分からなかったんですよね…。仕方なく、クリップボードの内容を配列に1つずつ入れて、配列の値を取り出す際に適宜ダブルクォートを削除する実装にしてみました。もっとスマートなやり方があるかしら。

// クリップボード操作開始
beginclipboardread;

// 配列$a[]にクリップボードの内容を一行ずつ取り込み
#i=0;
$a[#i]=getclipboard;

while($a[#i]!=""){
	#i=#i+1;
	$a[#i]=getclipboard;
}

// 配列$a[]が空の場合、マクロを終了
if ($a[0]==""){
	endmacro;
}

// 配列$a[]の大きさが1の場合、そのまま貼り付け
if ($a[1]==""){
	insert $a[0];
} else {
// 配列$a[]の大きさが2以上の場合、以下の処理を実行
//   一行目の処理
//   (1) ダブルクォート2つを1つに戻す
//   (2) 行頭のダブルクォートを削除
	insert $a[0];
	up 1;
	selectline;
	replaceall "\"\"", "\"" , regular , inselect;
	selectline;
	replaceall "^\"", "" , regular , inselect;
	down 1;
//   二行目から最終行の前の行までの処理
//   (1) ダブルクォート2つを1つに戻す
	#j=1;
	while($a[#j+1]!=""){
		insert $a[#j];
		up 1;
		selectline;
		replaceall "\"\"", "\"" , regular , inselect;
		down 1;
		#j=#j+1;
	}
//   最終行の処理
//   (1) ダブルクォート2つを1つに戻す
//   (2) 行末のダブルクォートを削除
	insert $a[#j];
	up 1;
	selectline;
	replaceall "\"\"", "\"" , regular , inselect;
	selectline;
	replaceall "\"$", "" , regular , inselect;
	down 1;
}

秀丸マクロで変数を記憶するためのメモリは640KBなので、あまり大きなデータは扱えないので注意が必要です。また、クリップボード内に一行の長さが4KB以上のデータは4KBでデータが切られてしまうらしいです。秀丸マクロのヘルプには「ぶっちぎられてしまいます。」と書いてあります。すごい表現ですね…。
ちなみに、EXCELのセル内での改行を検索する場合、検索文字列を入力する部分でCtrl+Jと入力する、ということを知っているとどこかで役に立つかも。(ソースはこちらです。 : http://arena.nikkeibp.co.jp/tec/excel/20040308/107599/)
追記ですが、上記のマクロはセル1つのコピーにしか対応していません。使えないですね…。複数のセルに対応しながら、それぞれのセルが1行か複数行かを判定し、状況に応じてダブルクォートを削除するのは相当難しそうです。私の現在のスキルでは無理です。セル内にはダブルクォートが含まれない、という前提があれば相当簡単になります。

// クリップボード操作開始
beginclipboardread;

// 配列$a[]にクリップボードの内容を一行ずつ取り込み
#i=0;
$a[#i]=getclipboard;

while($a[#i]!=""){
	#i=#i+1;
	$a[#i]=getclipboard;
}

// 配列$a[]が空の場合、マクロを終了
if ($a[0]==""){
	endmacro;
} else {
// 配列$a[]が空でない場合、ダブルクォートを削除
	#j=0;
	while($a[#j]!=""){
		insert $a[#j];
		up 1;
		selectline;
		replaceall "\"+", "" , regular , inselect;
		down 1;
		#j=#j+1;
	}
}

こちらの方がはるかに現実的かもしれないですね。