2012/02/20

JavaScript (WSH) でExcelファイル読み込み

Excelのテーブル定義書を元に、Java Beansの元となるテキストを作成するJavaScriptを書きました。
14行目からのCELL objectの定義を少し修正すれば、汎用的に使えると思います。

行が結合されてたりすると、途端に破綻してしまいますが...。

/*
 * Excelファイル読み込み
 * テーブル定義書から必要な情報を取得し、classの元データを生成する
 */

/** Excelファイル */
var XLS_FILES = [
 "3.1. テーブル定義\\テーブル定義書_1.xls",
    :
 "3.1. テーブル定義\\テーブル定義書_N.xls"
];

/** Cell位置定義 */
var CELL = {};
/** テーブル名 (物理名) */
CELL.TABLE_NAME_ROW = 8;
CELL.TABLE_NAME_COL = 1;
/** テーブル名 (正式名) */
CELL.TABLE_DESC_ROW = 8;
CELL.TABLE_DESC_COL = 12;

/** フィールド情報 開始位置定義 */
CELL.START_ROW = 10;
CELL.FIELD_NAME_COL = 4;  //フィールド名
CELL.FIELD_TYPE_COL = 12; //種類
CELL.FIELD_DESC_COL = 18; //概要

/** テーブル定義 シート名 */
var SHEET_NAME = 'フィールド';

var fso = new ActiveXObject('Scripting.FileSystemObject');


/**
 * Excelファイルを開く
 */
function readExcel(xlsFile){
 //ファイル存在チェック
 if( ! fso.FileExists(xlsFile) ){
  return;
 }
 
 var xls = null;
 var book = null;
 var fields = [];
 
 try{
  //Excel起動
  xls = new ActiveXObject('Excel.Application');
  //Excelファイル open
  book = xls.Workbooks.Open(xlsFile);
  //シート指定
  var sheet = book.WorkSheets(SHEET_NAME);

  // sheet.Cells(row, col);
  var tableName = sheet.Cells(CELL.TABLE_NAME_ROW, CELL.TABLE_NAME_COL).Value;
  var tableDesc = sheet.Cells(CELL.TABLE_DESC_ROW, CELL.TABLE_DESC_COL).Value;
  /*
   table = {
   name:
   description: 
   }
   */
  fields = [{ 'name':tableName, 'description':tableDesc }]; //1要素目はtable名
  /*
  field = {
   name:
   type:
   length:
   description:
  }
  */

  var reg = /\([0-9]+\)/;
  var row = CELL.START_ROW;
  while(1){
   var c = sheet.Cells(row, CELL.FIELD_NAME_COL).Value;
   if( c == null || c.length == 0){
    //フィールド名定義がない→ループ終了
    break;
   }
   //フィールド名
   var name = c;
   //種別
   var type = sheet.Cells(row, CELL.FIELD_TYPE_COL).Value;
   //長さ
   var length = 0;
   if( reg.test(type) ){
    var m = type.match(reg).join('');
    m = m.replace(/\(|\)/, '');
    length = parseInt(m);
   }
   //概要
   var desc = sheet.Cells(row, CELL.FIELD_DESC_COL).Value;
   if( desc == null || desc.length == 0 ){
    desc = '';
   }
   fields[fields.length] = {
     'name':name,
     'type':type,
     'length':length,
     'description': desc
    };

   row++;
  }
  
 }catch(e){
  //例外発生 -> 無視
 }finally{
  try{
   //Excelファイル close
   book.Close();
  }catch(e){}
  try{
   //Excel終了
   xls.Quit(); //きちんとQuitしないとプロセスが残る
   xls = null;
  }catch(e){}
 }
 return fields;
}

/**
 * アンダーバーを除去し、lowerCamelCaseに変換する
 */
function toLowerCamelCase(str){
 var tmp = str.toLowerCase();
 var arr = tmp.split('_');
 var ret = arr[0];
 for(var i=1; i<arr.length; i++){
  ret += arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
 }
 return ret;
}

/**
 * アンダーバーを除去し、UpperCamelCaseに変換する
 */
function toUpperCamelCase(str){
 var tmp = str.toLowerCase();
 var arr = tmp.split('_');
 var ret = '';
 for(var i=0; i<arr.length; i++){
  ret += arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
 }
 return ret;
}

/** JavaDocコメント文字列 出力 */
function javadocString(msg){
 return ['/**',msg,'*/'].join(' ');
}

/** DBMSタイプ→Java型に変換 */
function getType(t){
 var ret = 'String';
 
 if( /VARCHAR/i.test(t) ){
  ret = 'String';
 }else if( /NUMBER/i.test(t) ){
  ret = 'int';
 }else if( /DATE/i.test(t) ){
  ret = 'String';
 }
 
 return ret;
}


(function(){
 for( var i=0; i<XLS_FILES.length; i++ ){
  //Excelファイル読み込み
  var fields = readExcel(XLS_FILES[i]);
  //1つめの要素はテーブル定義
  var tableName = fields[0].name;
  var tableDesc = fields[0].description;
  //結果出力ファイル
  var fileName = tableName + '_' + tableDesc + '.txt';
  WScript.Echo(fileName);
  
  //出力ファイルデータ
  var dat = [];
  
  dat[dat.length] = javadocString(tableDesc);
  dat[dat.length] = 'final public static String TABLE_NAME = "' + tableName + '";';
  dat[dat.length] = '';
  
  //フィールド順の定義
  for( var j=1; j<fields.length; j++ ){
   dat[dat.length] = javadocString(fields[j].description);
   dat[dat.length] = 'final public static int FIELD_' + fields[j].name.toUpperCase() + ' = ' + j + ';';
  }
  dat[dat.length] = '';
  
  //フィールド変数
  for( var j=1; j<fields.length; j++ ){
   dat[dat.length] = javadocString(fields[j].description);
   var type = getType(fields[j].type);
   dat[dat.length] = ['private', type, fields[j].name.toLowerCase()].join(' ') + ';';
  }
  
  //ファイル出力
  var f = fso.CreateTextFile(fileName, true);
  f.WriteLine(dat.join(String.fromCharCode(13) + String.fromCharCode(10)));
  f.Close();
 }
})();

2012/02/10

【shell】 ファイルを指定ファイル数ごとにサブディレクトリに移動する

何年か前に書いたShell Script。
cutコマンドの使い方がすごい強引だったので、アップしてみます。
またどこかで使えるかも・・・


  • ファイルを指定されたディレクトリ以下に移動する
  • ファイル数が指定された数を越えないように、サブディレクトリに分割する


#! /bin/sh
# mv_files.sh
# ファイルを別ディレクトリに移動する
# 指定ファイル数ごとにサブディレクトリを作成する

FILE_NUM=30
TO_DIR=/work/mv_test/to_dir
FROM_DIR=/work/mv_test/from_dir

count=`find ${FROM_DIR} -type f | wc -l`
until [ $count -eq 0 ]; do
 if [ $count -le $FILE_NUM ]; then
  n=$count
 else
  n=$FILE_NUM
 fi
 # フォルダ作成
 dir_name=`date "+%Y%m%d%H%M%S%N"`
 mkdir "${TO_DIR}/${dir_name}"

 echo ${n}

 # ファイル移動
 files=`find ${FROM_DIR} -type f | sort | cut -d "
" -f 1-${n}`
 mv ${files} "${TO_DIR}/${dir_name}"

 count=`find ${FROM_DIR} -type f | wc -l`
done

2012/02/09

【PowerShell】 日時の処理 (get-date, new-timespan)


get-date


DateTimeオブジェクトを作成する。
System.DateTime。
Get-Date [[-date] <DateTime>] [-displayHint {<Date> | <Time> | <DateTime>}]
[-format <string>] [-year <int>] [-month <int>] [-day <int>] [-hour <int>]
[-minute <int>] [-second <int>] [<CommonParameters>]
Get-Date [[-date] <DateTime>] [-displayHint {<Date> | <Time> | <DateTime>}]
[-uFormat <string>] [-year <int>] [-month <int>] [-day <int>] [-hour <int>]
[-minute <int>] [-second <int>] [<CommonParameters>]

  • 来月の日時を取得する
(get-date).AddMonths(1)

  • 30日後を取得
$ts = new-timespan -days 30
(get-date).add($ts)


new-timespan

TimeSpanオブジェクトを作成する。
System.TimeSpan。
New-TimeSpan [[-start] <DateTime>] [[-end] <DateTime>] [<CommonParameters>]
New-TimeSpan [-days <int>] [-hours <int>] [-minutes <int>] [-seconds <int>] [<CommonParameters>]

  • 指定日から今日までの日数を取得する
(new-timespan (get-date -year 2000 -month 4 -day 1)).days

2012/02/04

「新しいタブ」の拡張



先日作成した「新しいタブ」に日時を表示するGoogle Chrome拡張を修正。


  • TwitterのBootstrapが2.0にバージョンアップしていたので、試してみる
  • CSS3のプロパティも使用して、それなりに映える見栄えを目指す



履歴検索機能を追加したものの、イマイチ使い勝手が良くない。
標準の「新しいタブ」に表示されている "よくアクセスするページ" はどうやって取得するんだろう・・・


https://github.com/Kazunori-Kimura/ClockNewTab