マクロ書き直した2つめ。ファイルは右のSkyDriveのSakura Editor Macroフォルダにありまそ。
Excelで範囲選択コピーしたものをサクラエディタに貼りつけると、
タブ区切りでガタガタになるので、イメージがつかめない。
ので、タブやカンマ区切りの表データを列幅を調節し罫線をつけて貼りつけるマクロ。
→ 
(function main(){
lines = {
maxWidth : [],
header : "",
data : [],
count : 0
};
var s = Editor.GetSelectedString(0)
|| new ActiveXObject('htmlfile').parentWindow.clipboardData.getData('text');
if(makeCells(s)) Editor.InsText(setEachLines());
})(); オブジェクトリテラルlinesは、
maxWidthは各列の最大幅、headerは1行目、dataは2行目以降、countは行番号。
範囲選択されていればそれ、されていなければクリップボードデータを取得して、
makeCells(s)以降の処理をしたら挿入。
Editorはサクラエディタから実行すると参照できるエディタオブジェクトで、マクロ関数が使える。
function makeCells(d){
var rowLines = d.replace(/\r\n/g,"\n").replace(/\r/g,"\n").replace(/\n/g,"\r\n").split("\r\n");
for(i in rowLines){
if(!rowLines[i]) continue;
if(!splitLine(rowLines[i])) return false;
lines.count++;
}
return true;
} サクラエディタは改行コードが混在するデータを扱えるので、
セル内改行の\nもひっくるめて\r\nに統一。
行毎に次の処理を呼び出し。
function splitLine(str){
var sep2ndLine = '"",""'; //csv format sepline
switch(lines.count){
case 0:
var sep = setColSep(str);
if(!sep) return false;
lines.header = str.split(sep);
compareCellLen(lines.header);
break;
case 1:
if(str == sep2ndLine) break;
default:
var sep = setColSep(str);
if(!sep) return false;
var d = str.split(sep);
compareCellLen(d);
lines.data[lines.count] = d;
}
return true;
} ヘッダ行、セパレータ行、それ以降の行でswitchして次の処理を呼び出しつつ格納。
function setColSep(str){
if(/\t/.test(str)) var colsep = " ";
if((/,/.test(str)) && (!colsep)) var colsep = ",";
if(!colsep) new ActiveXObject("WScript.Shell").popup("区切り文字判定できず");
else return colsep;
} 行毎にタブかカンマかの区切り文字を判定して返す。
function compareCellLen(arr){
if(! lines.count) for(var i=0 in arr) lines.maxWidth[i] = bLen(arr[i]);
else{
var ln = [];
for(var i=0 in arr){
ln[i] = bLen(arr[i]);
if(lines.maxWidth[i] < ln[i]) lines.maxWidth[i] = ln[i];
}
}
} 行毎に呼ばれるここで各セルの幅をmaxWidthと比較して大きければ格納。
function setEachLines(){
var hline ="", dlines ="", sline ="";
hline = attachWidth(lines.header).join("|") +"\r\n";
for(i in lines.data) dlines += attachWidth(lines.data[i]).join("|") + "\r\n";
sline +=setSeprateLine(lines.maxWidth).join("|") + "\r\n";
return(hline + sline + dlines);
} 次の処理で空白埋めした後にパイプ文字を挟んで結合。
function attachWidth(arrCol){
for(var i=0 in lines.maxWidth){
var colWth = bLen(arrCol[i]) || 0;
if(colWth >= lines.maxWidth[i]) continue;
var strBlank = "";
for(j=0; j < (lines.maxWidth[i]-colWth); j++) strBlank += " ";
if(!arrCol[i]) arrCol[i] ="";
arrCol[i] += strBlank;
}
return(arrCol);
} maxWidthになるまで半角空白で埋めて各列の幅をそろえる。
function setSeprateLine(arrColumn){
var arrDash = new Array();
for(i in arrColumn){
var strDash = "";
for(j=0; j < lines.maxWidth[i]; j++) strDash += "-";
arrDash[i] = strDash;
}
return(arrDash);
} セパレート行も幅に合わせて作成
function bLen(s){
if(!s) return;
var l = s.length, b = l;
function isWide(c){ return(0x80 <= c &&(c <= 0xff60 || 0xffa0 <= c)) }
for(i=0; i < l; i++) if(isWide(s.charCodeAt(i))) b++;
return(b);
} JScriptのlengthプロパティはUNICODE文字に対するものなので、byte長を返すため。
長い。処理するデータ量に比例してもっさりしていく。