2008年7月15日火曜日

works4Life season V » Blog Archive » Excelの数式で、フルパスからファイル名を取得でき

works4Life season V » Blog Archive » Excelの数式で、フルパスからファイル名を取得できたよー

なんちゅうか、すごい人がいるもんですねぇ
俺なんか、
Function reverse (ss As String) As String
reverse=StrReverse(ss)
End Function
をユーザ関数として使うことしか思いつかなかったもん。


このエントリの全文をコピー↓しちゃいましてどうもすみません。一番上のリンク先の人が考えたんだよー

Excelの数式で、フルパスからファイル名を取得できたよー

嬉しさのあまりと自分リマインドのためのエントリです。

Excelの数式って使っていますか? 私は大いに使っています。特に使っているのはTEXT関数で、フォーマットを揃えるのに重宝しています。シート全部が数式だけを使って表示されているようなものも作ったりもしました。

いやいや昔はマクロやVBAもがんばって使ったもんです。でも面倒なのよね、プログラム見るのが。そんなわけで、最近は数式だけでなんとかするようにしていました。

が、一つだけ前々から実装できなかったものがあります。それはファイル名とパスの分離。

数式でフルパスからファイル名を取得するのは無理なのか?

例えば、「/var/apps/abcapplication/setup.exe」なんてフルパスがあって、このうち「setup.exe」だけ を取得したいだとか、「/var/aaps/abcapplication」だけを取得したいだとか思うのですよ。VBAで実装するのは、ウェブで検索し てもよく見つかるんです。しかし、これが数式だとやり方が見つからない。

ぐーぐる先生にも聞いてみても、 「マクロしか無理」というかVBAのやり方しか見つけられません。そろそろ数式の限界が! というかExcel2003にはsplit関数がないんじゃよー。split関数さえあれば、ファイル名とかパスだけとかを取得するのは簡単なのですよ。 2007ぐらいからは確かsplit関数がExcelにも標準装備されるとかなんとかいう噂を聞くんですが、私の今使っているExcelは2003。 split関数ありません。

数式でフルパスからファイル名を取得するのは無理ではなかった!

でもできたんです! とうとう数式だけでファイル名を取れる数式ができたんです!! その数式がこれ↓

=MID(A1,FIND("★",SUBSTITUTE(A1,"/","★",LEN(A1)-LEN(SUBSTITUTE(A1,"/",""))),1)+1,LEN(A1)-FIND("★",SUBSTITUTE(A1,"/","★",LEN(A1)-LEN(SUBSTITUTE(A1,"/",""))),1))

ちなみに「/var/apps/abcapplication/setup.exe」がA1にある時の数式です。これで、「setup.exe」が取得できます。

そして、「/var/aaps/abcapplication」だけを取得する場合は、こちらの関数になります。

=LEFT(A1,FIND("★",SUBSTITUTE(A1,"/","★",LEN(A1)-LEN(SUBSTITUTE(A1,"/",""))),1)-1)

数式ざっくり解説

この関数のポイントは、一番右側にある「/」の順番をどうやって取得するか、です。関数の流れとしてはこんな感じで組んでます。

(1)「/」を空置換して文字数差分より、「/」の数を調べる
(2)一番最後の「/」をSUBSTITUTE関数で★に変換する
(3)★の場所をFIND関数で取得する
(4)MID関数もしくはLEFT関数で、目的の文字列部分を抜き出す

かなり無理やり感がありますが、そこは目的が果たせたので万事オッケーです。ちなみに、★に置換するのは勿論パスに存在しない前提。★が出てきそう だったら、別の文字に変更すればいいです。上記はUNIXパスなので、Windowsのパスなら「/」が「\」になるだけなハズです。

終わりに

GTDとは全然関係ない話でしたが、あまりに嬉しかったのでエントリしました。フルパスからファイル名等を数式で取得するのは、前々からできないか と気になってたんですが、数式では無理というのが通例でした。性も懲りずにいろいろ調べた結果、ヒントが見つかって今回の数式を作ることができました。本 当に嬉しかったです。

2008年7月14日月曜日

Open Lisp 超初心者用 コード集 01

;;Open Lisp です

;;ファイルへの書き出し(ファイルは上書きされる)
(with-open-output-file
    (outstream-test
    "T:/Lisp/test_code/test-output-file.txt")
    (format outstream-test "Hello file!~%")
    (format outstream-test "Hello line!~%")
    (format outstream-test "Hello strings!~%")
)

;;ちょっと調べたところでは、Lispでよく出てくる「with-open-file」は、存在しない模様…


;;ファイルを読む(ただし、この例だと初めの1行のみ読む)
(with-open-input-file
    (inputstream-test
    "T:/Lisp/test_code/test-input-file.txt")
    (read-line inputstream-test))


;;listの連結
;;(append list*) → <list> function
    ;;連結するlistはいくつでもいい
(defglobal aa nil)
(setf aa (append '(a b c) '(d e f)))
;;⇒ (a b c d e f)


;;文字列の連結
;;(string-append string*) → <string> function
    ;;連結する文字列はいくつでもいい
(string-append "abc" "def")
;;⇒ "abcdef"