2008/04/28

Excel ひとつの列の分割テクニック

同僚からちょっと面白いExcelネタを振られたので、そういうときの一番簡なワザを伝授しました。

その同僚の問いはこんな感じ。

  • A列に「XXXX-XX_999」というフォーマットで、CSVファイル名の一覧が入っている。
  • アンダースコアの後についている「999」はCSVの件数で、この「999」をゲットしたい。
  • 但し「XXXX-XX」にあたる部分の桁数は不揃いだし、「999」の方も、1桁だったり、4桁だったり桁は揃っていない。

同僚は「Right関数とかを使うのかな~?」というところまでは想像したものの、桁が揃ってないのでうまくいかず、関数を調べればどうにかなりそうだと見当はついたものの、調べているヒマもなく、アワアワしていたという話。

私はExcelには、大雑把に言って、オペレーター・テイストな小技と、プログラマー的な小技の2種類があると思うのですが、まずは超ラクチンなオペレーター技から。

  1. 問題の列を選択。
  2. [データ]→[区切り位置]
  3. 「カンマやタブの~」のオプションのまま[次へ]
  4. [区切り位置]のオプションで[その他]のヨコにあるテキストボックスへ、今回の区切り文字となる「_」を入力→[次へ]→[完了](まー、「列のデータの書式」を設定したければ、この辺でどうぞ)。

以上、Excel単体でこのテの問題は、サクッと完了できてしまうわけですね。文字列1文字を区切り文字にできてしまう「その他」オプションは意外と便利なので、試す価値アリです(「カンマやタブ~」のところまではきても、「その他」を使ったことのない人は意外と多い)。

ちなみにうちの新人に「Excelならではの機能を使ってもいいし、それよりはちょっと手間でも関数の組合せでも処理できたりするけど、どーゆー手段があると思う?」と気晴らしにネタを振ってみたところ(現在新人はAccess猛特訓中…)、列をエディタへコピーして、「_」を「,」へ置換。テキストファイルを「.txt」で一旦保存。それから「Excelでのcsv ファイルの取り扱い方」で扱った「ファイルを開く」から始めて、上の手順3に合流した流れへ入っていきました。ちゃんと教えたことを流用していて、なかなか良い解答を出してきました。

他に、SQLで頼まれようが、手続き型言語で処理するときだろうが、思考方法としては同じだから、その後につながる基礎体力になるだろうということで、新人へは関数技もあわせて伝授。一応、新人にはExcelにおける一通り文字列関数は教えたし、簡単な関数のコワザも教えたものの、まだまだそれらを組み合わせたコワザはでてこないようなので(調べてわかればオーケーだと思うので、基本はググって調べるなり、閃くなり、自力で問題解決できればオーケーという感じでやっているのですが)、

=VALUE(RIGHT(A1,LEN(A1)-FIND("_",A1)))

とかをやってみせる。

FIND 関数は指定された文字列(検索文字列)を他の文字列(対象)の中で検索し、その文字列が他の文字列内で最初に現れる位置を左端から数え、その番号を返す関数ですね。今回の場合SEARCH関数でも良いですが…。あまり細々したことを一方的に教えても仕方がないので、その辺の応用・知識の広げ方・好みは本人に任せるとして…。「先日教えてもらった関数はこのように使うのか」というカオをしていたので、大丈夫でしょう。

ちなみにこのテの列の分割ネタでよく頼まれ、しかもわりと面倒なネタとしては、住所の分割で、「都道府県とそれに続く住所を分けたい」とか、「市区町村と~以下同文」あたりなんですけどね。

住所を印字する場合、住所ラベルにしろハガキにしろ、印字面積の横幅は決まっているわけで、長い文字列の住所を扱う場合、ある程度の単位で改行する必要がでてきます。ところが、「なーんにも考えないで住所を収集しました!」という人々のデータというのは、最終的に印刷するときのMAX文字数を考えず(横幅とフォントサイズ次第で、つみこめる文字数は違ってきますが、それにしたって限界というものはあります)、1フィールドだったりするわけです。文字数でばっつり改行を入れても、郵便物は届くようではありますが、番地の途中等で改行されるのは見苦しいので、なるべく住所の文脈で改行したいではないですか。

「こんにゃろー、最初から分割していればくっつけるのは簡単なのに、文脈で分割するのは何倍も大変なんだよー。最終的に何の為にデータを集めるのか、少しは考えて回収しろよー」とブツクサ思いつつ、頭をしぼるわけですね。入力の段階で考えておけば手間いらずなのに、こっちになんの相談もせず、勝手に営業なりド素人が集めた回収データは、なにかとファジーで、データとして汚いものが多いわけです。

ちなみに住所分割のコワザは(特に都道府県分割ネタ)、ググると結構小技が出てくるので、わりとメジャーなネタなのではないかと思いマス。なので省略。

2008/04/27

買ったわー

GWはGeekWeek…。本日、マシンを買ってきました。ひさしぶのマシンのお買い物ですから、ついつい店員さんに根掘り葉掘り、部品ひとつひとつについて、訊いてしまいました。

見れば欲しくなるので普段は見ないようにしている…、というのもあって、ハードはマッタク詳しくないんですよね。ぽんぽん新しいCPUやらが出てくるし、グラフィックス系の部分もよく知らないし、Vistaもいじっていませんし…。ここ数年流行している光沢液晶も、いまだに使ったことがありませんし。

「完全に時代遅れだなー」という自覚があるので、ここぞとばかりにハテナ?と思っていたことはがんがん質問。

「ハードをいじるのことが、この人、かなり好きなんだろうな」という感じのハードへのラブが伝わってくる人で(「ナカを開けるとこのコはキレイなんですよー」と思わず嬉しそうに云う様は、まるで「内臓がキレイですねー」と嬉しそうにいう外科医のよう)、気兼ねなく質問できてヨカッタです。で、このオタな感じの店員さんは、「見た目より実をとれ」的な解説をする人で(さすがにあれだけ質問すれば、私の価値観を見極めますわね)、なんだかんだでディスプレイもノングレア液晶をプッシュされ、ノングレア液晶に…。

「光沢なんてただの飾りです!えらいヒトにはそれがわからんのですよ。映り込むのに!」

…みたいな?

あのツルツルした華やかさにふらふらと気持ちは傾いていたのですが、職場の蛍光灯が明るすぎたりして、常にディスプレイの「反射」には悩まされている日常があるので、「映り込み」の話を聞いて光沢はアッサリ断念。

省スペースのデスクトップが欲しかったので(≠ノートで。この数年ずーーーーーっと家でも職場でもノートだったので、なんというか飽きました)、まー満足です。OSはXP(今回は一応、Vistaのダウングレードで購入。XPはProfessionalなのでIISも使えるわー←所詮なにかとMSっ子)、CPUはCore2Duoとかがいいなーと思っていて(要はCPUが2つ以上ってところに拘っていた)、省スペース、の3つが必須条件。となると、殆ど選択肢がなかったところはありますが…。

お届けは29日の午前中デス。たのしみーー。

え、機種は?…秘密デス。

Excel 汚いデータをキレイにするにあたって便利な関数

データをクリーニングするにあたって便利な関数は、大体においてこんなものでしょう。

  • RIGHT関数/LEFT関数/MID関数…右から、左から、何個目から何個まで文字列を取得
  • TEXT関数…数値を書式変換した文字列にする
  • LEN関数…文字数
  • TRIM関数…左右の空白除去
  • VALUE関数…文字型のものを数字型に変換
  • JIS関数/ASC関数…全角・半角変換
  • UPPER関数/LOWER関数…英数の大文字・小文字変換

Replace関数(特定文字を置換する)も便利な関数ですが、Excelの場合だと、置換機能があるので、ちょっとした半手作業でデータを処理する場合、私はあまり使いません。

オーソドックスな利用シチュエーションは以下の通り。とりあえず、ここでは機能と使い方のヒントを列記していきます。関数の詳細については、Excelのヘルプを見てください。

LEFT関数を使って0つき数字の生成
RIGHT関数はそもそも右から何文字目までをゲットしてくる、という典型的な文字列操作関数。「0001」「0002」など0をつけて数字の桁を揃えたいとき、非常によく使います。
ex)A1に「123」という値が入っていて、B1のセルに「00123」という5桁のゼロつき数字にして表示したいとき
 B1のセルに「=RIGHT("00000" & A1,5)」と書く
 ※()カッコの中の文字列を引数と云います。「引数」というコトバは、頻出単語なので、関数の中に入れる文字列のコトなんだ、ととりあえず覚えておきましょう。この例の場合だと「"00000" & A1」と「5」のことを引数と云います。
 たとえばこのままドラッグすれば、A列の数字が全部5桁の0つき数字に揃います。
TEXT関数を使って数値の書式を揃える
TEXT関数を使って、数値の書式を変換することも可能です。上記の例で0つき数字5桁に揃えるには、
「=TEXT(A1, "00000")」
とかですね。TEXT関数でカンマつきの数値変換、及び日付変換などもできます。VBで云うところのFormat関数のようなものです。
LEFT関数で固定長の文字列の生成
RIGHT関数とは逆に左から何文字目までをゲットしてくる、というタイプの関数。固定長の文字列を作成したいときなどによく使いますね。固定長というのは、全角の6文字なら6文字で、文字と全角スペースで六文字を埋めてしまうこと。PCだと可変のCSVでのやりとりなどが多いのでこのワザの出番はあまりありませんが、ホスト相手にやりとりするデータだと、固定長にすることが多いので、基本はコレです。
ex)A1に「まつもとひろゆき」とかいてあって、B1のセルに「まつもとひろゆき□□□□□□□□□□□□」と表示したいとき。
 B1に「=LEFT(A1 &REPT("□",20),20)」と書けば、
「まつもとひろゆき□□□□□□□□□□□□」
という結果に。REPT関数は今回の場合、□を20コ繰り返すという意味。□を全角スペースと見立てると、固定長になります。
MID関数
左から何個目から、何個までをゲットしてくる関数。ちなみに左から「何個目から…」というところを1に設定すると、LEFT関数と同一の意味で使えます(一番左は1とカウントします)。上記の「まつもとひろゆき」の例の場合、「=MID(A1 & REPT("□",20),1,20」となります。
ちょっとした固定長のデータの検証するときなどにも多用していますねー。このテの仕様書は大抵Excelでいただいているので、フィールド名と文字数などが表になっているわけです。開始文字列の数をExcel上でちゃちゃと計算して(区切り文字があればそれも考慮)、仕様書の文字列数をそのままセットすれば、MID関数で固定長のデータを拾ってこれるわけですよね。私の場合、開始文字列と、拾ってくる文字列数を、仕様書のフォーマットにあわせて縦に向かって計算して、コピー&ペースト術で、それらのタテ型の列をヨコに並べる。で、このフィールドごとの開始文字列のポジションの計算結果と文字数を利用して、MID関数を利用することが多いです。仕様書をそのまま利用できるのでなかなかこのテの組合せは、ちょっとしたときにベンリで重宝しています。
LEN関数
文字数をカウントして返してくるカウント。Replace関数やMID関数、FIND関数などと組み合わせて使うシーンが多いですねー。
TRIM関数
引数の文字列の左右の空白を除去してくれます。「□あいうえお□□」という文字列がセルA1に入っていたとしたら、「=TRIM(A1)」で「あいうえお」を返してきます。空白が入っていれば、文字列の文字コードの組み合わせは変わってきてしまい、「見た目」は一緒なのに、データは異なるデータとして認識されますので、なにかと不都合がおこります。ですからなにかとデータにはTRIM関数を一旦かませてから、比較したり、加工したりすることなどが多いです。
VALUE関数
セルの書式設定が「文字列」のまま、見た目「数字」のデータを計算しようとしても、データ型は文字列として扱われ、四則の計算などの処理は一切出来ません。ですから、数字としてデータを扱いたい場合、一旦「VALUE」関数で、数値型になおしてから、計算などを行います(詳しくは「Excel文字列を数値変換する」を参照)。
JIS関数/ASC関数
JIS関数…半角文字を全角文字に変換する関数
ASC関数…全角文字を半角文字に変換する関数
というわけで、引数に指定された文字列を変換してくれますヨ。いわゆる「全角/半角」を知らないも入力するのがExcelワールドなので、集計作業等をするにあたってデータをクリーニングしたいとき、このテの関数はかなり重宝します。
UPPER関数/LOWER関数
UPPER関数…英文字をすべて大文字に変換する関数
LOWER関数…英文字をすべて小文字に変換する
このあたりも上記同様、押さえておきたい関数ですね。

以上、大抵の言語には、このテの役割を果す関数は、名前は違えど揃っているのではないでしょうか。プログラマーの方はこのテのコワザの思考方法は一通り抑えているのではないかと思います。

Excel的には、これらの関数と「Excelコピー&ペースト術」を組み合わせで、一発限りのちょっとしたデータをクリーニングのときなどは、大方半手作業で処理できてしまうわけです。

理想は勿論このテの加工をせずにすむよう、汚いデータを作成しないことです。その為には、事前にきちんとなんの為にデータを収集しているのだからどんなモノが必要なのか計画を練り入力時のがっつりしたエラーチェックなどは必須事項です。後から修正する方が当然大変ですから…。

しかし現実にはキタナいデータを突然送り付けられたり、特に単発のものであれば、多少の整形処理をしなくてはならないシーンは多いわけです。そんなとき、これらの関数を知っていれば、グンと早く、より確実な仕上がりのキレイなデータにすることができます。手作業部分が増えれば、それだけヒューマンエラーの出る可能性も大きくなるので、なるべく手作業をやらずにすむ部分はやらないというポリシーで、バッチ的に処理する工夫をして、ラクをしましょう。

2008/04/24

Excel文字列を数値変換する~見た目は数字なのに計算できない!とお困りの方へ

セルには明らかに数字が入っているのに、何故かSum関数やら引き算やら、数値計算ができない!──というシチュエーションの原因は、大抵、セルの書式が文字列になっていることによります。この場合、単に、セルの書式設定を「文字列」から「標準」などに変更するだけでは、計算結果を表示してくれません。何故なら文字列の書式 設定で入力されてしまった数字は、単にセルの書式設定を「標準(或いは数値など)」に戻すだけでは、見た目は数字でもやっぱりExcelには「文字列」として認識されてしまうからです。

よってここでは、「文字列」認識されてしまっているセルの値を「数値」として認識するよう、細工する必要がでてきます。以下が私がよく使っている文字列→数値変換の手順です。

  1. VALUE関数を利用して、あいているスペースに、セルの書式が文字列になってしまっているセルを引数にして、だだーーっとドラッッグしてコピー(B1のセルが文字列だとしたら、[=VALUE(B1)]とかです)。
  2. 貼り付け予定先のエリアの書式を[標準]にしておく([文字列]ではなく![文字列]のセルに貼り付けても、再び文字列になってしまいます)。
  3. VALUE関数で表示させたセルをコピー→形式を選択して貼り付け→[値]オプションをチェック!→任意のセル(貼り付け先のセルの書式は[標準]だとか、ちゃんとしたものを選んでください)を選択して、貼り付け!

Excelでのcsvファイルの取り扱い方でやったように、0落ちをおそれるばかりに、シートを全選択して、全てのセルの書式を文字列にしたときなどに、「見た目は数字なのに、Sum関数さえ使えない!」という自体によく陥るわけですね。それはセルの書式が文字列だから計算できないわけで(見た目は数字だけど、あくまでも「文字列」として扱っているわけですなー。Excelはそのセルを数字だとは思っていないので、計算などはできないわけです…、とデータ型の意識の希薄な人々の場合にはちと説明しづらいのですが、そーゆーもんだと思ってください)、計算したい列などに対しては、文字列から数値変換する必要があるんですね。そういう場面で、このテの変換ワザをよく使っていマス。

Excel上で文字列から数字変換するコワザは他にも色々あって、Value関数を使うかわりに、空いているセルに「=文字列のセル*1」という乗算を行なって、乗算を入れたセルの書式を「標準」選択。[形式を選択して貼り付け]→[値]オプションという流れに入るやり方も、王道の一つとしてあります。

さらにExcel2002あたりのバージョンからは、文字列のセルに数字のみを入れていると、左上隅に緑色のエラーインジケータが表示されているセルが現れ、そのインジゲータを選ぶと「!」が表示。「!」をクリックすると、[数値に変換する]というメニューが表示されるので、これを選ぶと、数字に変換される親切設計になっています。エラーインジゲータが一定範囲で連続して出ている列なんかだと、まとめて列のかたまり毎選択して、いっぺんに数値に変換は可能です。ですが、まー、一定の範囲をまとめて数値変換したいときには、イマヒトツ一発の動作で決まりづらいので、個人的には、関数やコピー業に慣れている人は、Value関数などの計算式を入れる方法が、途中、標準のセルが混ざっていようが気にせず確実に数値変換できるので、ベンリと感じるのではないかなー、という気もします。その辺は、その人の好みによりますが…。

他には、空いているセルの書式を[標準]にしてから「1」を入力。そのセルをコピー。文字列の書式になっている数値型にしたいセルの範囲を選択したのち[形式を選択して貼り付け]→[乗算]を選択→[OK]といったやり方。

[データ]→[区切り位置]→[カンマやタブの…]を選択→[次へ]→区切り文字に[タブ]を選んだまま→[次へ]→[列のデータ形式]で[標準/G]を選んだまま[完了]というやり方もあります。しかしこのやり方では、セルの内容的には数値になっているものの(例えば0つき数字であれば、0が落ちている=数値変換はなされているということ)、セルの書式は文字列のままになってしまうので、最終的には数値にしたかったセルの書式を[標準]に設定しなおした方が、キレイに決まると思います。

ちなみにプログラムでExcelにデータを吐き出すとき、シートを全選択してセルの書式は一旦文字列にしてからデータを吐き出す…、という流れで書く人は意外と多いので、納品されたExcel のセルの書式設定が[文字列]になっていて、その後、「数字として加工ができん!」というような場面は、よくありマス。まー、Excelをプログラムで吐き出す立場からすれば、日付だろうと、0つき数字だろうと、書式を文字列にしてしまえば「見た目」は確実に確保されるわけですから、指定された「見た目どおり」という意味では手軽な手段なんですよね。

というわけで「この納品されてきた Excel表にちょっと手を加えたいのに、どーして計算できないの?!」と大騒ぎしている人々の尻拭い/相談されることは、Excelラブを公言している立場上、好むと好まざるとにかかわらず意外と多いわけです。あんまり変換する表の数が多いときは、責任もって確実に全ての表を、単に0つき数字のコードとして使っているのか数値計算用する必要のあるフィールドなのかをイチイチ見極めて、変換するのは私にとっても苦痛なので(そもそも自分の担当案件ではございませんので…)、発注先に再納品を要求するよう薦めたり、数値変換のやり方を教えて、「あとは自力で頑張ってね」と申し渡したりするわけですが(二度とこんなザルな発注をしてくれるなよ…、てなところです)。

そんなこんなで、Excel納品を依頼する場合には、一応、この辺のセルの書式についても、発注先には予め注文をつけていた方が無難 だと思います。その一方で、このテのExcelを納品をしてくるプログラマ側には、素人が発注するとき、この辺のことは当然気づかないで発注しているんだから、プロならその辺まで察してフォローしてやれよ、とも思うわけですが…。発注元の「仕様」に入っていなかった云々というより、そもそもExcel納品を依頼されているときに、Excelとして死んでいる表を納品してどーする、と思うわけですね…。

2008/04/22

Excelコピー&ペースト術 ~ 行列を入れ替える他

Excelのコピー術、形式を選択して貼り付けから、整形する際によく使う、以下2点についての紹介(ドラッグとかについては、常識すぎるので他を当たってください)。

▲クリックすると画像拡大。
コピーしたエリアの左上のセルを選択して、右クリック→[形式を選択して貼り付け]を呼び出せば、式から値へとそのまま入れ替わる感じになりますね。

  • 行列を入れ替える

まず、形式を選択して貼り付けの呼び出し方は共通ですので、説明を。

  1. コピー範囲を選択
  2. 一旦コピー
  3. 貼り付け先のセルを選択
  4. 右クリックで[形式を選択して貼り付け]を選択

以上の動作を行うとずらずらっと、オプションボタンが出てきます。オプションボタンを選択して、[OK]をクリックすれば、便利なコピー&ペーストは完了です。

[値]オプションを選択

これはセルに関数などの式が入っていて、計算結果を固定してしまいたいとき、このオプションを利用すれば、計算式から見たままの値へと固定されます。式は便利ですが、コピーなどしていくうちに相対的に動いたりもして、危ない側面もありますから、値が不動だと決定したならば、固定してしまいたいときがありますよね。その際にご利用ください。

行列を入れ替える

コトバ通り。このチェックボックスを入れると、行と列が入れ替わりますね。たまーに行と列を入れ替えたい場面というのは出てくるかと思いますが、これであっさり解決です。

わりとこのチェックボックスを知らない方は多いみたいですねー。よく訊かれます。

2008/04/21

Excelでのcsvファイルの取り扱い方~0落ち/日付変換対策

データのやりとりはcsv形式(カンマ区切り)、という方が多いと思います。csvファイルをダブルクリックすると、Excelと関連づけられていて、Excelが起動するマシンがほとんどですよね。ここにワナがあります。csvファイルをExcelで開くと、データが壊れる可能性がある、ということを皆様ご存知でしょうか?

壊れる可能性のあるデータの代表格は、

  • ゼロつき数字のセル(「00001」など、ゼロからはじまるもの。Excelで開くと、数字型として認識されて0が消えてしまう)
  • 「2-2-3」など、数字とハイフォンやスラッシュのみで構成されているセル(「住所の番地のみ」のセルなどで、数字とハイフォンだけ、などだと、日付形式として認識され、番地が日付に解釈されてしまう)
  • カッコで囲まれた数字のみのセルはマイナスになってしまう(「(5000)」は「-5000」に)。

値をみてExcelが勝手にデータを、数字型だの日付型だのに解釈してしまって、データが壊れてしまうわけなのです。もらったそのままのデータの中身をみるだけなら、セルの表示書式は「文字列」でなければならないのです(ただし、文字列の書式だと、計算などはできなくなります。あくまでも「文字列」で数字ではないので)。

Excelでデータを確認して、「上書き保存」などされれば、完全にデータは壊れてしまうわけです(0落ちはともかく、日付変換などは致命的)。このテの事故は大変に多いですね。以下、csvファイルに対するお作法。

大前提としては、拡張子を変更しなければならないので、拡張子を表示しているマシンってトコですね。拡張子ってナニ?!という方はまずは拡張子の表示、隠しファイルの表示で、マシンを拡張子表示状態にしてください。Macは…。わかりません。

事故防止対策:Excelとcsvファイルの関連付けを外す(Winでのやり方)

Excelをインストールすると、Excelとcsvファイルが関連付けされるので、まずはこれを解除します。

  1. エクスプローラを起動。
  2. [ツール]→[フォルダ オプション]→[ファイルの種類]→[登録されているファイルの種類]の中から拡張子[CSV]を選択。
  3. 下段[拡張子'CSV'の詳細]→[変更]→[プログラム]の中から、利用しているエディタを探す、もしくは[参照]。→[OK]

以上で、CSVとエディタへの関連付けに変更されます。ハッキリいってデフォルト設定でCSVとExcelを関連付けていても、経験上、役に立つことはほとんどないと思いますので(紛らわしくて事故の元)、外した方が賢明だと思います。

具体的なExcelでのcsvファイルの取り扱い方
  1. [*.csv]というファイル名を[*.txt]ヘ変更。
  2. Excelを起動。
  3. [ファイル]→[開く]→csvファイルを選択。→[開く]
  4. [カンマやタブなどの区切り文字によって…]にチェック→[次へ]
  5. [区切り文字]で[カンマ]にチェック→[次へ]
  6. [データのプレビュー]で、文字列型のフィールドを選択して[列の選択]で[文字列]にチェック(全フィールドの選択も可。私は大抵、データを壊したくないので、とりあえず全フィールドを文字列にして、開いて中身を確認する、というパターンが多いです)→[完了]

ちなみに、ファイル名をtxt名に変更しないと、セルの書式を選択するウィザートが起動しません。

以上がオーソドックスな開き方。

他に、似たような手順としては、[データ]→[外部データの取り込み]→[テキストファイルのインポート]で拡張子を選ぶ[ファイルの種類]のボックスで[すべてのファイル(*.*)]を選択して、任意のCSVを選ぶという方法(その後は[カンマやタブなどの区切り文字によって…]という上記の手順と一緒)もあります。

CSVファイルをエディタで開いてコピー、Excelに貼り付けて、[データ]→[区切り位置]を選択して、[カンマやタブなどの区切り文字によって…]以降の手順に入る方法もあります。

少し気の利いたエスケープシーケンスを利用できるエディタ*1をお持ちの方でしたら、カンマをタブ区切りに変換。Excelのセルの書式を文字列にしておく、エディタのタブ区切りデータをコピーしてExcelに貼り付け、という方法などもOKです。

そんなこんなで、csvファイルよりタブ区切りのデータの方が、好ましいと私などは思っていますが、世の中はcsvファイルが主流ですからね。仕方ありません。

データに0つき数字などのあるcsvファイルで、スタートの私たちから仲介役を渡ってエンドまでの距離が長い場合や、事前に取り扱い方の注意をいくらうながしても、「この人、どーもわかってないな…」と危険を感じるとき、わざと拡張子をtxtにしてファイルを受け渡すこともあります。そうすると大抵素人さんは「Excelでファイルが開かない!」と大騒ぎして、データ作成元のこちらに問い合わせしてくるので、そのタイミングで"待ってました"とばかりに、電話で開き方講座をリモートコントロールして行なうわけです。csv取り扱いのマニュアルをつけようが、事前に注意を促そうが、現実に困るまでは、何を云われているのかわからない人はわかってはくれませんので、拡張子を変えてしまうのが、相手のレベルも測れて、意外と安全なんですよね…。

*1タブは¥t、改行は¥nとかで表現できるエディタであれば、検索対象に「,」カンマを入れて、置換後文字列に「¥t」と入れれば一発で置換完了。WinでフリーのエディタだとTeraPadあたりだと、アドミ権限をもっていなくてもインストール可能なので、わりと万人向けにオススメかも。

2008/04/15

Excel布教ことはじめ

客寄せパンダ的にExcelの簡単な小技・哲学なぞもちまちま載せていこうと思います。新人教育の時節ですし…(遠い目)。

Excel小技サイトは数あれど、私の中にもExcel哲学はありますので…。小技は数ある小技サイトで十分だと思いますし、細かいテクニックはその都度調べればいいと思っているわけですが、最低限覚えておくべき実践的な技、及びExcelを使うときに根底を流れるべき「哲学」の部分が、小技サイトや市販の教本にはどこか物足りないさを感じるわけですよ。私のExcel上における価値の基盤は、速さ、正確さ、美しさ。云ってみれば、処理の最短方法というところでしょうか。

ジオング
足(線引き)なんてただの飾り…!とは云いませんが。エクセルで線を引っ張るのは、最後でいーの!引き方にもちゃんと美学があるわけですから。

普段から私はExcelラブを公言しているので、Excel/Accessネタでは便利屋の如く呼び出され、他人の手元をみるチャンスも多いのですが…。

Excelは手軽なアプリなだけに、ユーザーのレベルも千差万別で、それ故に怖いツールだなーと思うことがしばしばあります。

この辺の「常識」の違いが、人災的ボトルネックになったりもするので(中継ぎ役が確認のつもりでCSVファイルをExcelで開いたせいで、データが壊れた!!とかはたまに聞く話…。運用を考えるとき、この種の余計なことをさせない経路を作るか、「常識」を関係者各位に徹底認知させるかはケースバイケースですが、その辺も読み込んでおかないとあっさり事故になりますからねー)、こちら側から歩み寄る必要は常に感じているわけですが。普段Excelを使い倒す必要のない人たちにどうこう云ってもしょうがないので、わかっている方が、基本、先回りして予防に走るしかないなー、というのが私のスタンスです。

とはいえ、あんなものは飾りです。 偉い人にはそれがわからんのですよ。(byジオン兵)と云いたくなることも、正直多いです。

あんなもの、というのは、罫線引き、セルの結合、フォントサイズ、色つけなどなど。Excelのビギナーであるほど(営業さんとか)「見た目のみ」重視で表を作成しているフシがありますが、私らデータ屋は再利用のしやすさを重視します。

見栄えも重要ではありますが、幾らキレイに色をつけても、表をつくるからには、色だけではなくフラグ(或いはコード)もたってなければナンセンス。フラグさえ立っていれば、色づけ線引きなんて瞬殺ですから。

「データを作成する」ときは、常に再利用(加工のしやすさ)について考慮するべき。偉いヒトにはそれがわからんのですよ。いくら綿密に網掛けをしたって、そのデータを二次利用するとき、網掛けじゃ、フィルターだとか並び替えだとかが全然できないじゃんよ。営業君がご丁寧に網掛けしてくれたデータをみて、その後ぼちぼち手作業でフラグをたてていくときのむなしさときたら…!同じ労力をかけるのなら、色づけじゃなくて、まずはフラグを立ててくれよ!!コストのムダ!──と心中叫んでいるExcelユーザーは多いはず。

タグでいえば、物理タグと論理タグの溝みたいなものでやんす。私は当然論理タグ派です!!なんちゃって。あっ、そこでソースをみないこと!

mumble→今年の新人はカーリング型でしたっけ。超氷河期時代の私たちとは隔世の感がありますの…。

6月以降どこへ配属されるにしろ、ググり方、Excel、Accessの基本は3種の神器として叩き込まねばの、うちで預かるからには。

でも実際の仕事としては、手頃なサイズの課題が今現在、私の手元にはあまりないんだよなー…。入力作業でも集計作業、ラベル印刷でも細かいものならなんでもいいんだけど、誰かなんか軽めの仕事をくれないかなー。やっぱりナマの教材の方が燃えるし。

自分の得意ジャンルのものは、ある意味、気がつくと同時に処理しちゃっているところがあるので、私の周囲では常に残件ゼロ状態…。わりと困る。

2008/04/05

Webアプリのバッチ処理

こんばんは。なにかとスタンドアローンのじょにです(←ちょっとヤケ)。

普段私はバッチ処理系なものを作ることが多いので、大量データを一気に加工するシーンはよくあります(でもMax60万件くらい。まーそんなもんです。Accessなので)。バッチ処理といえども、流して帰る…、という悠長なことはなかなかやってはいられませんので、なんであれ、待ち時間(処理時間)はなるべく短くすることは常に気にかけています。その際、まず私が考えることは、アプリからDBへのアクセス回数を減らこと。

DB設計も絡んでくる話だとは思いますが、手っ取り早い手段としては、

  • コード等が入っているマスターテーブルをハッシュに入れて、いちいちエラーチェックやら情報付加の為にマスターテーブルにアクセスしにいかない。
  • ぶんぶんLoopさせているところは、SQL一本で一挙にカタをつけられないか考える(Loopの回数を減らす)。

あたりでしょうか。

ADO.NET であれば、テーブルをDataSet(メモリ常駐型のデータ表現)へ展開させるので、自然とそれほどDBへはアクセスしなくてすむようになりましたが(もっともメモリに展開してからの書き方は色々で、書き方次第かなり速度に差は出ます。DataViewに突っ込んでRowFilterを使うよりハッシュを使った方が早いとか、リレーションシップを生成した方が早いとか)、Access単体の時はADO/DAO接続なので、インデックスの張り方、Dictionary関数とSQLの使い方に比重がかかってきます。その為には、メモリでもワークテーブルでも使えるものはなんでも使おうとします。

ところがWebのお作法は少し違うようですね。

近頃近所でアワアワしている人が、テストサーバーでWebアプリからよくCSVファイルをテーブルへ登録する実験を行なっています。登録したい件数が多すぎて(といっても4万件くらい?)、1回でアップロードできないので、その原因を探っているとのこと。テスト環境のColdFusionからかえってくるエラーメッセージはメモリーオーバーです(なんでメモリーオーバーのエラー表示???)。そんなこんなで、現時点で本番環境で速やかにできることといえば、CSVファイルを分割して、ちまちまアップロードすることくらいなんですね。あまりにそれでは手間ヒマがかかりすぎるということで、うまいことソースに修正を加えたいらしいのですが…。

実験してみてわかったことは、一見胡散臭そうにみえたCSVファイルの読み込み、INSERT文自体は4万件であろうとも、実はほんの数秒の処理であること。負荷の原因は、どうやらCSVファイルに対するエラーチェックだということです。で、そのエラーチェックのソースがどうなっているかといえば、1件1件エラーチェックする為に、次々、コード表を持っているテーブルを見に行っては値のチェックを行なっている。え。


4万件×何回テーブルを見に行っているの?


担当者は「Oracleだから沢山アクセスがあってもダイジョーブ」とか云っていますが、それってホントのことですか?この辺のことは簡易DBのAccessユーザーの私には正直わかりませんが、仮に1行につき10回DBを見に行ったとすれば、あっという間に40万回の連続ワザ。ホントにそれでヘーキなのでしょうか。なんであれ、ラウンドトリップ回数なんてなるべく少なくするべきものなんじゃないの???

Webの世界だと、色んな人が色々なテーブルを参照したり更新していたりいるし、アプリケーションサーバーでパワーの要ることをやったり(ハッシュとかも私のようにばんばん使っていると、一人分のメモリ消費×同時アクセスしている人数なので、あっという間にサーバーのメモリを消費してしまうわけですね)、色んなレコードに対して一挙にどうこうすると、Webを使っていた他の人が困っちゃう…、という発想があるから、ロックをかけるレコードはなるべく少なく、ちまちま1件ずつレコードを見に行くのがまずは基本のようですが。

CSVファイルの登録なんてバッチ処理なんだし、ある程度のコード表ならいちいちDBへアクセスしにいかずにメモリで持っていた方が断然早いし、既存データとの重複チェックを行ないたいなら、ワークテーブルに一端入れて、SQLで一発チェックした方が手っ取り早い気がするんですけど(或いはテーブルに入れてステータス管理とかでもまぁいいけど、インデックスとか張っちゃったりしていると問題ありそうなので、ワークテーブル)。ワークテーブルにもセッションみたいなものを入れられるフィールドを1列作っておけば、ワークテーブルに入ったデータのうち、どのセッションで利用したデータかの識別はできるわけだし──とか考えちゃうわけですが、なんらかの「失敗」がおきて残っちゃったワークテーブルのデーターをいつ削除するんだ、とか色々あって、そういう考え方自体危険なのかなぁ…、と無知なだけにモヤモヤ。

普段、スタンドアローン寄りのアプリばかり作っているので、この種の「バッチ処理」の実装部分で私はそこまでメモリの消費を気にしたり、同時アクセスしているメンバーのことをあまり考えていません。複数人で使うLAN内で使ってもらうようなアプリに「バッチ処理」を載せるときには、DBへアクセスしている人が自分以外にいないかをチェックする機能をつけて、「バッチ処理を行なう人は現時点で一人」という環境を作ってから、バッチ処理を実行させたり。「運用」とセットで考えると、単体のプログラムの外側で簡単に解決できちゃうことも多いですから、その辺で無理のないような回避方法を考えるとか(←1本のソフト単体でなんでもかんでもどうにかしようとはあまり思っていない。人の動きを簡便にすることは念頭にありますが)。

私の使っているDBはAccessですし、同時アクセスの人数はもともと少なく、それが通ってしまう素朴な世界に住んでいるので、考え方も「素直」なんですよねー。Web界隈に生息するイシカワさんと話していても、この辺からしていつも距離を感じます。想定条件のあまりの違いに、私ってスタンドアローンなんだなー、Winアプリなんだなー、としみじみ思うわけですね。

まーなにはともあれ、とりあえず、1回のアップロードで全部登録することを最優先に考えるなら、処理時間は無視して、5,000件くらいごとに、スリープさせるロジックをループの最中にいれちゃえば、殆ど今のソースを変えずに、全部登録できるんじゃないかなーというのが私の見込みです。どこでメモリーオーバーをおこしているにせよ、ファイルを小さくすれば通るロジックであることは確かなので、ときどきスリープして、ある程度のかたまり毎に処理を完結させてしまえば、どうにかなるのではないかなーという仮説。根本的な解決にはなりませんが、うまくいっているロジックを大改造するよりは安全・お手軽だし、ファイルをちまちま分割してからアップロードする現状よりは、黙って待つ方がラクチンだと思うし。

なんだか誰も信用してくれずに実験すらしてくれないんですけど(カウントして余りがゼロになったときにスリープするだけなのに!!)、実験してもらえないほど的外れな仮説なのでしょうか?なにかとマイノリティの自覚はあるけどさ…(悲)。

2008/04/02

ColdFusionとJava

ColdFusionはイシカワさんと違って素人なのですが(そもそも私はWeb系全般に疎い…。それに比べてイシカワさんはCFの日本語の参考書を全種類買い集めた人です)。隣で他人がColdFusionのソースの改修でアワアワしていたので、なんとなくソースを見ていて、ナゾなところを、ちまちまとググっておりました(好奇心&手伝いです)。

そんなこんなでウワサには聞いていたけど、CFってホントにJavaで実装しているんだなぁ、と妙に実感したサンプルソース。

<cfset fr=CreateObject("java","java.io.FileReader")>
<cfset fr.init("/tmp/testfile.txt")>
<cfset br=CreateObject("java","java.io.BufferedReader")>
<cfset br.init(fr)>
<cfloop condition="true">
  <cfset line=br.readLine()>
  <cfif not IsDefined("line")><cfbreak></cfif>
  <cfoutput>#line#<br></cfoutput> <!--- この部分 --->
</cfloop>
<cfset fr.close()>
参照元:逆引きColdFusion(1)

上記のソースで私にはよくわからなかったのが、initで、これはなんだろうと思ってググってみたら、リファレンスでは以下のような定義になっていました。

Use the init method, with appropriate arguments, to call an instance of the class.

CFML Reference

initメソッドでjavaのクラスのインスタンス生成というわけなんですね。initのカッコの中は当然コンストラクタの引数。なるほど。

さらにもう一つ、冒頭のソースで躓いたのは、

<cfloop condition="true">

conditionの後の""に条件式を入れるようですが、trueの存在がなんとなく唐突に見えてナットクがいきづらかったのですね。

  <cfif not IsDefined("line")><cfbreak></cfif>

で、読みこんだ行がカラッポだったら、ループを抜けるのでどーでもいいといえばどーでもいいのでしょうが、

<cfloop condition="br.ready()">
  <cfset line=br.readLine()>
  <cfoutput>#line#<br></cfoutput>
</cfloop>

とかの方がなんとなく、個人的には読みやすい気がする…。この辺は普段、自分がそういう書き方ばかりをしているせいなのでしょうか(あ、でも条件式にreadyメソッドを入れることが適切なのか、Javaに疎いので実はあまりわかっていません。どーなんでしょう?)。

ちなみにあれやこれやのサーフィンの道中に、書き込み速度のやり方の比較実験の記事も見つけました(読み込みにあらず)。

CFFILE vs Java.IO.BufferedWriter

CFFILE tag を使うより、圧倒的にJava.IOを使った方が早いんですね。

5.5MBくらいの書き込みでCFFILE tagをフツーに使っていたら600秒かかっていたものが、Java.IOを利用したら、1秒になったそうです。上記サイトの筆者は、当然のことながら、CFFILEはとても手軽だけど、大きいファイルを扱う時にはJavaのメソッドを使った方が良さそうだという結論をくだしています。

まーそりゃそうだろうな、と思いつつも、600秒って10分ですよ。落ちているかと思って、途中でブラウザを閉じてもおかしくない長さですよね。道具は適切に使い分けたいものですね。

memo→本日のブックマーク

はてなのブクマ

ColdFusionのブクマ。ColdFusionは手軽だし、エラーとかも返してくれて結構いいツールだと思うけど、なんで流行らないのでしょーか?

ColdFusionカフェテリア

フォーラム。CF8って.NET Framework 2.0も使えるのか。へー。ほー。でも.NETを使うと今のところWinに環境が限定されちゃうもんね(悲)。Monoプロジェクトに期待したいところだけど、そのままの移植は厳しそうかなぁ…。

Coldfusion-Style

なんか追っかけていたら色々と…。

2008/04/01

カネゴンの78ちゃんねるまとめブログ

エイプリルフールですね。あちこち今年も、エイプリルフールサイトが登場しているのでしょうか。

窓の社は毎年なんとなく見てしまうわけですが(今年は携帯サイトっぽいデザイン)、近年個人的に大ヒットしているのは、円谷ステーション。 毎年4月1日のみ存在しているハイクオリティサイト。今年は「カネゴンの78ちゃんねるまとめブログ」。2chのパロディみたいですね(SNSサイトは帰ってこれなかったらしい??)。この1日限りに向ける情熱に、脱帽します…。

1日限りなので、今日もせっせと探索しよーと思いマス。o(%)o

サイバー大学

この仕事をやっているとコンピューターサイエンスを しっかり学びたいという欲求がしばしば起こります。 1人で学ぶのは、ちょっと範囲が大きすぎで難しいですしだからと言って情報系大学に入学するのもスクーリングなどかなり難しい。

そこで、私が注目してるのがサイバー大学
ちょっと、名前があれなのですが、文部省が認可した学位も 取れる正規の大学です。

授業は、すべてネットから受講可能で通う必要がありません。 設立してから、1年が立ちましたが社会人学生が多くそこそこ うまく行ってる様子です。

ですが、問題がひとつ。

学費が卒業までに270万もかかります。 正規の大学なのでしょうがない気もしますが、私みたいな 境遇の人には、かなり厳しい気がします。

せめて100万以下に、ならないものでしょうか。

2008/03/31

イシカワのスペック2008

じょにさんがスペックをさらしていたので、私も続きます。
書き出してみて、改めて思いましたがたいしたことしてませんねぇ。精進せねば

■わかってること・出来ること

  • PHP:現在の主な言語。まあ、普通にWEBサイトを立ち上げられますよってレベル。 (どんなレベルだ?)現在のところ、一番サクサク書けます。
  • ColdFusion:知る人ぞ知る言語。ポジションとしては、PHPみたいな感じでWEB専用言語です。PHPのsmartyなんて、近いかもしれません。で、スキルですが、現在の2番手かな。 普通にWEBサイトを作れますが、PHPよりは、時間がかかるかも。
  • ASP(VBScript):3番手。ちょっと関数とか自信なしです。 でも勉強する気はあまりなし。
  • WEBサイト:セキュリティも含め、基本的な動きは、知ってるつもり。 なので、言語が何であっても、改修なら比較的早く対応できると思います (WEBの動きから、コードを推測できるので。)でも、whitespaceは、厳しいかも(笑)
  • DB:MySQL、postgres、oracle、SQLserverなど一通り、仕事で使っています。 あとは、DB2が入ればコンプリートかな?薄く広くって感じです。 処理を早くするチューニングなどは、苦手。(インデックス張るぐらいしかわかりません。)
  • SQL:仕事で使う範囲は、問題なしです。早い書き方、遅い書き方なども かなり理解したつもり。DBの速さって8割SQLだそうで、結構重要だと思う。 でも、軽視されがちな気が・・・。
  • Linux:FedoraやCentOSなど主にレッドハッド系のものを仕事でいじっています。 LAMP環境のWEBサイトならば、まあ普通に設定できます。
  • シェル:時々、楽するために使ってます。sedとか少々。もう少し使えこなせるようになりたい。
  • ケータイサイト:PC用とどこが違うんだって突込みがありそうですが、いろいろ違います。クッキー使えないとか、絵文字の処理とか。その辺も一通り勉強かつ経験したつもり。

■やりたいこと・身につけたいこと

  • 正規表現:すごい便利。一回勉強しましたが、もう一度しっかり学びたい。 ちなみに、PHPでは(多言語でも?)多用するとオーバーヘッドが発生するので注意。 関数で出来ることは、関数でやりましょう。(数字チェックなどね。)
  • Java:やっぱり、プログラムと言えば、これ。何かと情報も多いし王道って イメージなので、学んでおきたい。市場価値も高いですし、Web系でも 組込み系で、使えるところもグーです。
  • Ruby:matzさんファンなので(笑)。Rubyを勉強すれば、オブジェクト指向も自然と わかるらしいし、Ruby on railsをやるためにもやっておきたい。
  • Ruby on rails(cakephp):フレームワーク自体あまり好きじゃないのですが、話題になっているので、さわってみたい。でも、「DB設計をする必要がない」とか「SQLを書かないでよい」ってどうよ?
  • コンピュータサイエンス:基礎をやっていないので、この先、この業界でやっていけるか かなり不安。なので、この辺の知識を付けておきたい。
  • 大規模開発:今まで、経験したプロジェクトは、1人~数人程度の小さいものが多かったので、大規模での開発を経験してみたい。大規模なりのノウハウがあるはず。

2008/03/30

OOP再考

■ところで私、OOPについて理解していないんじゃん?

VB6.0→VB.NET(VS2003)へ移行した当初は、OOP関連の書籍を読んだりして、わりとマジメにモヤモヤしていたものの、いつの間にかVB.NETでの表面的な書き方にすっかり慣れてしまって、

  • クラスは機能単位にまとめられてベンリだし
  • スコープの管理もなんだかラクチンだし
  • 全てをクラスで書くというシンプルさがいいではないの

というあたりで満足してしまっていたわけですが…。

移行当初に「差分プログラミングだ!」と思って、Formを継承するという大技にでて苦い思いをして以来(「VisualBasic」なのにVisualな環境ではなくなってしまい、ボタンの位置をズラしたくても、ソースに戻らねばならず大変なことに…。理屈を考えるとそりゃそーなんですけど)、すっかり懲りて、自分自身がコードを書く際には、継承、抽象クラス、Interfaceという三種の神器は、私の中ではまとめて「なかったこと」になっていたんですね。せいぜいヘルプを読む際に、その知識を生かす程度でした。

ところが最近、別件でサーフィンをしていたら、「俺のOOPの理解がどう間違っていたかのふりかえり」の記事がふと目にとまり、

クラス = 構造体 + 関数みたいにムリに構造化プログラミングの考え方で見ようとしてはいけない。でないと、オブジェクトを入れ替えることで実装を切り替えられる、という技術によって非常に柔軟なコードが書けるようになる不思議が中々理解できないんじゃないかと思う。

という一節が妙にココロに引っかかってきたんですね。私もクラス = 構造体 + 関数って捉えてない?捉えているよね?と自問自答…。

あらためて「OOPってナンだっけ。とりあえずデザインパターン本あたりから読んでみる?」という気になって、数年前に挫折したあたりからのやりなおし計画発動です。

■OOPやりなおし計画発動 ~ デザインパターン本を読む

4774115797
技術評論社 2002-09
売り上げランキング : 24748
おすすめ平均 star

Amazonで詳しく見る

やりなおし計画の第一歩として、「Javaデザインパターン徹底攻略 」とうい本を手にとってみました。

サンプルソースはホントにパターンの骨だけが書かれているこの書籍。非常に短いセンテンスでパターンを紹介しているので、読みやすく、それぞれのクラスの関係性については、よく見えてくる本でした。

ただサンプルソースは短いだけあって、ホントに骨だけ。具体性には欠けていて、この本を読んだからといって、すぐさま「おお、確かにこういうシーンで使うと超ベンリだよね!」という感じにはなれませんでした。

前半のパターンでは「こんなコードを、デザインパターンでこんな具合にシンプルに!」という、デザインパターン以前のサンプルソースがついていて、ナットクしやすかったのに、後半では何故かデザインパターン以前のサンプルを端折りだしていますしね…。このAfter、Beforeの対比は、是非、全部のパターンにつけて欲しかったですね。

というわけで、パターンの作りは見えたものの、この本を読んだからといって「すぐさまデザインパターンを自分のソースに…!」とはならず、「まー、いずれ使うかもね…」くらいの感じではあったわけですが…。

23パターンをつらつらと見ていて、強く印象づけられたのは次の2点。

  • ポリモーフィズムを使いまくり。
  • ポリモーフィズムを利用して、IF文での判定を減らしている。

「IF文って嫌われている?まぁ処理に名前はついてないからね…」と思いながら、ひたすらポリモーフィズムを利用するパターンを読み続けているうちに、今更ながらに、「ポリモーフィズムってこういう風に使うのか…」という「気づき」はありました。ポリモーフィズムを利用した書き方なら、結構ラクに今の自分の書き方に取り入れられるかも…、という「気づき」でもあります。

■ポリモーフィズムについて実践考

ポリモーフィズムを使うことを前提に、一つの機能について大雑把に整理しなおしてみると、次の3つの階層に切り分けることができます。

  1. データを具体的に加工したりする階層
  2. Aのレベルのクラスのメソッド等を順序よく操る階層
  3. Button.Clickのイベントの辺りで書いたりするクライアントプログラムの階層。

A階層のデータを操る部分は、データが変わるたびにソースを書かざるをえません。でもB階層は単なるメソッド呼び出しの手順なので、意外と一緒だったりすることが多いんですよね。データは変わっても、それを扱う順序は変わらない。

もともと汎用的なツールを作っているときは、データ(画像とか)を直接処理するAの部分は固定で、Bの部分を作り変えることが多く、自然とこの 3階層に切り分けて書くことが多かったわけなのですが…(とはいえ、この場合は、Bの部分の書き換えなので、ポリモーフィズムは利用できませんが…)。

それとは逆の場合には、これまで主に2階層で書いていました。業務によって仕様の違うデータを処理する部分では(値を加工してテーブルを入れたり出したりするような作業とか)、A+Bが一体となっているクラスαを作って、Cからαクラスの、順序を管理しているメソッドを呼び出す…、という書き方です。Button1のクリックに対応するのはαクラス、という1対1の関係で、αクラスのメソッドを順番にみていけば、ストーリーの大筋は終えてしまう、という書き方。

ただこのB的な「順序を管理しているメソッド」の大部分は、別のクラスからのコピー&ペーストの世界です。このコピー&ペーストのメソッド部分を、別クラスに出して、3階層で切り分けてみると、A階層のクラスをひたすら作り変えている、というカタチになるなぁ、と今回改めて気がついたわけです。


もう少し具体的に考えていきましょう。たとえば、CSVファイルのDBへのインポート機能を考えると、

  1. ファイルのパスをゲット。
  2. テーブルにデータを突っ込む。
  3. インポートしたデーターのエラーチェックを行なう。
  4. エラーがあればレポートの出力。

シチュエーションによって多少の差異は出てくるにしろ、大筋はこんな流れになります。

ということは…。

  1. 定型的なメソッドをInterfaceで宣言
  2. A階層のクラスでInterfaceをImplements。
  3. B階層のクラスはInterfaceで宣言したクラスを操作する。
  4. クライアントプログラムとなるC階層では、BのクラスをNewするときか、別メソッドを作るかして、Bのクラスへ、引数としてAのクラスを渡す。

InterfaceをImplementsしているA階層のクラスを、データに沿ったカタチで複数作っていけばいいわけですね。クライアントプログラムでは、扱いたいデータを処理しているA階層のクラスをひとつ選んで、ひたすらBのクラスへ引数として渡せばいい…。

データを入れたり出したりのバッチ処理は、頻繁に書いているものの、フローのバリエーションはいくつかに絞れそうですし…。そのバリエーションの数だけ Interfaceを作って、Interfaceを操作するBも作ればいいわけですから。作ってしまえば、あとはひたすらAの部分を書いていくだけ、と。

ポリモーフィズムを連荘で見せつけられて、自分の今のソースへの当てはめ方も見えてくると、「なーんだ、そっかー、簡単じゃん」という気になってきました。…私、騙されています?それとも、今更…、ってところなのでしょうか。

memo

VBユーザーだけどOOPならJava本でしょ、やっぱり

私はVB2005ユーザーですが、OOP本はなにかとサンプルソースがJavaの本が多いので、「Javaをある程度読めないと、OOP本は読めないぞ」と思って、VB6.0→VB.NET(VS2003)への移行当時、覚悟を決めてJavaの入門書を一通り通読しました。で、Javaの入門書を読みながら思ったことといえば、

VB.NETの参考書よりも、Javaの参考書を読んだ方が、クラスのお作法についても、なんだかわかりやすい」(ナニソレ)

Java本が質・量とともに豊富なのに比べて、.Net系の良い参考書は、今でも「コレ!!」といったものがないですからね。VBユーザーといえども、Javaの簡単なサンプルソースくらいは読めないとツライご時世なのです。

とはいえ、今回私が読んだ「Javaデザインパターン徹底攻略」程度の簡単なサンプルソースであれば、わざわざJavaの入門書まで戻らなくても、ある程度、クラスのお作法に慣れている人であれば、非Javaユーザーの人でもつらつらと読めるのではないかと思います。共にOOP志向の言語で、大筋は似ていますから…。

ちなみにVB2005とJavaとの差異の部分は、VBという言語仕様のOOP志向への中途半端さ加減を感じる部分でもあります。例えばVBの場合、Interfaceにアクセス修飾子をつけられます。「ちょっとマテ。そこでpublic以外のアクセス修飾子をつけられる余地があるのは、どういうことなのさ?ポリモーフィズムを利用しようと思っても、不完全な可能性が…」この種の方向性の中途半端さ気がつくとなんだか気持ち悪くてムズムズしてきます。…あぁ神サマ、どーして私はVBユーザーなのでしょーか。この気持ち悪さを忘れるくらいの、自分の言語に対するLoveが欲しい。

memo2

Matzのにっき→2003年のOOPの記事リスト

Rubyは触ったことがないのですが、内容的にはなるほどなるほど。「オブジェクト指向は難しい」のオブジェクト指向の嬉しさの違いや、「(その2)」のオブジェクト指向のシンプルさについては、拙い書き方ながらも、これまでクラスを書きはじめてから感じていたことだったので、「あぁこの嬉しさの違いは私にもわかるなぁ」と共感(嬉)。

「継承は悪か」のま2さんのツッコミ記事は今の自分にはタイムリー(2003年の記事で、世間的には5年も前の議論なわけですが…)。

4. で実際問題として,手続きが変わるより,データ形式が変わることの方が多い。したがって,実際問題としてオブジェクト指向の方が威力を発揮する。

オブジェクト指向は「データ中心」の産物で,「データ中心世界」では強い。そこでプログラミングの対象が「データ中心世界」なのか「手続き中心世界」なのかが重要だということです。結局オブジェクト指向とは「ものの見方」なのですね

まさに!!ってところですね。

2008/03/27

マイスペック2008

B0015IQ776
日経ソフトウエア2008年5月号は「はじめてのプログラミング」総力特集号。プログラミングを始めるその瞬間に知っておきたいことを,ぐぐっとまとめてお届けします。はじめてのプログラミングでは,迷いと不安がつきものです。先輩プログラマからの手紙に始まり,プログラミング言語カタログ,多くの言語で共通するプログラミングの基本概念,学ぶときに気を付けたいことなどをやさしく解説して,“着実な一歩”をしっかりサポートします。

さてはてMSっ子のじょにです。日経ソフトウエアを読んでいたら、結城先生からの手紙に以下のような部分がありました。

今の自分が知っている言葉を紙に書き出してみましょう。

~中略~

そうやって、自分のノート、自分の理解の現状を具体的な形にしていきます。そして、例えば、1年後、そのノートを振り返ったとき、あなたは格段に変化している自分に気づくでしょう。

このブログのそもそもの私の目的はそれに近いので…(学習記録帳。恥を晒す)。かなりの恥さらしと自覚しつつ、現状把握の為、マイスペックを書き出してみることにしました。

わかっていること・LOVE・使えるレベル

  • Excel(2000/2003):LOVE。関数からマクロまで。ちなみにに汚いデータを整形したり(全角・半角を整えたり、桁数を揃えたり)、表の作成等については、かなりスピードに自信あります。
  • Access(97/2000/2003):LOVE。クエリも好きですが、Accessの大抵のVBAでの操作はかなりあれこれ大技・小技を含めて使っている方だと思います。ちなみにマクロ機能はまず使いません(VBAで大抵のことはコントロールできますし、ソースだけを見れば全体像がつかめて視認性が良いので)。
  • VB6.0:主にAccessとの連携プログラムばかり作成。生成物としてはCSV、Excelデータ作成など。レポート出力はAccessのレポート機能を使っていて、クリスタルレポートは使ったことナシ。データを管理する(インポート・検索・新規登録・編集・削除・レポート出力など)ようなものや、バッチ処理系のスタンドアローンなプログラムばかり作成。APIは、パクったものの利用くらいしか使えていません。他、dll利用の圧縮ツール等。
  • Visual Basic 2005:現在主に利用中。作成しているプログラムの内容的にはVB6.0時代と同様スタンドアローンのツール。レポート出力はActiveReportにて。たまーにバッチ処理的な画像処理のクラスの作成など。TIFのフォーマットについては多少勉強。他にはAccessのDB解析プログラムなど。
  • VBScript:主にEmEditorのマクロで。WinのDBサーバーへVBScriptでODBC経由でエラーチェックつきのインポートツールを作ってみたり。Winでありさえすればなにはなくとも動くので、ちょっと楽しいと思いはじめている。

遊んだことがあるもの

  • Basic:学生時代の授業にて半年だったか1年だったか…。毎週課題が出るわけですが、今で言うギークっぽい子たちに、毎度毎度助けられていました(ちなみに私の初PC購入にあたっても、彼らに付き合ってもらいました。予算とやりたいことのみ伝えて、機器の選定から値段交渉まで全部お任せ…。配線や設定等は自力でやりましたが)。気がついたら、学期の後半には、このクラスには彼らと私しか残っていませんでした(他は全員脱落…)。
  • C言語:社会人になってからの最初の研修で10日くらい???家ではTURBO Cを入れて、ちらっと遊んでいました。ほぼ最初に触れた言語がCだったせいか、今でも型宣言等がキッチリしている言語の方が読みやすいとは感じます。
  • Java:結城本(プログラムレッスンの上下巻)を2冊読んで、OOP本の入門系のサンプルソースくらいは読めるレベル(ま、VB.NETとも似ているので…)。但し、当然、アプリを作るレベルではありません。
  • JavaScript:たまーにアイディアを思いつくと、ブラウザ上で動くミニツールを作成。ブラウザさえあれば、動くものを作れるので、ちょっと楽しいと思い始めているところ。でも普段あまり使わない言語なので、VBScriptほどにはサクサク書けず、もどかしい。
  • ASP:VBScriptとAccess連携で、セキュリティ無視の遊びレベルのツールくらいは作ったことあり(ホワイトボードや検索系)。でもセッションの使い方は、実は当時なんだかよくわかっていませんでした。今は概念はわかっていますが、実装レベルではどーでしょ?
  • ColdFusion:一週間くらい何故かいじったことがあります。業務アプリ・改修経験はナシ。
  • Python:Zope上で数日体験した程度。
  • Perl:初心者本を2冊通読した程度。インストールして多少いじったことはあるものの、ひとさまのソースもロクに読めない状況…。ソースになかなか慣れない原因その1.書き方のバリエーションがなんだか随分あるように感じられ、まごつく。その2.引数を明示しないファンクションになじめず、どこからともなく降ってわいた値がいきなり動き出しているような印象をもってしまう。その3.苦手な正規表現をばんばん使っているソースが多い。その4.Perlの関数を知らなさ過ぎる。
  • FileMaker:お友だちがこれの使い方がわからずパニくっていたので、お試し版を落として、多少のヘルプに入ったことアリ。でも根っからのAccessユーザーなので、これならAccessの方がいいや…、と思って、用が済んだらさっさとアンインストール。
  • Oracle10gEx:タダなので入れてみました。標準SQLを試しに叩いてみる程度。
  • MySQL:タダなので入れてみたことアリ。他人の作ったWebアプリを使うにあたって、ちらっといじってみたことがある程度。
  • CSS:カスケードとかはわかっていますが、あまり体系的に勉強はしておらず。整理されたCSSを書く力量はナシ。

壁を感じること・アイタタタ

  • UMLなど:設計書の類を読んだり、書いたりすること。当然、いきなりソースを書き出すタイプです。設計~開発までがある意味守備範囲なので、端折ろうと思えば端折れ、仕様を残せといわれて、大抵、作った後にごそごそ書類を書いています。設計~開発まで一人で担当できるレベルだから、どうにかなってはいるものの…。.NETに移行した際に、これからはUML図だ!──と思ったのもつかのま、挫折…。
  • ポインタ変数:C言語やC#の参考書を読むたびに、挫折。VBからC#へ移動したい気持ちはあるのに、毎回この山の麓あたりで挫折。
  • 再帰処理:どーにか他人のソースは読むものの、自力では書けない感じ。シナプスが切れている感じで、思いつけません…。
  • スレッド:追いかけているうちに、何がなんだかわからなくなります。sleepしか使ったことがないなんて…。
  • 正規表現:毎回何かしようと思うたびに、自分が欲しいと思っているモデルとなるサンプルをググって、多少改造するレベルでしか使えていません。
  • XMLとかXSLとか:入門書トライの度に、最初はわかったつもりでふんふんと思っているうちに、いつの間にか何がなんだかわからなくなってしまう。たまーに.Netから単純なものは利用したりもしますが、一体、なんなんですかー?
  • Webセキュリティ:全然知りません。SQLインジェクションとかブラインドSQLインジェクション、XSSについてもわりと最近知っておぉ…と思った暢気さ加減。いや、だからこそWebアプリは作ってこなかったわけですが。

こうして書き出してみると、アプリ使いって感じですね。自信があるのはExcelとAccessだけか!…みたいな。来年の今頃は、多少スペックは上がっているのでしょうか。

2008/03/22

Java/Officeストーリー

MSっ子な私はこれまでVB6.0なり.NetからのExcel出力部分ではCOM利用をしていて、その部分ではたいした苦労をしたことありません(COMオブジェクトの解放 はちと面倒臭いですけどねー)。ですが、JavaからのExcel出力には、なんだか随分大変な歴史があったのですね。

◆Javaを使ってOffice2007をクラックする

上記サイトの記事を読むと、COM利用の言語の人の場合は、「ExcelのCOMを利用すればいいじゃん」のヒトコトで済むわけなんですが、COMをサポートしてない言語ではCSVで吐いてみたり(それを聞いただけで泣ける…!)、涙と汗の紆余曲折。Office2003が登場したかと思えば、独自路線なXMLフォーマット。しかもそのフォーマットはきちんと文書化されていないという中途半端な状況で、トライアル・アンド・エラーを頻発させしながら、自分達でそのフォーマット状態を手探り状態で解明しなければならないという、暗中模索作業が待っていて…。

全般的に、Java/Officeストーリーは、控えめに言っても、極めて不快な状態でした。Javaの開発者はじっと耐えるか、「Officeは最低だ。とにかく、なぜ、誰かがそれを使いたがるんだい?」と言うことで、イソップ物語の1つを大いに連想するやり方で自分自身を慰めるか、単純に Officeを使っているユーザーに、Microsoft とSun の訴訟問題のせいで、JavaはOfficeを理解することができないのだ、と言ってみるかしかありませんでした。

Javaを使ってOffice2007をクラックする

極めて不快…Officeは最低って…。憎まれちゃって、まぁ。憎むほど苦労する前に、その部分は、素直にCOMを使える言語を使えばいいのに…、とついつい憎まれっ子世に憚る(?)MSっ子としては呟きたくなるわけですが…。

上記サイトのストーリーを読むと、Office2007の登場でXML文書のZIPファイル以外何物でもないものになったので、やっとJavaの開発者もハッピーになりそうだ、というようなストーリーになっていますね。

もっとも、今のところ、私はOffice2007でのフォーマットの納品自体を頼まれたことはありません。むしろなるべく多くのOfficeで問題なく開くよう、バージョンダウンを意識しています。Java開発者がOOXMLで大手を振って納品できるようになるのはもう少し先のことなのかなぁ、と思うわけですが。

現在、企業ではOffice2007はどれくらい普及しているのでしょうかね。

EmEditorのマクロ 選択範囲をpタグで囲む

選択範囲をpタグで囲むマクロ。

改行はbrタグで記事を書こうと思っていたわけですが、やっぱりパラグラフはpタグの方がレイアウトしやすいなと思って、pタグも準備しました。ソース的には新鮮さゼロですが。

ついでに個人的にはすーごく気持ち悪かったbloggerの記事を囲んでいたpタグも外してしまいました(ウィジットテンプレートをぽーっと見ていて、やっとどこで設定しているのかわかりました。ふー、スッキリ。更に調子に乗って「ウィジットのテンプレートを展開」にチェックを入れて、ウィジットのタグもいじってみましたが、こちらはことごとくエラーになりました。あー改造したい…)。

Dim intXB        '選択範囲の最終行のX
Dim intYC        '現在位置のY
Dim intYA        '選択範囲の開始行
Dim intYB        '選択範囲の最終行
Dim i

intYC = document.selection.GetActivePointY( eePosLogical )
intXB = document.selection.GetBottomPointX( eePosLogical )

intYA = document.selection.GetAnchorPointY( eePosLogical )
intYB = document.selection.GetBottomPointY( eePosLogical )


If intXB = 1 Then
    intYB = intYB -1
    If intYC > 1 Then intYC = intYC - 1
End If

If intYC <> intYB Then
    For i = intYC To intYB
        document.selection.StartOfLine False,eeLineLogical
        document.selection.Text="<p>"
        document.selection.EndOfLine False,eeLineLogical
        document.selection.Text="</p>"
        document.selection.LineDown
    Next
Else
    For i= intYA to intYB
        document.selection.StartOfLine False,eeLineLogical
        document.selection.Text="<p>"
        document.selection.EndOfLine False,eeLineLogical
        document.selection.Text="</p>"
        document.selection.LineDown
    Next
End If

2008/03/20

Whitespace

本日の面白ネタは、「Whitespace」というプログラミング言語。
るびまのMatzさんの解説は、こちら。

何が面白いってすべてが、スペース、タブ、改行で表されていてWeb上やwindows付属のメモ帳とかでは何がなんだかわからない。
たとえ、EmEditorや秀丸などの高機能エディタを使っていても見にくいこと、この上ない。じゃあ、なんのために存在するんだよ って思ったところ

通常無視されがちな空白に対する不公平を是正 する

ためらしい。まさに、ジョーク言語!!
なんというかもう、最高。面白い。

ちなみに本家サイトは、こちら

2008/03/18

日本オラクル

17日の英語でしゃべらナイトを本日見ました(録画)。

外資の取材といいつつ、番組の8割くらいはOracleさんネタでした(パックン英検もなかったし…)。

入社1年目の子の1日の密着とか、かなり興味深かったです。入社1年目にして、家の中にホワイトボードまであったりして、なぬぬ、ビックリしたものの、すごくまじめ。頭が下がります。上司に対して、研修についの有用性を訴えるプレゼンのシーンなんかもなかなか面白かったです。自分の意見を認めてもう為に、プレゼンの機会を設けて上司(関係者)を説得する、という風景なのですが、プレゼンの練習にもなりますしね。

ちなみに再放送は3月21日(金)深夜2:50からのようです。

EmEditorのマクロ 選択範囲内をprettyprint

EmEditorのマクロで選択範囲をソースコード用のタグ<pre class="prettyprint"></pre>で囲んで、&類を実体参照化するマクロ。preの中だと自動で実体参照に変換してくれないようなので。

Blogger投稿用デス。

Dim strData
Dim intSCount

intSCount = 4    'tab→半角スペース置換えの際のスペースの数
strData = document.selection.Text

strData = Replace(strData, vbTab, String(intSCount," "))
strData = Replace(strData, "&", "&amp;")
strData = Replace(strData, "<", "&lt;")
strData = Replace(strData, ">", "&gt;")
strData = Replace(strData, """", "&quot;")
strData = Replace(strData, "'", "&#39;")

document.selection.Text = "<pre class=""prettyprint"">"
document.selection.NewLine
document.selection.Text = strData
document.selection.Text = "</pre>"

2008/03/17

バカにされる言語?

最近、webを徘徊していてものすごく笑ったのがこれ

◆PHPやってるだけでバカにされるんですがどうしたらいいでしょうか。 - 人力検索はてな

PHPやってるだけでバカにされるんですがどうしたらいいでしょうか。
あとIPAの総論とかもひどいな~。

◆IPA ISEC セキュア・プログラミング講座:Webアプリケーション編 第1章 総論:より良いWebアプリケーション設計のヒント

開発基盤選定における考慮事項の例
(1) プログラミング言語の選択
1) 例えば、PHPを避ける
まあ、phpについては、matzさんもdisりまくってるのですが、間違った方向に いっている例もあるということで・・・・。

なんにせよ、人気言語ってことでしょうか?